web-annotation-renderer 0.6.4 → 0.7.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.
- package/CHANGELOG.md +129 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +62 -61
- package/dist/index.js.map +1 -1
- package/dist/index10.cjs +1 -1
- package/dist/index10.cjs.map +1 -1
- package/dist/index10.js +160 -13
- package/dist/index10.js.map +1 -1
- package/dist/index11.cjs +1 -1
- package/dist/index11.cjs.map +1 -1
- package/dist/index11.js +13 -50
- package/dist/index11.js.map +1 -1
- package/dist/index12.cjs +1 -1
- package/dist/index12.cjs.map +1 -1
- package/dist/index12.js +48 -155
- package/dist/index12.js.map +1 -1
- package/dist/index13.cjs +1 -1
- package/dist/index13.cjs.map +1 -1
- package/dist/index13.js +150 -34
- package/dist/index13.js.map +1 -1
- package/dist/index14.cjs +1 -1
- package/dist/index14.cjs.map +1 -1
- package/dist/index14.js +32 -65
- package/dist/index14.js.map +1 -1
- package/dist/index15.cjs +1 -1
- package/dist/index15.cjs.map +1 -1
- package/dist/index15.js +66 -33
- package/dist/index15.js.map +1 -1
- package/dist/index16.cjs +1 -1
- package/dist/index16.cjs.map +1 -1
- package/dist/index16.js +35 -77
- package/dist/index16.js.map +1 -1
- package/dist/index17.cjs +1 -1
- package/dist/index17.cjs.map +1 -1
- package/dist/index17.js +53 -28
- package/dist/index17.js.map +1 -1
- package/dist/index18.cjs +1 -1
- package/dist/index18.cjs.map +1 -1
- package/dist/index18.js +28 -22
- package/dist/index18.js.map +1 -1
- package/dist/index19.cjs +1 -1
- package/dist/index19.cjs.map +1 -1
- package/dist/index19.js +22 -117
- package/dist/index19.js.map +1 -1
- package/dist/index2.cjs +1 -1
- package/dist/index2.cjs.map +1 -1
- package/dist/index2.js +94 -98
- package/dist/index2.js.map +1 -1
- package/dist/index20.cjs +1 -1
- package/dist/index20.cjs.map +1 -1
- package/dist/index20.js +137 -100
- package/dist/index20.js.map +1 -1
- package/dist/index21.cjs +1 -1
- package/dist/index21.cjs.map +1 -1
- package/dist/index21.js +34 -76
- package/dist/index21.js.map +1 -1
- package/dist/index22.cjs +1 -1
- package/dist/index22.cjs.map +1 -1
- package/dist/index22.js +35 -139
- package/dist/index22.js.map +1 -1
- package/dist/index23.cjs +1 -1
- package/dist/index23.cjs.map +1 -1
- package/dist/index23.js +37 -37
- package/dist/index23.js.map +1 -1
- package/dist/index24.cjs +1 -1
- package/dist/index24.cjs.map +1 -1
- package/dist/index24.js +69 -37
- package/dist/index24.js.map +1 -1
- package/dist/index25.cjs +1 -1
- package/dist/index25.cjs.map +1 -1
- package/dist/index25.js +40 -38
- package/dist/index25.js.map +1 -1
- package/dist/index26.cjs +1 -1
- package/dist/index26.cjs.map +1 -1
- package/dist/index26.js +4 -39
- package/dist/index26.js.map +1 -1
- package/dist/index27.cjs +1 -1
- package/dist/index27.js +4 -4
- package/dist/index28.cjs +1 -1
- package/dist/index28.cjs.map +1 -1
- package/dist/index28.js +71 -5
- package/dist/index28.js.map +1 -1
- package/dist/index29.cjs +1 -1
- package/dist/index29.cjs.map +1 -1
- package/dist/index29.js +24 -69
- package/dist/index29.js.map +1 -1
- package/dist/index3.cjs +1 -1
- package/dist/index3.cjs.map +1 -1
- package/dist/index3.js +31 -31
- package/dist/index3.js.map +1 -1
- package/dist/index5.cjs +1 -1
- package/dist/index5.cjs.map +1 -1
- package/dist/index5.js +237 -190
- package/dist/index5.js.map +1 -1
- package/dist/index6.cjs +1 -1
- package/dist/index6.cjs.map +1 -1
- package/dist/index6.js +37 -19
- package/dist/index6.js.map +1 -1
- package/dist/index7.cjs +1 -1
- package/dist/index7.cjs.map +1 -1
- package/dist/index7.js +11 -17
- package/dist/index7.js.map +1 -1
- package/dist/index8.cjs +1 -1
- package/dist/index8.cjs.map +1 -1
- package/dist/index8.js +16 -125
- package/dist/index8.js.map +1 -1
- package/dist/index9.cjs +1 -1
- package/dist/index9.cjs.map +1 -1
- package/dist/index9.js +118 -201
- package/dist/index9.js.map +1 -1
- package/package.json +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,135 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.7.0] - 2026-05-02
|
|
9
|
+
|
|
10
|
+
Stroke-unified renderer refactor. Restores correctness of highlights and
|
|
11
|
+
diagonal arrows, removes ~600 LOC of dead code and duplication, and
|
|
12
|
+
unifies the public method contract.
|
|
13
|
+
|
|
14
|
+
### Visual Changes (read before upgrading)
|
|
15
|
+
|
|
16
|
+
- **text annotation: fontSize denominator changed from 1000 to
|
|
17
|
+
REFERENCE_HEIGHT (500).** Glyphs now render approximately **2× larger**
|
|
18
|
+
at the same `fontSize` value. To match v0.6.x size, halve your
|
|
19
|
+
`fontSize` (e.g., `fontSize: 24` → `fontSize: 12`). This was a latent
|
|
20
|
+
inconsistency between the converter constant and `REFERENCE_HEIGHT`;
|
|
21
|
+
the fix aligns text scaling with all other stroke widths.
|
|
22
|
+
- **highlight thickness now tracks the underlying text height**
|
|
23
|
+
(`quad.h * REFERENCE_HEIGHT * widthScale`). Existing v0.6.x deployments
|
|
24
|
+
that relied on the chunky fixed `width: 24` highlight will see thinner
|
|
25
|
+
bands on small text. To approximate the v0.6.x look, set
|
|
26
|
+
`strokeConfig: { highlight: { widthScale: 2.5 } }`. The legacy `width`
|
|
27
|
+
field is silently ignored — the converter now emits a one-time
|
|
28
|
+
`console.warn` the first time it sees `style.width`.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- **PDFRenderer now applies `devicePixelRatio` for HiDPI/retina sharpness
|
|
33
|
+
— matches StrokeRenderer behavior.** Previously the PDF canvas rendered
|
|
34
|
+
at CSS pixels while the annotation overlay rendered at DPR-scaled
|
|
35
|
+
pixels, producing a blurry PDF behind sharp annotations on retina
|
|
36
|
+
displays. The pixel buffer is now sized to `viewport * DPR` and pdf.js
|
|
37
|
+
is asked to render at `scale * DPR`; the canvas's CSS display size
|
|
38
|
+
stays in CSS pixels so the annotation overlay continues to line up.
|
|
39
|
+
The returned `viewport` is still in CSS pixels — `StrokeRenderer.setViewport`
|
|
40
|
+
applies its own DPR internally, so returning the render viewport here
|
|
41
|
+
would double-apply DPR.
|
|
42
|
+
- **Highlight thickness now matches the underlying text quad height.**
|
|
43
|
+
The previous fixed `width: 24` painted a band ~5× thicker than the
|
|
44
|
+
actual line of text on small viewports. Width is now derived from
|
|
45
|
+
`quad.h * REFERENCE_HEIGHT`. (#highlight)
|
|
46
|
+
- **Diagonal arrows render symmetric V-shaped heads.** Wing geometry is
|
|
47
|
+
recomputed every frame in screen-pixel space, so the angle between
|
|
48
|
+
the main line and each wing is preserved across viewport aspect
|
|
49
|
+
ratios. Previously the angle warped along non-square viewports.
|
|
50
|
+
- Highlight `lineCap` now defaults to `'butt'` so quad endpoints
|
|
51
|
+
terminate cleanly instead of bleeding past the quad.
|
|
52
|
+
|
|
53
|
+
### Added
|
|
54
|
+
|
|
55
|
+
- `setupPdfWorker(workerSrc)` helper export — single call to configure
|
|
56
|
+
`pdfjsLib.GlobalWorkerOptions.workerSrc`.
|
|
57
|
+
- `StrokeRenderer.setAnnotations(arr, page, { validate: true })` —
|
|
58
|
+
opt-in validation that runs `normalizeAnnotationArray` on the input
|
|
59
|
+
before conversion (clamps invalid quads, drops invalid types). The
|
|
60
|
+
default (`validate: false`) preserves v0.6.x behaviour.
|
|
61
|
+
- Per-page strokes cache inside `StrokeRenderer`. Round-tripping through
|
|
62
|
+
`setPage(1) → setPage(2) → setPage(1)` no longer re-runs the converter
|
|
63
|
+
for page 1 — strokes are pulled from the cache, keyed on annotation
|
|
64
|
+
array identity. Use `setAnnotations(..., { noCache: true })` to bypass.
|
|
65
|
+
- `widthScale` field on `strokeConfig.highlight` — multiplier applied on
|
|
66
|
+
top of the data-derived highlight width (default `1.0`).
|
|
67
|
+
- `src/config/defaults.js` — single source of truth for `DEFAULT_CONFIG`,
|
|
68
|
+
`REFERENCE_HEIGHT`, and `ANNOTATION_TYPES`. `StrokeRenderer` and
|
|
69
|
+
presets import from here instead of carrying duplicate copies.
|
|
70
|
+
- `src/converters/_shared.js` — `buildRoughOptions` and `resolveColor`
|
|
71
|
+
helpers that replace ~6 lines of boilerplate per converter.
|
|
72
|
+
|
|
73
|
+
### Changed
|
|
74
|
+
|
|
75
|
+
- **BREAKING:** `strokeConfig.highlight.width` is no longer honoured;
|
|
76
|
+
use `widthScale` to scale the data-derived width. Existing configs
|
|
77
|
+
that override `width: 24` will silently ignore the field — drop the
|
|
78
|
+
override (recommended) or migrate to `widthScale`.
|
|
79
|
+
- **BREAKING:** `AnnotationRenderer.setPage(pageNum)` no longer calls
|
|
80
|
+
`setAnnotations` internally. Adapters/callers must re-bind annotations
|
|
81
|
+
after a page change. The shipped `AnnotPdf` React component does this
|
|
82
|
+
automatically.
|
|
83
|
+
- **BREAKING:** Public methods on `AnnotationRenderer` now return a
|
|
84
|
+
uniform `{ success: boolean, error?: string, ...payload }` shape:
|
|
85
|
+
`loadPDF`, `setPage`, `setScale`, `setAnnotations`, `setStrokes`,
|
|
86
|
+
`setTime`, `updateStrokeConfig`. Constructor remains the only entry
|
|
87
|
+
point that throws. Methods that previously returned `void` now return
|
|
88
|
+
`{ success: true }` on success or `{ success: false, error }` on
|
|
89
|
+
invalid input.
|
|
90
|
+
- `src/types/validators.js` rewritten as schema-driven (~717 → ~349
|
|
91
|
+
LOC). Public function surface (`normalizeAnnotationArray`,
|
|
92
|
+
`normalizeAnnotation`, `normalizeBaseFields`, `normalizeHighlight`,
|
|
93
|
+
`normalizeText`, `normalizeUnderline`, `normalizeArrow`,
|
|
94
|
+
`normalizeCircle`, `normalizeCoordinate`, `normalizeColor`,
|
|
95
|
+
`normalizePositiveNumber`) and warning text are unchanged.
|
|
96
|
+
- `coordinateUtils.pointNormToAbs` is now actually used by
|
|
97
|
+
`StrokeRenderer` for default-projection points — previously it was
|
|
98
|
+
exported but the renderer duplicated the math inline.
|
|
99
|
+
- Style presets (`DEFAULT_PRESET`, `BLUE_PRESET`, `MINIMAL_PRESET`,
|
|
100
|
+
`getPreset`, `getPresetNames`) moved from `src/pen/presets.js` to
|
|
101
|
+
`src/config/presets.js`. Re-exports from `web-annotation-renderer`
|
|
102
|
+
are unchanged.
|
|
103
|
+
- `MINIMAL_PRESET` highlight previously set `width: 20`; it now sets
|
|
104
|
+
`widthScale: 0.85` to preserve relative thinness under the new
|
|
105
|
+
data-derived width model.
|
|
106
|
+
- `AnnotPdf.jsx`: removed the no-op `useMemo(() => strokeConfig,
|
|
107
|
+
[strokeConfig])` and the `isFirstRender` guard; tracks the latest
|
|
108
|
+
annotations through a ref so it can re-bind on page change without
|
|
109
|
+
re-running the page effect on every annotation update.
|
|
110
|
+
|
|
111
|
+
### Removed
|
|
112
|
+
|
|
113
|
+
- **BREAKING:** `GradualRenderer`, `StrokeDrawer`, `getPenPreset`,
|
|
114
|
+
`getPenPresetNames` exports. The whole `pen/*` module is gone — it
|
|
115
|
+
was internally unused since v0.4.0. Migration: use `StrokeRenderer`
|
|
116
|
+
directly (it has been the only renderer used by the React adapter
|
|
117
|
+
for two minor versions).
|
|
118
|
+
- **BREAKING:** `coordinateUtils.NormSizeToPixel` (a deprecated alias
|
|
119
|
+
for `rectNormToAbs`). Use `rectNormToAbs` instead.
|
|
120
|
+
- Local `DEFAULT_CONFIG` definition in `StrokeRenderer.js` (now imported
|
|
121
|
+
from `config/defaults.js`).
|
|
122
|
+
- Inline `style.color || 'rgba(...)'` fallbacks in every converter —
|
|
123
|
+
the resolved style from `setConfig` already carries the type's
|
|
124
|
+
default colour, so the second fallback was dead.
|
|
125
|
+
|
|
126
|
+
### Performance
|
|
127
|
+
|
|
128
|
+
- ~–598 LOC across `src/` (~10.4% reduction; baseline at tag
|
|
129
|
+
`spec-v0.7.0-frozen` was 5767 LOC, current is 5169 LOC). The original
|
|
130
|
+
spec target of <4500 LOC was relaxed during implementation — see
|
|
131
|
+
`docs/qa-report-v0.7.0.md` for the recalibration rationale.
|
|
132
|
+
- Per-page strokes cache cuts conversion cost on multi-page deck
|
|
133
|
+
navigation to ~zero for revisited pages.
|
|
134
|
+
|
|
135
|
+
[0.7.0]: https://github.com/jhl72e/pdfAutoAnnotator/compare/v0.6.4...v0.7.0
|
|
136
|
+
|
|
8
137
|
## [0.5.3] - 2025-01-20
|
|
9
138
|
|
|
10
139
|
### Fixed
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./index2.cjs"),u=require("./index3.cjs"),d=require("./index4.cjs"),T=require("./index5.cjs"),t=require("./index6.cjs"),g=require("./index7.cjs"),S=require("./index8.cjs"),n=require("./index9.cjs"),k=require("./index10.cjs"),p=require("./index11.cjs"),s=require("./index12.cjs"),h=require("pdfjs-dist"),P=require("./index13.cjs"),q=require("./index14.cjs"),f=require("./index15.cjs"),E=require("./index16.cjs"),A=require("./index17.cjs"),R=require("./index18.cjs"),m=require("./index19.cjs"),l=require("./index20.cjs"),a=require("./index21.cjs"),x=require("./index22.cjs"),y=require("./index23.cjs");function b(e){const o=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const i=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(o,r,i.get?i:{enumerable:!0,get:()=>e[r]})}}return o.default=e,Object.freeze(o)}const _=b(h);function D(e){if(typeof e!="string"||e.length===0)throw new Error("setupPdfWorker: workerSrc must be a non-empty string");_.GlobalWorkerOptions.workerSrc=e}const L="0.7.0",M="web-annotation-renderer";exports.AnnotationRenderer=c.AnnotationRenderer;exports.PDFRenderer=u.PDFRenderer;exports.TimelineSync=d.TimelineSync;exports.StrokeRenderer=T.StrokeRenderer;exports.BLUE_PRESET=t.BLUE_PRESET;exports.DEFAULT_PRESET=t.DEFAULT_PRESET;exports.MINIMAL_PRESET=t.MINIMAL_PRESET;exports.getPreset=t.getPreset;exports.getPresetNames=t.getPresetNames;exports.coordinateUtils=g;exports.viewportUtils=S;exports.extractAllBlocks=n.extractAllBlocks;exports.extractMultiplePages=n.extractMultiplePages;exports.extractPDFBlocks=n.extractAllBlocks;exports.normalizeAnnotationArray=k.normalizeAnnotationArray;exports.TypeValidators=p;exports.preloadCJK=s.preloadCJK;exports.setCJKDataUrl=s.setCJKDataUrl;exports.AnnotPdf=P.default;exports.highlightToStrokes=q.highlightToStrokes;exports.textToStrokes=f.textToStrokes;exports.underlineToStrokes=E.underlineToStrokes;exports.arrowToStrokes=A.arrowToStrokes;exports.circleToStrokes=R.circleToStrokes;exports.inkToStrokes=m.inkToStrokes;exports.annotationTools=l.annotationTools;exports.getAnnotationTools=l.getAnnotationTools;exports.handleToolCall=a.handleToolCall;exports.handleToolCalls=a.handleToolCalls;exports.createHighlight=x.createHighlight;exports.createText=y.createText;exports.LIB_NAME=M;exports.VERSION=L;exports.setupPdfWorker=D;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/index.js"],"sourcesContent":["/**\n * @ai-annotator/renderer - Public API\n *\n * Single entry point for the Dynamic PDF Annotation Renderer library.\n * Exports all core subsystems, utilities, and types.\n *\n * @module @ai-annotator/renderer\n */\n\n// ============================================================================\n// Core Rendering Engine\n// ============================================================================\n\nimport { AnnotationRenderer } from './core/AnnotationRenderer.js';\nimport { PDFRenderer } from './core/PDFRenderer.js';\nimport { TimelineSync } from './core/TimelineSync.js';\n\nexport { AnnotationRenderer };\nexport { PDFRenderer };\nexport { TimelineSync };\n\n// ============================================================================\n// Stroke Renderer - Unified Canvas-Based Annotation Rendering\n// ============================================================================\n\nimport { StrokeRenderer } from './renderer/StrokeRenderer.js';\n\nexport { StrokeRenderer };\n\n// ============================================================================\n// Converters - Annotation to Stroke Conversion\n// ============================================================================\n\nimport {\n highlightToStrokes,\n textToStrokes,\n underlineToStrokes,\n arrowToStrokes,\n circleToStrokes,\n inkToStrokes\n} from './converters/index.js';\n\nexport { highlightToStrokes };\nexport { textToStrokes };\nexport { underlineToStrokes };\nexport { arrowToStrokes };\nexport { circleToStrokes };\nexport { inkToStrokes };\n\n// ============================================================================\n//
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/index.js"],"sourcesContent":["/**\n * @ai-annotator/renderer - Public API\n *\n * Single entry point for the Dynamic PDF Annotation Renderer library.\n * Exports all core subsystems, utilities, and types.\n *\n * @module @ai-annotator/renderer\n */\n\n// ============================================================================\n// Core Rendering Engine\n// ============================================================================\n\nimport { AnnotationRenderer } from './core/AnnotationRenderer.js';\nimport { PDFRenderer } from './core/PDFRenderer.js';\nimport { TimelineSync } from './core/TimelineSync.js';\n\nexport { AnnotationRenderer };\nexport { PDFRenderer };\nexport { TimelineSync };\n\n// ============================================================================\n// Stroke Renderer - Unified Canvas-Based Annotation Rendering\n// ============================================================================\n\nimport { StrokeRenderer } from './renderer/StrokeRenderer.js';\n\nexport { StrokeRenderer };\n\n// ============================================================================\n// Converters - Annotation to Stroke Conversion\n// ============================================================================\n\nimport {\n highlightToStrokes,\n textToStrokes,\n underlineToStrokes,\n arrowToStrokes,\n circleToStrokes,\n inkToStrokes\n} from './converters/index.js';\n\nexport { highlightToStrokes };\nexport { textToStrokes };\nexport { underlineToStrokes };\nexport { arrowToStrokes };\nexport { circleToStrokes };\nexport { inkToStrokes };\n\n// ============================================================================\n// Style Presets - Ready-to-use configurations for strokeConfig\n// ============================================================================\n\nexport {\n getPreset,\n getPresetNames,\n DEFAULT_PRESET,\n BLUE_PRESET,\n MINIMAL_PRESET,\n} from './config/presets.js';\n\n// ============================================================================\n// Utilities\n// ============================================================================\n\nimport * as coordinateUtils from './utils/coordinateUtils.js';\nimport * as viewportUtils from './utils/viewportUtils.js';\n\nexport { coordinateUtils };\nexport { viewportUtils };\n\n// ============================================================================\n// PDF Extraction Utilities\n// ============================================================================\n\nimport { extractAllBlocks, extractMultiplePages } from './utils/pdfExtractor.js';\n\nexport { extractAllBlocks };\nexport { extractMultiplePages };\nexport { extractAllBlocks as extractPDFBlocks };\n\n// ============================================================================\n// Type Definitions & Validators\n// ============================================================================\n\nexport { normalizeAnnotationArray } from './types/validators.js';\nexport * as TypeValidators from './types/index.js';\n\n// ============================================================================\n// Framework Adapters\n// ============================================================================\n\nexport { AnnotPdf } from './adapters/index.js';\n\n// ============================================================================\n// AI Tools for Annotation Generation\n// ============================================================================\n\nexport {\n annotationTools,\n getAnnotationTools,\n handleToolCall,\n handleToolCalls,\n createHighlight,\n createText\n} from './ai-tools/index.js';\n\n// ============================================================================\n// Multilingual Text Support\n// ============================================================================\n\nexport { preloadCJK, setCJKDataUrl } from './converters/glyphResolver.js';\n\n// ============================================================================\n// PDF.js Worker Setup\n// ============================================================================\n\nimport * as pdfjsLib from 'pdfjs-dist';\n\n/**\n * Configure the pdf.js worker source. Call this once at app startup before\n * any PDF is loaded. The argument is whatever value you would otherwise\n * assign to `pdfjsLib.GlobalWorkerOptions.workerSrc` — typically the URL\n * of `pdfjs-dist/build/pdf.worker.mjs` (or `.min.js`) resolved by your\n * bundler.\n *\n * @example\n * import { setupPdfWorker } from 'web-annotation-renderer';\n * import workerSrc from 'pdfjs-dist/build/pdf.worker.mjs?url';\n * setupPdfWorker(workerSrc);\n *\n * @param {string} workerSrc URL or path to the pdf.js worker bundle.\n * @returns {void}\n */\nexport function setupPdfWorker(workerSrc) {\n if (typeof workerSrc !== 'string' || workerSrc.length === 0) {\n throw new Error('setupPdfWorker: workerSrc must be a non-empty string');\n }\n pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;\n}\n\n// ============================================================================\n// Package Metadata\n// ============================================================================\n\nexport const VERSION = '0.7.0';\nexport const LIB_NAME = 'web-annotation-renderer';\n"],"names":["setupPdfWorker","workerSrc","pdfjsLib","VERSION","LIB_NAME"],"mappings":"k9BAsIO,SAASA,EAAeC,EAAW,CACxC,GAAI,OAAOA,GAAc,UAAYA,EAAU,SAAW,EACxD,MAAM,IAAI,MAAM,sDAAsD,EAExEC,EAAS,oBAAoB,UAAYD,CAC3C,CAMY,MAACE,EAAU,QACVC,EAAW"}
|
package/dist/index.js
CHANGED
|
@@ -1,65 +1,66 @@
|
|
|
1
|
-
import { AnnotationRenderer as
|
|
2
|
-
import { PDFRenderer as
|
|
3
|
-
import { TimelineSync as
|
|
4
|
-
import { StrokeRenderer as
|
|
5
|
-
import
|
|
6
|
-
import * as
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
|
|
1
|
+
import { AnnotationRenderer as m } from "./index2.js";
|
|
2
|
+
import { PDFRenderer as x } from "./index3.js";
|
|
3
|
+
import { TimelineSync as c } from "./index4.js";
|
|
4
|
+
import { StrokeRenderer as k } from "./index5.js";
|
|
5
|
+
import { BLUE_PRESET as g, DEFAULT_PRESET as E, MINIMAL_PRESET as P, getPreset as A, getPresetNames as h } from "./index6.js";
|
|
6
|
+
import * as e from "./index7.js";
|
|
7
|
+
import * as t from "./index8.js";
|
|
8
|
+
import { extractAllBlocks as R, extractMultiplePages as w, extractAllBlocks as y } from "./index9.js";
|
|
9
|
+
import { normalizeAnnotationArray as L } from "./index10.js";
|
|
10
|
+
import * as n from "./index11.js";
|
|
11
|
+
import { preloadCJK as b, setCJKDataUrl as C } from "./index12.js";
|
|
12
|
+
import * as r from "pdfjs-dist";
|
|
13
|
+
import { default as I } from "./index13.js";
|
|
14
|
+
import { highlightToStrokes as N } from "./index14.js";
|
|
15
|
+
import { textToStrokes as F } from "./index15.js";
|
|
16
|
+
import { underlineToStrokes as J } from "./index16.js";
|
|
17
|
+
import { arrowToStrokes as O } from "./index17.js";
|
|
18
|
+
import { circleToStrokes as j } from "./index18.js";
|
|
19
|
+
import { inkToStrokes as z } from "./index19.js";
|
|
20
|
+
import { annotationTools as H, getAnnotationTools as q } from "./index20.js";
|
|
21
|
+
import { handleToolCall as X, handleToolCalls as Y } from "./index21.js";
|
|
22
|
+
import { createHighlight as $ } from "./index22.js";
|
|
23
|
+
import { createText as ro } from "./index23.js";
|
|
24
|
+
function a(o) {
|
|
25
|
+
if (typeof o != "string" || o.length === 0)
|
|
26
|
+
throw new Error("setupPdfWorker: workerSrc must be a non-empty string");
|
|
27
|
+
r.GlobalWorkerOptions.workerSrc = o;
|
|
28
|
+
}
|
|
29
|
+
const p = "0.7.0", s = "web-annotation-renderer";
|
|
26
30
|
export {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
L as arrowToStrokes,
|
|
42
|
-
_ as circleToStrokes,
|
|
31
|
+
I as AnnotPdf,
|
|
32
|
+
m as AnnotationRenderer,
|
|
33
|
+
g as BLUE_PRESET,
|
|
34
|
+
E as DEFAULT_PRESET,
|
|
35
|
+
s as LIB_NAME,
|
|
36
|
+
P as MINIMAL_PRESET,
|
|
37
|
+
x as PDFRenderer,
|
|
38
|
+
k as StrokeRenderer,
|
|
39
|
+
c as TimelineSync,
|
|
40
|
+
n as TypeValidators,
|
|
41
|
+
p as VERSION,
|
|
42
|
+
H as annotationTools,
|
|
43
|
+
O as arrowToStrokes,
|
|
44
|
+
j as circleToStrokes,
|
|
43
45
|
e as coordinateUtils,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
r as viewportUtils
|
|
46
|
+
$ as createHighlight,
|
|
47
|
+
ro as createText,
|
|
48
|
+
R as extractAllBlocks,
|
|
49
|
+
w as extractMultiplePages,
|
|
50
|
+
y as extractPDFBlocks,
|
|
51
|
+
q as getAnnotationTools,
|
|
52
|
+
A as getPreset,
|
|
53
|
+
h as getPresetNames,
|
|
54
|
+
X as handleToolCall,
|
|
55
|
+
Y as handleToolCalls,
|
|
56
|
+
N as highlightToStrokes,
|
|
57
|
+
z as inkToStrokes,
|
|
58
|
+
L as normalizeAnnotationArray,
|
|
59
|
+
b as preloadCJK,
|
|
60
|
+
C as setCJKDataUrl,
|
|
61
|
+
a as setupPdfWorker,
|
|
62
|
+
F as textToStrokes,
|
|
63
|
+
J as underlineToStrokes,
|
|
64
|
+
t as viewportUtils
|
|
64
65
|
};
|
|
65
66
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.js"],"sourcesContent":["/**\n * @ai-annotator/renderer - Public API\n *\n * Single entry point for the Dynamic PDF Annotation Renderer library.\n * Exports all core subsystems, utilities, and types.\n *\n * @module @ai-annotator/renderer\n */\n\n// ============================================================================\n// Core Rendering Engine\n// ============================================================================\n\nimport { AnnotationRenderer } from './core/AnnotationRenderer.js';\nimport { PDFRenderer } from './core/PDFRenderer.js';\nimport { TimelineSync } from './core/TimelineSync.js';\n\nexport { AnnotationRenderer };\nexport { PDFRenderer };\nexport { TimelineSync };\n\n// ============================================================================\n// Stroke Renderer - Unified Canvas-Based Annotation Rendering\n// ============================================================================\n\nimport { StrokeRenderer } from './renderer/StrokeRenderer.js';\n\nexport { StrokeRenderer };\n\n// ============================================================================\n// Converters - Annotation to Stroke Conversion\n// ============================================================================\n\nimport {\n highlightToStrokes,\n textToStrokes,\n underlineToStrokes,\n arrowToStrokes,\n circleToStrokes,\n inkToStrokes\n} from './converters/index.js';\n\nexport { highlightToStrokes };\nexport { textToStrokes };\nexport { underlineToStrokes };\nexport { arrowToStrokes };\nexport { circleToStrokes };\nexport { inkToStrokes };\n\n// ============================================================================\n//
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.js"],"sourcesContent":["/**\n * @ai-annotator/renderer - Public API\n *\n * Single entry point for the Dynamic PDF Annotation Renderer library.\n * Exports all core subsystems, utilities, and types.\n *\n * @module @ai-annotator/renderer\n */\n\n// ============================================================================\n// Core Rendering Engine\n// ============================================================================\n\nimport { AnnotationRenderer } from './core/AnnotationRenderer.js';\nimport { PDFRenderer } from './core/PDFRenderer.js';\nimport { TimelineSync } from './core/TimelineSync.js';\n\nexport { AnnotationRenderer };\nexport { PDFRenderer };\nexport { TimelineSync };\n\n// ============================================================================\n// Stroke Renderer - Unified Canvas-Based Annotation Rendering\n// ============================================================================\n\nimport { StrokeRenderer } from './renderer/StrokeRenderer.js';\n\nexport { StrokeRenderer };\n\n// ============================================================================\n// Converters - Annotation to Stroke Conversion\n// ============================================================================\n\nimport {\n highlightToStrokes,\n textToStrokes,\n underlineToStrokes,\n arrowToStrokes,\n circleToStrokes,\n inkToStrokes\n} from './converters/index.js';\n\nexport { highlightToStrokes };\nexport { textToStrokes };\nexport { underlineToStrokes };\nexport { arrowToStrokes };\nexport { circleToStrokes };\nexport { inkToStrokes };\n\n// ============================================================================\n// Style Presets - Ready-to-use configurations for strokeConfig\n// ============================================================================\n\nexport {\n getPreset,\n getPresetNames,\n DEFAULT_PRESET,\n BLUE_PRESET,\n MINIMAL_PRESET,\n} from './config/presets.js';\n\n// ============================================================================\n// Utilities\n// ============================================================================\n\nimport * as coordinateUtils from './utils/coordinateUtils.js';\nimport * as viewportUtils from './utils/viewportUtils.js';\n\nexport { coordinateUtils };\nexport { viewportUtils };\n\n// ============================================================================\n// PDF Extraction Utilities\n// ============================================================================\n\nimport { extractAllBlocks, extractMultiplePages } from './utils/pdfExtractor.js';\n\nexport { extractAllBlocks };\nexport { extractMultiplePages };\nexport { extractAllBlocks as extractPDFBlocks };\n\n// ============================================================================\n// Type Definitions & Validators\n// ============================================================================\n\nexport { normalizeAnnotationArray } from './types/validators.js';\nexport * as TypeValidators from './types/index.js';\n\n// ============================================================================\n// Framework Adapters\n// ============================================================================\n\nexport { AnnotPdf } from './adapters/index.js';\n\n// ============================================================================\n// AI Tools for Annotation Generation\n// ============================================================================\n\nexport {\n annotationTools,\n getAnnotationTools,\n handleToolCall,\n handleToolCalls,\n createHighlight,\n createText\n} from './ai-tools/index.js';\n\n// ============================================================================\n// Multilingual Text Support\n// ============================================================================\n\nexport { preloadCJK, setCJKDataUrl } from './converters/glyphResolver.js';\n\n// ============================================================================\n// PDF.js Worker Setup\n// ============================================================================\n\nimport * as pdfjsLib from 'pdfjs-dist';\n\n/**\n * Configure the pdf.js worker source. Call this once at app startup before\n * any PDF is loaded. The argument is whatever value you would otherwise\n * assign to `pdfjsLib.GlobalWorkerOptions.workerSrc` — typically the URL\n * of `pdfjs-dist/build/pdf.worker.mjs` (or `.min.js`) resolved by your\n * bundler.\n *\n * @example\n * import { setupPdfWorker } from 'web-annotation-renderer';\n * import workerSrc from 'pdfjs-dist/build/pdf.worker.mjs?url';\n * setupPdfWorker(workerSrc);\n *\n * @param {string} workerSrc URL or path to the pdf.js worker bundle.\n * @returns {void}\n */\nexport function setupPdfWorker(workerSrc) {\n if (typeof workerSrc !== 'string' || workerSrc.length === 0) {\n throw new Error('setupPdfWorker: workerSrc must be a non-empty string');\n }\n pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;\n}\n\n// ============================================================================\n// Package Metadata\n// ============================================================================\n\nexport const VERSION = '0.7.0';\nexport const LIB_NAME = 'web-annotation-renderer';\n"],"names":["setupPdfWorker","workerSrc","pdfjsLib","VERSION","LIB_NAME"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAsIO,SAASA,EAAeC,GAAW;AACxC,MAAI,OAAOA,KAAc,YAAYA,EAAU,WAAW;AACxD,UAAM,IAAI,MAAM,sDAAsD;AAExE,EAAAC,EAAS,oBAAoB,YAAYD;AAC3C;AAMY,MAACE,IAAU,SACVC,IAAW;"}
|
package/dist/index10.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./index25.cjs"),c=(t,o,i,e,n)=>t.push(`[${o}]: Field "${i}" invalid value "${e}", using default ${n}`);function u(t,o,i,e,n){const r=typeof t=="string"?parseFloat(t):t;return typeof r!="number"||Number.isNaN(r)?(c(n,i,e,t,o),o):r<0?(n.push(`[${i}]: Field "${e}" value ${r} below range [0,1], clamping to 0`),0):r>1?(n.push(`[${i}]: Field "${e}" value ${r} exceeds range [0,1], clamping to 1`),1):r}const D=/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/,L=/^rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(,\s*[\d.]+\s*)?\)$/,z=new Set(["red","blue","green","yellow","black","white","gray","grey","orange","purple","pink","brown","transparent"]);function A(t,o,i,e){if(typeof t=="string"){const n=t.trim();if(n&&(D.test(n)||L.test(n)||z.has(n.toLowerCase())))return n}return e.push(`[${i}]: Invalid color format "${t}", using default ${o}`),o}function _(t,o,i,e,n){const r=typeof t=="string"?parseFloat(t):t;return typeof r!="number"||Number.isNaN(r)||r<=0?(c(n,i,e,t,o),o):r}const m={x:.1,y:.1,w:.8,h:.05};function b(t,o,i,e){return!t||typeof t!="object"?(i.push(`[${o}]: Invalid quad object, using default`),{...e}):{x:u(t.x,e.x,o,"quad.x",i),y:u(t.y,e.y,o,"quad.y",i),w:u(t.w,e.w,o,"quad.w",i),h:u(t.h,e.h,o,"quad.h",i)}}function $(t,o,i,e,n){switch(o.kind){case"coord":return u(i,o.default,e,t,n);case"color":return A(i,o.default,e,n);case"content":return typeof i=="string"&&i.trim().length>0?i:(n.push(`[${e}]: Field "${t}" missing or empty, using default "${o.default}"`),o.default);case"mode":return i===o.expectedMode?i:(n.push(`[${e}]: Field "${t}" invalid value "${i}", using default "${o.expectedMode}"`),o.expectedMode);case"quads":{if(!Array.isArray(i)||i.length===0)return n.push(`[${e}]: Field "${t}" missing or empty, using default`),o.defaultQuads;const r=o.quadDefault||m;return i.map(l=>b(l,e,n,r))}default:return i}}function E(t,o,i,e){const n={...o};for(const[r,l]of Object.entries(t.fields))n[r]=$(r,l,i[r],o.id,e);if(t.style){const r=i.style&&typeof i.style=="object";!r&&t.styleRequired&&e.push(`[${o.id}]: Field "style" missing or invalid, using default`);const l={};for(const[a,f]of Object.entries(t.style)){const p=r?i.style[a]:void 0;l[a]=$(`style.${a}`,f,p,o.id,e)}n.style=l}return n}const U=t=>({kind:"coord",default:t}),d=t=>({kind:"color",default:t}),g=(t,o)=>Object.fromEntries(o.map(i=>[i,U(t[i])])),h={highlight:{fields:{mode:{kind:"mode",expectedMode:s.HIGHLIGHT_DEFAULTS.mode},quads:{kind:"quads",defaultQuads:s.HIGHLIGHT_DEFAULTS.quads,quadDefault:m}},style:{color:d(s.HIGHLIGHT_DEFAULTS.style.color)},styleRequired:!0},text:{fields:{content:{kind:"content",default:s.TEXT_DEFAULTS.content},...g(s.TEXT_DEFAULTS,["x","y","w","h"])},style:{bg:d(s.TEXT_DEFAULTS.style.bg),color:d(s.TEXT_DEFAULTS.style.color)},styleRequired:!0},underline:{fields:{quads:{kind:"quads",defaultQuads:s.UNDERLINE_DEFAULTS.quads,quadDefault:m}},style:{color:d(s.UNDERLINE_DEFAULTS.style.color)}},arrow:{fields:g(s.ARROW_DEFAULTS,["from_x","from_y","to_x","to_y"]),style:{color:d(s.ARROW_DEFAULTS.style.color)}},circle:{fields:g(s.CIRCLE_DEFAULTS,["cx","cy","rx","ry"]),style:{color:d(s.CIRCLE_DEFAULTS.style.color)}}};function F(t,o,i){const e={type:t.type};return typeof t.id=="string"&&t.id.trim().length>0?e.id=t.id.trim():(e.id=`anno-${Date.now()}-${Math.random().toString(36).slice(2,11)}`,i.push(`[${e.id}]: Auto-generated ID (original was missing or invalid)`)),typeof t.page=="number"&&t.page>=1?e.page=Math.floor(t.page):(c(o,e.id,"page",t.page,s.BASE_DEFAULTS.page),e.page=s.BASE_DEFAULTS.page),typeof t.start=="number"&&t.start>=0?e.start=t.start:(c(o,e.id,"start",t.start,s.BASE_DEFAULTS.start),e.start=s.BASE_DEFAULTS.start),typeof t.end!="number"||t.end<0?(o.push(`[${e.id}]: Field "end" invalid value "${t.end}", using start value ${e.start}`),e.end=e.start):t.end<e.start?(o.push(`[${e.id}]: Field "end" (${t.end}) < start (${e.start}), clamping to start`),e.end=e.start):e.end=t.end,e}const S=t=>(o,i,e)=>E(h[t],o,i,e),x=S("highlight"),I=S("text");function T(t,o){const i=[],e=[],n=f=>({annotation:null,warnings:i,info:e,critical:f});if(!t||typeof t!="object")return n(`Annotation at index ${o}: Not a valid object`);if(typeof t.type!="string"||t.type.trim().length===0)return n(`Annotation at index ${o}: Missing or invalid type field`);const r=t.type.trim(),l=F(t,i,e);let a;if(h[r])a=E(h[r],l,t,i);else if(r==="ink")a={...l,strokes:t.strokes||[]},t.style&&(a.style=t.style);else return n(`Annotation at index ${o}: Unsupported type "${r}"`);return{annotation:a,warnings:i,info:e,critical:null}}function k(t,o={}){const i=o.warnInConsole!==!1,e=typeof o.onWarning=="function"?o.onWarning:null,n={normalized:[],warnings:[],info:[],skipped:[]};if(!Array.isArray(t)){const r="normalizeAnnotationArray: Input is not an array, returning empty result";return n.warnings.push(r),i&&console.warn(`[Annotation Normalizer] ${r}`),n}return t.forEach((r,l)=>{if(r==null){n.skipped.push({index:l,annotation:r,reason:"Annotation is null or undefined"});return}const{annotation:a,warnings:f,info:p,critical:y}=T(r,l);if(y){n.skipped.push({index:l,annotation:r,reason:y}),i&&console.error(`[Annotation Normalizer] ${y}`);return}n.normalized.push(a),n.warnings.push(...f),n.info.push(...p)}),i&&(n.warnings.length||n.info.length||n.skipped.length)&&(console.group("[Annotation Normalizer] Validation Summary"),n.normalized.length&&console.info(`✓ Normalized ${n.normalized.length} annotation(s)`),n.skipped.length&&(console.error(`✗ Skipped ${n.skipped.length} annotation(s)`),n.skipped.forEach(r=>console.error(` Index ${r.index}: ${r.reason}`))),n.warnings.length&&(console.warn(`⚠ ${n.warnings.length} warning(s):`),n.warnings.forEach(r=>console.warn(` ${r}`))),n.info.length&&(console.info(`ℹ ${n.info.length} info message(s):`),n.info.forEach(r=>console.info(` ${r}`))),console.groupEnd()),e&&e(n),n}exports.normalizeAnnotation=T;exports.normalizeAnnotationArray=k;exports.normalizeBaseFields=F;exports.normalizeColor=A;exports.normalizeCoordinate=u;exports.normalizeHighlight=x;exports.normalizePositiveNumber=_;exports.normalizeText=I;
|
|
2
2
|
//# sourceMappingURL=index10.cjs.map
|
package/dist/index10.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index10.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index10.cjs","sources":["../src/types/validators.js"],"sourcesContent":["/**\n * Annotation Data Normalization (Schema-Driven)\n *\n * Defensive normalizers that validate raw annotation input, clamp\n * out-of-range values, fill missing fields from defaults, and collect\n * human-readable warnings. The hand-rolled per-type normalizers were\n * replaced by per-type schemas walked through a small set of field-level\n * validators. Public function surface is preserved for backward compat.\n *\n * @module types/validators\n */\n\nimport {\n BASE_DEFAULTS,\n HIGHLIGHT_DEFAULTS,\n TEXT_DEFAULTS,\n UNDERLINE_DEFAULTS,\n ARROW_DEFAULTS,\n CIRCLE_DEFAULTS,\n} from './defaults.js';\n\n// --- Field-level normalizers ------------------------------------------------\n\nconst warnInvalid = (warnings, id, fieldName, value, defaultValue) =>\n warnings.push(`[${id}]: Field \"${fieldName}\" invalid value \"${value}\", using default ${defaultValue}`);\n\n/**\n * Coerce a value into the 0–1 range. Strings are parsed; out-of-range values\n * clamp to 0/1; non-numeric values fall back to `defaultValue`. Each fixup\n * appends a warning.\n */\nexport function normalizeCoordinate(value, defaultValue, id, fieldName, warnings) {\n const num = typeof value === 'string' ? parseFloat(value) : value;\n if (typeof num !== 'number' || Number.isNaN(num)) {\n warnInvalid(warnings, id, fieldName, value, defaultValue);\n return defaultValue;\n }\n if (num < 0) {\n warnings.push(`[${id}]: Field \"${fieldName}\" value ${num} below range [0,1], clamping to 0`);\n return 0;\n }\n if (num > 1) {\n warnings.push(`[${id}]: Field \"${fieldName}\" value ${num} exceeds range [0,1], clamping to 1`);\n return 1;\n }\n return num;\n}\n\nconst HEX_RE = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/;\nconst RGB_RE = /^rgba?\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*(,\\s*[\\d.]+\\s*)?\\)$/;\nconst NAMED_COLORS = new Set([\n 'red', 'blue', 'green', 'yellow', 'black', 'white', 'gray', 'grey',\n 'orange', 'purple', 'pink', 'brown', 'transparent',\n]);\n\n/** Validate a color string (hex / rgb(a) / a small named-color set). */\nexport function normalizeColor(value, defaultValue, id, warnings) {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed && (HEX_RE.test(trimmed) || RGB_RE.test(trimmed) || NAMED_COLORS.has(trimmed.toLowerCase()))) {\n return trimmed;\n }\n }\n warnings.push(`[${id}]: Invalid color format \"${value}\", using default ${defaultValue}`);\n return defaultValue;\n}\n\n/** Validate a strictly positive number (`> 0`). Strings are parsed first. */\nexport function normalizePositiveNumber(value, defaultValue, id, fieldName, warnings) {\n const num = typeof value === 'string' ? parseFloat(value) : value;\n if (typeof num !== 'number' || Number.isNaN(num) || num <= 0) {\n warnInvalid(warnings, id, fieldName, value, defaultValue);\n return defaultValue;\n }\n return num;\n}\n\n// --- Schema walker ----------------------------------------------------------\n\n/**\n * @typedef {Object} FieldSpec\n * @property {'coord'|'color'|'content'|'mode'|'quads'} kind\n * @property {*} [default] invalid/missing → this value\n * @property {string} [expectedMode] kind='mode': the only accepted literal\n * @property {Object} [quadDefault] kind='quads': per-quad fallback\n * @property {Array} [defaultQuads] kind='quads': fallback when array missing\n *\n * @typedef {Object} TypeSchema\n * @property {Object<string, FieldSpec>} fields top-level fields keyed by name\n * @property {Object<string, FieldSpec>} [style] optional style.* fields\n * @property {boolean} [styleRequired] warn when raw.style missing\n */\n\n/** Per-quad fallback shared by highlight & underline schemas. */\nconst DEFAULT_QUAD = { x: 0.1, y: 0.1, w: 0.8, h: 0.05 };\n\n/** Normalize one quad object via `normalizeCoordinate` per field. */\nfunction normalizeQuad(quad, id, warnings, fallback) {\n if (!quad || typeof quad !== 'object') {\n warnings.push(`[${id}]: Invalid quad object, using default`);\n return { ...fallback };\n }\n return {\n x: normalizeCoordinate(quad.x, fallback.x, id, 'quad.x', warnings),\n y: normalizeCoordinate(quad.y, fallback.y, id, 'quad.y', warnings),\n w: normalizeCoordinate(quad.w, fallback.w, id, 'quad.w', warnings),\n h: normalizeCoordinate(quad.h, fallback.h, id, 'quad.h', warnings),\n };\n}\n\n/** Normalize a single field according to its schema spec. */\nfunction applyFieldSpec(name, spec, value, id, warnings) {\n switch (spec.kind) {\n case 'coord':\n return normalizeCoordinate(value, spec.default, id, name, warnings);\n case 'color':\n return normalizeColor(value, spec.default, id, warnings);\n case 'content':\n if (typeof value === 'string' && value.trim().length > 0) return value;\n warnings.push(`[${id}]: Field \"${name}\" missing or empty, using default \"${spec.default}\"`);\n return spec.default;\n case 'mode':\n if (value === spec.expectedMode) return value;\n warnings.push(`[${id}]: Field \"${name}\" invalid value \"${value}\", using default \"${spec.expectedMode}\"`);\n return spec.expectedMode;\n case 'quads': {\n if (!Array.isArray(value) || value.length === 0) {\n warnings.push(`[${id}]: Field \"${name}\" missing or empty, using default`);\n return spec.defaultQuads;\n }\n const fallback = spec.quadDefault || DEFAULT_QUAD;\n return value.map((q) => normalizeQuad(q, id, warnings, fallback));\n }\n default:\n return value;\n }\n}\n\n/** Apply a `TypeSchema` to a raw annotation, producing the normalized output. */\nfunction applySchema(schema, base, raw, warnings) {\n const out = { ...base };\n for (const [name, spec] of Object.entries(schema.fields)) {\n out[name] = applyFieldSpec(name, spec, raw[name], base.id, warnings);\n }\n if (schema.style) {\n const hasStyle = raw.style && typeof raw.style === 'object';\n if (!hasStyle && schema.styleRequired) {\n warnings.push(`[${base.id}]: Field \"style\" missing or invalid, using default`);\n }\n const style = {};\n for (const [name, spec] of Object.entries(schema.style)) {\n const value = hasStyle ? raw.style[name] : undefined;\n style[name] = applyFieldSpec(`style.${name}`, spec, value, base.id, warnings);\n }\n out.style = style;\n }\n return out;\n}\n\n// --- Per-type schemas (single source of truth for field validation) --------\n\nconst coord = (def) => ({ kind: 'coord', default: def });\nconst color = (def) => ({ kind: 'color', default: def });\nconst coordsFromDefaults = (defaults, names) =>\n Object.fromEntries(names.map((n) => [n, coord(defaults[n])]));\n\n/** @type {Object<string, TypeSchema>} */\nconst SCHEMAS = {\n highlight: {\n fields: {\n mode: { kind: 'mode', expectedMode: HIGHLIGHT_DEFAULTS.mode },\n quads: { kind: 'quads', defaultQuads: HIGHLIGHT_DEFAULTS.quads, quadDefault: DEFAULT_QUAD },\n },\n style: { color: color(HIGHLIGHT_DEFAULTS.style.color) },\n styleRequired: true,\n },\n text: {\n fields: {\n content: { kind: 'content', default: TEXT_DEFAULTS.content },\n ...coordsFromDefaults(TEXT_DEFAULTS, ['x', 'y', 'w', 'h']),\n },\n style: {\n bg: color(TEXT_DEFAULTS.style.bg),\n color: color(TEXT_DEFAULTS.style.color),\n },\n styleRequired: true,\n },\n underline: {\n fields: {\n quads: { kind: 'quads', defaultQuads: UNDERLINE_DEFAULTS.quads, quadDefault: DEFAULT_QUAD },\n },\n style: { color: color(UNDERLINE_DEFAULTS.style.color) },\n },\n arrow: {\n fields: coordsFromDefaults(ARROW_DEFAULTS, ['from_x', 'from_y', 'to_x', 'to_y']),\n style: { color: color(ARROW_DEFAULTS.style.color) },\n },\n circle: {\n fields: coordsFromDefaults(CIRCLE_DEFAULTS, ['cx', 'cy', 'rx', 'ry']),\n style: { color: color(CIRCLE_DEFAULTS.style.color) },\n },\n};\n\n// --- Base-field normalization -----------------------------------------------\n\n/**\n * Normalize fields common to every annotation: `id`, `type`, `page`, `start`,\n * `end`. Auto-generates `id` when missing (logged to `info`).\n */\nexport function normalizeBaseFields(raw, warnings, info) {\n const base = { type: raw.type };\n\n if (typeof raw.id === 'string' && raw.id.trim().length > 0) {\n base.id = raw.id.trim();\n } else {\n base.id = `anno-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n info.push(`[${base.id}]: Auto-generated ID (original was missing or invalid)`);\n }\n\n if (typeof raw.page === 'number' && raw.page >= 1) {\n base.page = Math.floor(raw.page);\n } else {\n warnInvalid(warnings, base.id, 'page', raw.page, BASE_DEFAULTS.page);\n base.page = BASE_DEFAULTS.page;\n }\n\n if (typeof raw.start === 'number' && raw.start >= 0) {\n base.start = raw.start;\n } else {\n warnInvalid(warnings, base.id, 'start', raw.start, BASE_DEFAULTS.start);\n base.start = BASE_DEFAULTS.start;\n }\n\n if (typeof raw.end !== 'number' || raw.end < 0) {\n warnings.push(`[${base.id}]: Field \"end\" invalid value \"${raw.end}\", using start value ${base.start}`);\n base.end = base.start;\n } else if (raw.end < base.start) {\n warnings.push(`[${base.id}]: Field \"end\" (${raw.end}) < start (${base.start}), clamping to start`);\n base.end = base.start;\n } else {\n base.end = raw.end;\n }\n\n return base;\n}\n\n// Per-type wrappers — kept for API parity. `info` is accepted for the legacy\n// v0.6.x signature but unused; only `normalizeBaseFields` writes to it.\nconst wrap = (key) => (base, raw, warnings) => applySchema(SCHEMAS[key], base, raw, warnings);\nexport const normalizeHighlight = wrap('highlight');\nexport const normalizeText = wrap('text');\nexport const normalizeUnderline = wrap('underline');\nexport const normalizeArrow = wrap('arrow');\nexport const normalizeCircle = wrap('circle');\n\n// --- Single-annotation and array entry points ------------------------------\n\n/**\n * Normalize a single raw annotation, dispatching on `type`. Returns\n * `{annotation, warnings, info, critical}`; `critical` is non-null when the\n * input is unrecoverable (missing/unknown `type`, not an object).\n */\nexport function normalizeAnnotation(raw, index) {\n const warnings = [];\n const info = [];\n const fail = (reason) => ({ annotation: null, warnings, info, critical: reason });\n\n if (!raw || typeof raw !== 'object') return fail(`Annotation at index ${index}: Not a valid object`);\n if (typeof raw.type !== 'string' || raw.type.trim().length === 0) {\n return fail(`Annotation at index ${index}: Missing or invalid type field`);\n }\n\n const type = raw.type.trim();\n const base = normalizeBaseFields(raw, warnings, info);\n let annotation;\n\n if (SCHEMAS[type]) {\n annotation = applySchema(SCHEMAS[type], base, raw, warnings);\n } else if (type === 'ink') {\n // Ink carries pre-built strokes from upstream; pass through unchanged.\n annotation = { ...base, strokes: raw.strokes || [] };\n if (raw.style) annotation.style = raw.style;\n } else {\n return fail(`Annotation at index ${index}: Unsupported type \"${type}\"`);\n }\n\n return { annotation, warnings, info, critical: null };\n}\n\n/**\n * Main entry point. Normalizes each raw annotation and returns a\n * `ValidationResult` shape — `{normalized, warnings, info, skipped}`.\n *\n * @param {Array} rawAnnotations\n * @param {{warnInConsole?: boolean, onWarning?: Function}} [options]\n */\nexport function normalizeAnnotationArray(rawAnnotations, options = {}) {\n const warnInConsole = options.warnInConsole !== false;\n const onWarning = typeof options.onWarning === 'function' ? options.onWarning : null;\n\n const result = { normalized: [], warnings: [], info: [], skipped: [] };\n\n if (!Array.isArray(rawAnnotations)) {\n const msg = 'normalizeAnnotationArray: Input is not an array, returning empty result';\n result.warnings.push(msg);\n if (warnInConsole) console.warn(`[Annotation Normalizer] ${msg}`);\n return result;\n }\n\n rawAnnotations.forEach((raw, index) => {\n if (raw == null) {\n result.skipped.push({ index, annotation: raw, reason: 'Annotation is null or undefined' });\n return;\n }\n\n const { annotation, warnings, info, critical } = normalizeAnnotation(raw, index);\n\n if (critical) {\n result.skipped.push({ index, annotation: raw, reason: critical });\n if (warnInConsole) console.error(`[Annotation Normalizer] ${critical}`);\n return;\n }\n\n result.normalized.push(annotation);\n result.warnings.push(...warnings);\n result.info.push(...info);\n });\n\n if (warnInConsole && (result.warnings.length || result.info.length || result.skipped.length)) {\n console.group('[Annotation Normalizer] Validation Summary');\n if (result.normalized.length) console.info(`✓ Normalized ${result.normalized.length} annotation(s)`);\n if (result.skipped.length) {\n console.error(`✗ Skipped ${result.skipped.length} annotation(s)`);\n result.skipped.forEach((s) => console.error(` Index ${s.index}: ${s.reason}`));\n }\n if (result.warnings.length) {\n console.warn(`⚠ ${result.warnings.length} warning(s):`);\n result.warnings.forEach((w) => console.warn(` ${w}`));\n }\n if (result.info.length) {\n console.info(`ℹ ${result.info.length} info message(s):`);\n result.info.forEach((i) => console.info(` ${i}`));\n }\n console.groupEnd();\n }\n\n if (onWarning) onWarning(result);\n return result;\n}\n"],"names":["warnInvalid","warnings","id","fieldName","value","defaultValue","normalizeCoordinate","num","HEX_RE","RGB_RE","NAMED_COLORS","normalizeColor","trimmed","normalizePositiveNumber","DEFAULT_QUAD","normalizeQuad","quad","fallback","applyFieldSpec","name","spec","q","applySchema","schema","base","raw","out","hasStyle","style","coord","def","color","coordsFromDefaults","defaults","names","n","SCHEMAS","HIGHLIGHT_DEFAULTS","TEXT_DEFAULTS","UNDERLINE_DEFAULTS","ARROW_DEFAULTS","CIRCLE_DEFAULTS","normalizeBaseFields","info","BASE_DEFAULTS","wrap","key","normalizeHighlight","normalizeText","normalizeAnnotation","index","fail","reason","type","annotation","normalizeAnnotationArray","rawAnnotations","options","warnInConsole","onWarning","result","msg","critical","s","w","i"],"mappings":"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"}
|
package/dist/index10.js
CHANGED
|
@@ -1,16 +1,163 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { UNDERLINE_DEFAULTS as E, TEXT_DEFAULTS as f, HIGHLIGHT_DEFAULTS as m, BASE_DEFAULTS as c, CIRCLE_DEFAULTS as F, ARROW_DEFAULTS as x } from "./index25.js";
|
|
2
|
+
const p = (t, o, i, e, n) => t.push(`[${o}]: Field "${i}" invalid value "${e}", using default ${n}`);
|
|
3
|
+
function u(t, o, i, e, n) {
|
|
4
|
+
const r = typeof t == "string" ? parseFloat(t) : t;
|
|
5
|
+
return typeof r != "number" || Number.isNaN(r) ? (p(n, i, e, t, o), o) : r < 0 ? (n.push(`[${i}]: Field "${e}" value ${r} below range [0,1], clamping to 0`), 0) : r > 1 ? (n.push(`[${i}]: Field "${e}" value ${r} exceeds range [0,1], clamping to 1`), 1) : r;
|
|
6
|
+
}
|
|
7
|
+
const S = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/, D = /^rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(,\s*[\d.]+\s*)?\)$/, _ = /* @__PURE__ */ new Set([
|
|
8
|
+
"red",
|
|
9
|
+
"blue",
|
|
10
|
+
"green",
|
|
11
|
+
"yellow",
|
|
12
|
+
"black",
|
|
13
|
+
"white",
|
|
14
|
+
"gray",
|
|
15
|
+
"grey",
|
|
16
|
+
"orange",
|
|
17
|
+
"purple",
|
|
18
|
+
"pink",
|
|
19
|
+
"brown",
|
|
20
|
+
"transparent"
|
|
21
|
+
]);
|
|
22
|
+
function q(t, o, i, e) {
|
|
23
|
+
if (typeof t == "string") {
|
|
24
|
+
const n = t.trim();
|
|
25
|
+
if (n && (S.test(n) || D.test(n) || _.has(n.toLowerCase())))
|
|
26
|
+
return n;
|
|
27
|
+
}
|
|
28
|
+
return e.push(`[${i}]: Invalid color format "${t}", using default ${o}`), o;
|
|
29
|
+
}
|
|
30
|
+
function U(t, o, i, e, n) {
|
|
31
|
+
const r = typeof t == "string" ? parseFloat(t) : t;
|
|
32
|
+
return typeof r != "number" || Number.isNaN(r) || r <= 0 ? (p(n, i, e, t, o), o) : r;
|
|
33
|
+
}
|
|
34
|
+
const $ = { x: 0.1, y: 0.1, w: 0.8, h: 0.05 };
|
|
35
|
+
function N(t, o, i, e) {
|
|
36
|
+
return !t || typeof t != "object" ? (i.push(`[${o}]: Invalid quad object, using default`), { ...e }) : {
|
|
37
|
+
x: u(t.x, e.x, o, "quad.x", i),
|
|
38
|
+
y: u(t.y, e.y, o, "quad.y", i),
|
|
39
|
+
w: u(t.w, e.w, o, "quad.w", i),
|
|
40
|
+
h: u(t.h, e.h, o, "quad.h", i)
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function b(t, o, i, e, n) {
|
|
44
|
+
switch (o.kind) {
|
|
45
|
+
case "coord":
|
|
46
|
+
return u(i, o.default, e, t, n);
|
|
47
|
+
case "color":
|
|
48
|
+
return q(i, o.default, e, n);
|
|
49
|
+
case "content":
|
|
50
|
+
return typeof i == "string" && i.trim().length > 0 ? i : (n.push(`[${e}]: Field "${t}" missing or empty, using default "${o.default}"`), o.default);
|
|
51
|
+
case "mode":
|
|
52
|
+
return i === o.expectedMode ? i : (n.push(`[${e}]: Field "${t}" invalid value "${i}", using default "${o.expectedMode}"`), o.expectedMode);
|
|
53
|
+
case "quads": {
|
|
54
|
+
if (!Array.isArray(i) || i.length === 0)
|
|
55
|
+
return n.push(`[${e}]: Field "${t}" missing or empty, using default`), o.defaultQuads;
|
|
56
|
+
const r = o.quadDefault || $;
|
|
57
|
+
return i.map((s) => N(s, e, n, r));
|
|
58
|
+
}
|
|
59
|
+
default:
|
|
60
|
+
return i;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function z(t, o, i, e) {
|
|
64
|
+
const n = { ...o };
|
|
65
|
+
for (const [r, s] of Object.entries(t.fields))
|
|
66
|
+
n[r] = b(r, s, i[r], o.id, e);
|
|
67
|
+
if (t.style) {
|
|
68
|
+
const r = i.style && typeof i.style == "object";
|
|
69
|
+
!r && t.styleRequired && e.push(`[${o.id}]: Field "style" missing or invalid, using default`);
|
|
70
|
+
const s = {};
|
|
71
|
+
for (const [l, d] of Object.entries(t.style)) {
|
|
72
|
+
const y = r ? i.style[l] : void 0;
|
|
73
|
+
s[l] = b(`style.${l}`, d, y, o.id, e);
|
|
74
|
+
}
|
|
75
|
+
n.style = s;
|
|
76
|
+
}
|
|
77
|
+
return n;
|
|
78
|
+
}
|
|
79
|
+
const I = (t) => ({ kind: "coord", default: t }), a = (t) => ({ kind: "color", default: t }), h = (t, o) => Object.fromEntries(o.map((i) => [i, I(t[i])])), A = {
|
|
80
|
+
highlight: {
|
|
81
|
+
fields: {
|
|
82
|
+
mode: { kind: "mode", expectedMode: m.mode },
|
|
83
|
+
quads: { kind: "quads", defaultQuads: m.quads, quadDefault: $ }
|
|
84
|
+
},
|
|
85
|
+
style: { color: a(m.style.color) },
|
|
86
|
+
styleRequired: !0
|
|
87
|
+
},
|
|
88
|
+
text: {
|
|
89
|
+
fields: {
|
|
90
|
+
content: { kind: "content", default: f.content },
|
|
91
|
+
...h(f, ["x", "y", "w", "h"])
|
|
92
|
+
},
|
|
93
|
+
style: {
|
|
94
|
+
bg: a(f.style.bg),
|
|
95
|
+
color: a(f.style.color)
|
|
96
|
+
},
|
|
97
|
+
styleRequired: !0
|
|
98
|
+
},
|
|
99
|
+
underline: {
|
|
100
|
+
fields: {
|
|
101
|
+
quads: { kind: "quads", defaultQuads: E.quads, quadDefault: $ }
|
|
102
|
+
},
|
|
103
|
+
style: { color: a(E.style.color) }
|
|
104
|
+
},
|
|
105
|
+
arrow: {
|
|
106
|
+
fields: h(x, ["from_x", "from_y", "to_x", "to_y"]),
|
|
107
|
+
style: { color: a(x.style.color) }
|
|
108
|
+
},
|
|
109
|
+
circle: {
|
|
110
|
+
fields: h(F, ["cx", "cy", "rx", "ry"]),
|
|
111
|
+
style: { color: a(F.style.color) }
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
function L(t, o, i) {
|
|
115
|
+
const e = { type: t.type };
|
|
116
|
+
return typeof t.id == "string" && t.id.trim().length > 0 ? e.id = t.id.trim() : (e.id = `anno-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`, i.push(`[${e.id}]: Auto-generated ID (original was missing or invalid)`)), typeof t.page == "number" && t.page >= 1 ? e.page = Math.floor(t.page) : (p(o, e.id, "page", t.page, c.page), e.page = c.page), typeof t.start == "number" && t.start >= 0 ? e.start = t.start : (p(o, e.id, "start", t.start, c.start), e.start = c.start), typeof t.end != "number" || t.end < 0 ? (o.push(`[${e.id}]: Field "end" invalid value "${t.end}", using start value ${e.start}`), e.end = e.start) : t.end < e.start ? (o.push(`[${e.id}]: Field "end" (${t.end}) < start (${e.start}), clamping to start`), e.end = e.start) : e.end = t.end, e;
|
|
117
|
+
}
|
|
118
|
+
const k = (t) => (o, i, e) => z(A[t], o, i, e), C = k("highlight"), M = k("text");
|
|
119
|
+
function R(t, o) {
|
|
120
|
+
const i = [], e = [], n = (d) => ({ annotation: null, warnings: i, info: e, critical: d });
|
|
121
|
+
if (!t || typeof t != "object") return n(`Annotation at index ${o}: Not a valid object`);
|
|
122
|
+
if (typeof t.type != "string" || t.type.trim().length === 0)
|
|
123
|
+
return n(`Annotation at index ${o}: Missing or invalid type field`);
|
|
124
|
+
const r = t.type.trim(), s = L(t, i, e);
|
|
125
|
+
let l;
|
|
126
|
+
if (A[r])
|
|
127
|
+
l = z(A[r], s, t, i);
|
|
128
|
+
else if (r === "ink")
|
|
129
|
+
l = { ...s, strokes: t.strokes || [] }, t.style && (l.style = t.style);
|
|
130
|
+
else
|
|
131
|
+
return n(`Annotation at index ${o}: Unsupported type "${r}"`);
|
|
132
|
+
return { annotation: l, warnings: i, info: e, critical: null };
|
|
133
|
+
}
|
|
134
|
+
function j(t, o = {}) {
|
|
135
|
+
const i = o.warnInConsole !== !1, e = typeof o.onWarning == "function" ? o.onWarning : null, n = { normalized: [], warnings: [], info: [], skipped: [] };
|
|
136
|
+
if (!Array.isArray(t)) {
|
|
137
|
+
const r = "normalizeAnnotationArray: Input is not an array, returning empty result";
|
|
138
|
+
return n.warnings.push(r), i && console.warn(`[Annotation Normalizer] ${r}`), n;
|
|
139
|
+
}
|
|
140
|
+
return t.forEach((r, s) => {
|
|
141
|
+
if (r == null) {
|
|
142
|
+
n.skipped.push({ index: s, annotation: r, reason: "Annotation is null or undefined" });
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const { annotation: l, warnings: d, info: y, critical: g } = R(r, s);
|
|
146
|
+
if (g) {
|
|
147
|
+
n.skipped.push({ index: s, annotation: r, reason: g }), i && console.error(`[Annotation Normalizer] ${g}`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
n.normalized.push(l), n.warnings.push(...d), n.info.push(...y);
|
|
151
|
+
}), i && (n.warnings.length || n.info.length || n.skipped.length) && (console.group("[Annotation Normalizer] Validation Summary"), n.normalized.length && console.info(`✓ Normalized ${n.normalized.length} annotation(s)`), n.skipped.length && (console.error(`✗ Skipped ${n.skipped.length} annotation(s)`), n.skipped.forEach((r) => console.error(` Index ${r.index}: ${r.reason}`))), n.warnings.length && (console.warn(`⚠ ${n.warnings.length} warning(s):`), n.warnings.forEach((r) => console.warn(` ${r}`))), n.info.length && (console.info(`ℹ ${n.info.length} info message(s):`), n.info.forEach((r) => console.info(` ${r}`))), console.groupEnd()), e && e(n), n;
|
|
152
|
+
}
|
|
3
153
|
export {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
m as normalizeHighlight,
|
|
13
|
-
t as normalizePositiveNumber,
|
|
14
|
-
z as normalizeText
|
|
154
|
+
R as normalizeAnnotation,
|
|
155
|
+
j as normalizeAnnotationArray,
|
|
156
|
+
L as normalizeBaseFields,
|
|
157
|
+
q as normalizeColor,
|
|
158
|
+
u as normalizeCoordinate,
|
|
159
|
+
C as normalizeHighlight,
|
|
160
|
+
U as normalizePositiveNumber,
|
|
161
|
+
M as normalizeText
|
|
15
162
|
};
|
|
16
163
|
//# sourceMappingURL=index10.js.map
|