@twinfinity/printing 5.0.3-ci.28538-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +208 -0
- package/dist/BuildInfo.d.ts +25 -0
- package/dist/BuildInfo.d.ts.map +1 -0
- package/dist/BuildInfo.js +15 -0
- package/dist/BuildInfo.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/analyzeTemplate.d.ts +29 -0
- package/dist/layout/analyzeTemplate.d.ts.map +1 -0
- package/dist/layout/analyzeTemplate.js +168 -0
- package/dist/layout/analyzeTemplate.js.map +1 -0
- package/dist/layout/clipUtils.d.ts +18 -0
- package/dist/layout/clipUtils.d.ts.map +1 -0
- package/dist/layout/clipUtils.js +165 -0
- package/dist/layout/clipUtils.js.map +1 -0
- package/dist/layout/colorConstants.d.ts +11 -0
- package/dist/layout/colorConstants.d.ts.map +1 -0
- package/dist/layout/colorConstants.js +14 -0
- package/dist/layout/colorConstants.js.map +1 -0
- package/dist/layout/elementKinds.d.ts +21 -0
- package/dist/layout/elementKinds.d.ts.map +1 -0
- package/dist/layout/elementKinds.js +17 -0
- package/dist/layout/elementKinds.js.map +1 -0
- package/dist/layout/exportDrawing.d.ts +143 -0
- package/dist/layout/exportDrawing.d.ts.map +1 -0
- package/dist/layout/exportDrawing.js +146 -0
- package/dist/layout/exportDrawing.js.map +1 -0
- package/dist/layout/filters.d.ts +33 -0
- package/dist/layout/filters.d.ts.map +1 -0
- package/dist/layout/filters.js +77 -0
- package/dist/layout/filters.js.map +1 -0
- package/dist/layout/geometryConstants.d.ts +8 -0
- package/dist/layout/geometryConstants.d.ts.map +1 -0
- package/dist/layout/geometryConstants.js +10 -0
- package/dist/layout/geometryConstants.js.map +1 -0
- package/dist/layout/index.d.ts +86 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/layout/index.js +363 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/layout/itemBuilders.d.ts +29 -0
- package/dist/layout/itemBuilders.d.ts.map +1 -0
- package/dist/layout/itemBuilders.js +135 -0
- package/dist/layout/itemBuilders.js.map +1 -0
- package/dist/layout/labelsRender.d.ts +29 -0
- package/dist/layout/labelsRender.d.ts.map +1 -0
- package/dist/layout/labelsRender.js +109 -0
- package/dist/layout/labelsRender.js.map +1 -0
- package/dist/layout/legendConstants.d.ts +12 -0
- package/dist/layout/legendConstants.d.ts.map +1 -0
- package/dist/layout/legendConstants.js +12 -0
- package/dist/layout/legendConstants.js.map +1 -0
- package/dist/layout/legendRender.d.ts +13 -0
- package/dist/layout/legendRender.d.ts.map +1 -0
- package/dist/layout/legendRender.js +424 -0
- package/dist/layout/legendRender.js.map +1 -0
- package/dist/layout/legendRows.d.ts +26 -0
- package/dist/layout/legendRows.d.ts.map +1 -0
- package/dist/layout/legendRows.js +45 -0
- package/dist/layout/legendRows.js.map +1 -0
- package/dist/layout/legendUtils.d.ts +21 -0
- package/dist/layout/legendUtils.d.ts.map +1 -0
- package/dist/layout/legendUtils.js +110 -0
- package/dist/layout/legendUtils.js.map +1 -0
- package/dist/layout/metadata.d.ts +43 -0
- package/dist/layout/metadata.d.ts.map +1 -0
- package/dist/layout/metadata.js +191 -0
- package/dist/layout/metadata.js.map +1 -0
- package/dist/layout/model.d.ts +15 -0
- package/dist/layout/model.d.ts.map +1 -0
- package/dist/layout/model.js +310 -0
- package/dist/layout/model.js.map +1 -0
- package/dist/layout/options.d.ts +17 -0
- package/dist/layout/options.d.ts.map +1 -0
- package/dist/layout/options.js +2 -0
- package/dist/layout/options.js.map +1 -0
- package/dist/layout/presets.d.ts +23 -0
- package/dist/layout/presets.d.ts.map +1 -0
- package/dist/layout/presets.js +41 -0
- package/dist/layout/presets.js.map +1 -0
- package/dist/layout/qrRender.d.ts +13 -0
- package/dist/layout/qrRender.d.ts.map +1 -0
- package/dist/layout/qrRender.js +97 -0
- package/dist/layout/qrRender.js.map +1 -0
- package/dist/layout/renderDrawing.d.ts +62 -0
- package/dist/layout/renderDrawing.d.ts.map +1 -0
- package/dist/layout/renderDrawing.js +555 -0
- package/dist/layout/renderDrawing.js.map +1 -0
- package/dist/layout/renderUtils.d.ts +36 -0
- package/dist/layout/renderUtils.d.ts.map +1 -0
- package/dist/layout/renderUtils.js +117 -0
- package/dist/layout/renderUtils.js.map +1 -0
- package/dist/layout/sectionValidation.d.ts +3 -0
- package/dist/layout/sectionValidation.d.ts.map +1 -0
- package/dist/layout/sectionValidation.js +2 -0
- package/dist/layout/sectionValidation.js.map +1 -0
- package/dist/layout/templateVariables.d.ts +137 -0
- package/dist/layout/templateVariables.d.ts.map +1 -0
- package/dist/layout/templateVariables.js +295 -0
- package/dist/layout/templateVariables.js.map +1 -0
- package/dist/layout/typeGuards.d.ts +5 -0
- package/dist/layout/typeGuards.d.ts.map +1 -0
- package/dist/layout/typeGuards.js +9 -0
- package/dist/layout/typeGuards.js.map +1 -0
- package/dist/layout/types.d.ts +816 -0
- package/dist/layout/types.d.ts.map +1 -0
- package/dist/layout/types.js +2 -0
- package/dist/layout/types.js.map +1 -0
- package/dist/layout/utils.d.ts +9 -0
- package/dist/layout/utils.d.ts.map +1 -0
- package/dist/layout/utils.js +84 -0
- package/dist/layout/utils.js.map +1 -0
- package/dist/layout/validation.d.ts +7 -0
- package/dist/layout/validation.d.ts.map +1 -0
- package/dist/layout/validation.js +352 -0
- package/dist/layout/validation.js.map +1 -0
- package/dist/layout/validationHelpers.d.ts +15 -0
- package/dist/layout/validationHelpers.d.ts.map +1 -0
- package/dist/layout/validationHelpers.js +43 -0
- package/dist/layout/validationHelpers.js.map +1 -0
- package/dist/layout/validationUtils.d.ts +5 -0
- package/dist/layout/validationUtils.d.ts.map +1 -0
- package/dist/layout/validationUtils.js +5 -0
- package/dist/layout/validationUtils.js.map +1 -0
- package/dist/layout/viewportPrep.d.ts +47 -0
- package/dist/layout/viewportPrep.d.ts.map +1 -0
- package/dist/layout/viewportPrep.js +275 -0
- package/dist/layout/viewportPrep.js.map +1 -0
- package/dist/layout/viewportRender.d.ts +42 -0
- package/dist/layout/viewportRender.d.ts.map +1 -0
- package/dist/layout/viewportRender.js +337 -0
- package/dist/layout/viewportRender.js.map +1 -0
- package/dist/layout/viewportUtils.d.ts +9 -0
- package/dist/layout/viewportUtils.d.ts.map +1 -0
- package/dist/layout/viewportUtils.js +40 -0
- package/dist/layout/viewportUtils.js.map +1 -0
- package/dist/layout/warnings.d.ts +2 -0
- package/dist/layout/warnings.d.ts.map +1 -0
- package/dist/layout/warnings.js +4 -0
- package/dist/layout/warnings.js.map +1 -0
- package/dist/printToPdf.d.ts +38 -0
- package/dist/printToPdf.d.ts.map +1 -0
- package/dist/printToPdf.js +79 -0
- package/dist/printToPdf.js.map +1 -0
- package/dist/printToSvg.d.ts +11 -0
- package/dist/printToSvg.d.ts.map +1 -0
- package/dist/printToSvg.js +168 -0
- package/dist/printToSvg.js.map +1 -0
- package/dist/sections.d.ts +118 -0
- package/dist/sections.d.ts.map +1 -0
- package/dist/sections.js +839 -0
- package/dist/sections.js.map +1 -0
- package/dist/templates/default-template.json +137 -0
- package/dist/types.d.ts +54 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/package.json +47 -0
- package/src/BuildInfo.ts +41 -0
- package/src/index.ts +10 -0
- package/src/layout/analyzeTemplate.ts +218 -0
- package/src/layout/clipUtils.ts +193 -0
- package/src/layout/colorConstants.ts +16 -0
- package/src/layout/elementKinds.ts +35 -0
- package/src/layout/exportDrawing.ts +206 -0
- package/src/layout/filters.ts +80 -0
- package/src/layout/geometryConstants.ts +11 -0
- package/src/layout/index.ts +671 -0
- package/src/layout/itemBuilders.ts +159 -0
- package/src/layout/labelsRender.ts +170 -0
- package/src/layout/legendConstants.ts +11 -0
- package/src/layout/legendRender.ts +543 -0
- package/src/layout/legendRows.ts +62 -0
- package/src/layout/legendUtils.ts +144 -0
- package/src/layout/metadata.ts +210 -0
- package/src/layout/model.ts +372 -0
- package/src/layout/options.ts +17 -0
- package/src/layout/presets.ts +51 -0
- package/src/layout/qrRender.ts +126 -0
- package/src/layout/qrcode.d.ts +2 -0
- package/src/layout/renderDrawing.ts +710 -0
- package/src/layout/renderUtils.ts +138 -0
- package/src/layout/sectionValidation.ts +2 -0
- package/src/layout/templateVariables.ts +317 -0
- package/src/layout/typeGuards.ts +9 -0
- package/src/layout/types.ts +835 -0
- package/src/layout/utils.ts +85 -0
- package/src/layout/validation.ts +392 -0
- package/src/layout/validationHelpers.ts +59 -0
- package/src/layout/validationUtils.ts +6 -0
- package/src/layout/viewportPrep.ts +351 -0
- package/src/layout/viewportRender.ts +442 -0
- package/src/layout/viewportUtils.ts +50 -0
- package/src/layout/warnings.ts +3 -0
- package/src/printToPdf.ts +108 -0
- package/src/printToSvg.ts +188 -0
- package/src/sections.ts +1019 -0
- package/src/templates/default-template.json +137 -0
- package/src/types.ts +49 -0
- package/templates/default-a0-landscape.json +209 -0
- package/templates/default-a0-portrait.json +195 -0
- package/templates/default-a1-landscape.json +167 -0
- package/templates/default-a1-portrait.json +153 -0
- package/templates/default-a3-landscape.json +111 -0
- package/templates/default-a3-portrait.json +125 -0
- package/templates/default-a4-landscape.json +97 -0
- package/templates/default-a4-portrait.json +97 -0
- package/templates/template-schema.json +1395 -0
package/README.md
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# @twinfinity/printing
|
|
2
|
+
|
|
3
|
+
Template-driven page composition, section SVG building, and PDF/SVG export for BIM drawings.
|
|
4
|
+
|
|
5
|
+
This package consolidates layout composition (formerly `@measurement-tools/print-layout`), PDF/SVG export (formerly `@measurement-tools/printing`), and section SVG building (formerly `@measurement-tools/sections`) into a single package.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
### Build a section render state
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { createSectionSvg } from '@twinfinity/printing';
|
|
13
|
+
|
|
14
|
+
// entries = from computePlaneSectionsForProducts() in @twinfinity/geometry
|
|
15
|
+
const sectionState = createSectionSvg(entries);
|
|
16
|
+
|
|
17
|
+
// sectionState.paths — SVG path data with fill/stroke info
|
|
18
|
+
// sectionState.transform — viewport dimensions
|
|
19
|
+
// sectionState.labels — positioned text labels
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Compose a drawing page from a template
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { renderDrawing } from '@twinfinity/printing';
|
|
26
|
+
|
|
27
|
+
const { svg, viewportScales } = await renderDrawing({
|
|
28
|
+
template,
|
|
29
|
+
sectionState,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// svg is a complete page SVG with title block, legend, scale bar, QR codes, etc.
|
|
33
|
+
// viewportScales['main-viewport'].denom tells you the scale (e.g. 100 = 1:100)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Export to PDF
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { exportToPdf } from '@twinfinity/printing';
|
|
40
|
+
|
|
41
|
+
await exportToPdf(svg, {
|
|
42
|
+
fileName: 'drawing.pdf',
|
|
43
|
+
pageFormat: 'a3',
|
|
44
|
+
orientation: 'landscape',
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Quick PDF without a template
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { exportSectionToPdf } from '@twinfinity/printing';
|
|
52
|
+
|
|
53
|
+
await exportSectionToPdf({
|
|
54
|
+
state: sectionState,
|
|
55
|
+
fileName: 'section.pdf',
|
|
56
|
+
pageFormat: 'a3',
|
|
57
|
+
orientation: 'landscape',
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### End-to-end: BIM model to PDF
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { SlabSection } from '@twinfinity/product-geometry';
|
|
65
|
+
import { computePlaneSectionsForProducts } from '@twinfinity/geometry';
|
|
66
|
+
import { createSectionSvg, renderDrawing, exportToPdf } from '@twinfinity/printing';
|
|
67
|
+
import { planeFromPointAndNormal } from '@twinfinity/geometry';
|
|
68
|
+
|
|
69
|
+
// 1. Compute section geometry
|
|
70
|
+
const section = new SlabSection(scene, { cutHeight: 1.5, depth: { above: 2, below: 0.3 } });
|
|
71
|
+
const geometry = await section.compute(products);
|
|
72
|
+
|
|
73
|
+
// 2. Build section state
|
|
74
|
+
const plane = planeFromPointAndNormal([0, 1.5, 0], [0, 1, 0]);
|
|
75
|
+
const entries = await computePlaneSectionsForProducts(products, plane);
|
|
76
|
+
const sectionState = createSectionSvg(entries);
|
|
77
|
+
|
|
78
|
+
// 3. Compose drawing page from template
|
|
79
|
+
const { svg } = await renderDrawing({ template, sectionState });
|
|
80
|
+
|
|
81
|
+
// 4. Export to PDF
|
|
82
|
+
await exportToPdf(svg, { fileName: 'drawing.pdf', pageFormat: 'a3', orientation: 'landscape' });
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Template-based layout composition
|
|
86
|
+
|
|
87
|
+
### Validation and rendering
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import {
|
|
91
|
+
renderLayout,
|
|
92
|
+
validateLayoutTemplate,
|
|
93
|
+
preflight,
|
|
94
|
+
buildViewportItems,
|
|
95
|
+
sectionStateToModelView,
|
|
96
|
+
type LayoutTemplate,
|
|
97
|
+
type ProductFieldPaths,
|
|
98
|
+
} from '@twinfinity/printing';
|
|
99
|
+
|
|
100
|
+
// Validate template
|
|
101
|
+
const vt = validateLayoutTemplate(tmpl);
|
|
102
|
+
if (!vt.ok) throw new Error(vt.errors.map(e => `${e.path}: ${e.message}`).join('; '));
|
|
103
|
+
|
|
104
|
+
// Build viewport items
|
|
105
|
+
const productFields: ProductFieldPaths = {
|
|
106
|
+
idPath: 'propertySets.BIP.hyresobjektsnummer.value',
|
|
107
|
+
namePath: 'propertySets.BIP.spacename.value',
|
|
108
|
+
areaPath: 'propertySets.BIP.area.value',
|
|
109
|
+
classPath: 'propertySets.BIP.ifcClass.value',
|
|
110
|
+
};
|
|
111
|
+
const items = buildViewportItems(rawProducts, { productFields });
|
|
112
|
+
|
|
113
|
+
// Preflight check
|
|
114
|
+
const pf = preflight(tmpl, { viewports: { main: { items } } }, ['main'], sectionState);
|
|
115
|
+
if (!pf.ok) {
|
|
116
|
+
const msgs = [
|
|
117
|
+
...(pf.templateErrors ?? []).map(e => `${e.path}: ${e.message}`),
|
|
118
|
+
...(pf.dataErrors ?? []),
|
|
119
|
+
...(pf.sectionErrors ?? []),
|
|
120
|
+
];
|
|
121
|
+
throw new Error(msgs.join('; '));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Render
|
|
125
|
+
const { svg } = await renderLayout(tmpl, { viewports: { main: { items } } }, models);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Advanced section state
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
import {
|
|
132
|
+
buildSectionStateForEntries,
|
|
133
|
+
extractViewWindow,
|
|
134
|
+
strokeWidthForWindow,
|
|
135
|
+
} from '@twinfinity/printing';
|
|
136
|
+
|
|
137
|
+
const state = buildSectionStateForEntries(entries, {
|
|
138
|
+
viewport: { viewMinX: -10, viewMaxX: 30, viewMinZ: -5, viewMaxZ: 25 },
|
|
139
|
+
strokeWidth: 0.15,
|
|
140
|
+
fills: [
|
|
141
|
+
{ class: 'ifcspace', fillOpacity: 0.35 },
|
|
142
|
+
{ class: ['ifcwall', 'ifcslab'], fillOpacity: 0 },
|
|
143
|
+
],
|
|
144
|
+
includeLabels: true,
|
|
145
|
+
labelFontSize: 2.5,
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Template JSON quick reference
|
|
150
|
+
|
|
151
|
+
Templates are JSON files that define page layout. Use `$schema` for IDE validation:
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"$schema": "./path-to/template-schema.json",
|
|
156
|
+
"id": "my-template",
|
|
157
|
+
"page": { "widthMm": 420, "heightMm": 297, "marginMm": 10 },
|
|
158
|
+
"elements": []
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
- **page**: `{ widthMm, heightMm, marginMm?, backgroundColor? }`
|
|
163
|
+
- **styles**: named text styles `{ fontFamily, fontSizeMm, fontWeight?, letterSpacing?, lineHeight? }`
|
|
164
|
+
- **assets**: `{ id, type: "image", src }` or `{ id, type: "svg", content }`
|
|
165
|
+
- **elements** (z-index sorted):
|
|
166
|
+
- `viewport`: model view with scale, filters, clip, highlight, fills
|
|
167
|
+
- `text`: static or `{{interpolated}}` text
|
|
168
|
+
- `image`: logo or decorative image
|
|
169
|
+
- `line`, `rect`, `circle`: basic shapes
|
|
170
|
+
- `polyline`, `polygon`: custom vectors
|
|
171
|
+
- `scaleBar`: graphical scale indicator
|
|
172
|
+
- `qr`: QR codes for spatial anchoring (main + corner anchors)
|
|
173
|
+
- `labels`: per-item data-driven labels (room names, etc.)
|
|
174
|
+
- `legend`: tabular data with filtering and columns
|
|
175
|
+
- `group`: container with transforms/clipping
|
|
176
|
+
- **presets**: reusable class filters and scale lists
|
|
177
|
+
|
|
178
|
+
### Data contract
|
|
179
|
+
|
|
180
|
+
- Item metadata must use `propertySets.<Set>.<Prop>.value`. Legacy `properties.*` is rejected.
|
|
181
|
+
- Validate before render: use `validateLayoutTemplate` and `validateLayoutData` (or `preflight`).
|
|
182
|
+
|
|
183
|
+
### Default templates
|
|
184
|
+
|
|
185
|
+
Default templates (A0-A4, landscape/portrait) and a JSON schema for IDE validation are in the `templates/` directory.
|
|
186
|
+
|
|
187
|
+
### Limits
|
|
188
|
+
|
|
189
|
+
- Max 3 viewports by default (configurable in validation).
|
|
190
|
+
- Legend: up to 200 rows, 5 data columns + color swatch.
|
|
191
|
+
- Environment: PDF/QR export requires a browser/DOM with `document` and `svg2pdf.js`.
|
|
192
|
+
- `DEFAULT_LAYOUT_TEMPLATE` provides a bundled A3 landscape example.
|
|
193
|
+
|
|
194
|
+
## Troubleshooting
|
|
195
|
+
|
|
196
|
+
| Message | Fix |
|
|
197
|
+
|---------|-----|
|
|
198
|
+
| `propertySets.<Set>.<Prop>.value` required | Update template/data paths to the canonical propertySets shape. |
|
|
199
|
+
| `viewports.<id>.items is required...` | Provide a non-empty `items` array per viewport with `propertySets` on each item. |
|
|
200
|
+
| `clip`/`highlight`/`legend` filter path is invalid | Use paths in the canonical shape; legacy `properties.*` is rejected. |
|
|
201
|
+
| `Section render state is required` / transform errors | Ensure `SectionRenderState` has `geometryTransform`, `transform`, and non-empty `paths`. |
|
|
202
|
+
| `Document is not available` | Run in a browser/DOM environment; headless Node is not supported out of the box. |
|
|
203
|
+
|
|
204
|
+
## Documentation
|
|
205
|
+
|
|
206
|
+
- [Template reference (field-by-field)](../../docs/specs/printing-template-reference.md)
|
|
207
|
+
- [Template guide (practical examples)](../../docs/specs/printing-template-guide.md)
|
|
208
|
+
- [Architecture overview](../../docs/specs/printing-architecture.md)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents either production or development build type
|
|
3
|
+
*/
|
|
4
|
+
export type BuildType = 'Dev' | 'Prod';
|
|
5
|
+
/**
|
|
6
|
+
* Contains property metadata for the Twinfinity build
|
|
7
|
+
*/
|
|
8
|
+
export interface BuildInfo {
|
|
9
|
+
/** Major version number */
|
|
10
|
+
readonly major: number;
|
|
11
|
+
/** Minor version number */
|
|
12
|
+
readonly minor: number;
|
|
13
|
+
/** Patch version number */
|
|
14
|
+
readonly patch: number;
|
|
15
|
+
/** Unique build id */
|
|
16
|
+
readonly id: number;
|
|
17
|
+
/** The commit checksum */
|
|
18
|
+
readonly commit: string;
|
|
19
|
+
/** String that uniquely identifies the current version */
|
|
20
|
+
readonly version: string;
|
|
21
|
+
/** The build type */
|
|
22
|
+
readonly buildType: BuildType;
|
|
23
|
+
}
|
|
24
|
+
export declare const BUILD_INFO: Readonly<BuildInfo>;
|
|
25
|
+
//# sourceMappingURL=BuildInfo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildInfo.d.ts","sourceRoot":"/","sources":["BuildInfo.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,SAAS;IACtB,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sBAAsB;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,qBAAqB;IACrB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;CACjC;AAiBD,eAAO,MAAM,UAAU,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const gBi = {
|
|
2
|
+
major: 5,
|
|
3
|
+
minor: 0,
|
|
4
|
+
patch: 3,
|
|
5
|
+
id: 28538,
|
|
6
|
+
commit: '8df82701',
|
|
7
|
+
version: '',
|
|
8
|
+
buildType: 'Prod'
|
|
9
|
+
};
|
|
10
|
+
gBi.version = `${gBi.major}.${gBi.minor}.${gBi.patch}.${gBi.id}-[${gBi.commit}]`;
|
|
11
|
+
if (gBi.commit === 'unknownCommit') {
|
|
12
|
+
gBi.buildType = 'Dev';
|
|
13
|
+
}
|
|
14
|
+
export const BUILD_INFO = Object.freeze(gBi);
|
|
15
|
+
//# sourceMappingURL=BuildInfo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildInfo.js","sourceRoot":"/","sources":["BuildInfo.ts"],"names":[],"mappings":"AAyBA,MAAM,GAAG,GAAc;IACnB,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,MAAM;IACb,EAAE,EAAE,MAAM;IACV,MAAM,EAAE,eAAe;IACvB,OAAO,EAAE,EAAE;IACX,SAAS,EAAE,MAAM;CACpB,CAAC;AAED,GAAG,CAAC,OAAkB,GAAG,GAAG,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC;AAC7F,IAAI,GAAG,CAAC,MAAM,KAAK,eAAe,EAAE,CAAC;IAChC,GAAG,CAAC,SAAuB,GAAG,KAAK,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC","sourcesContent":["/**\r\n * Represents either production or development build type\r\n */\r\nexport type BuildType = 'Dev' | 'Prod';\r\n\r\n/**\r\n * Contains property metadata for the Twinfinity build\r\n */\r\nexport interface BuildInfo {\r\n /** Major version number */\r\n readonly major: number;\r\n /** Minor version number */\r\n readonly minor: number;\r\n /** Patch version number */\r\n readonly patch: number;\r\n /** Unique build id */\r\n readonly id: number;\r\n /** The commit checksum */\r\n readonly commit: string;\r\n /** String that uniquely identifies the current version */\r\n readonly version: string;\r\n /** The build type */\r\n readonly buildType: BuildType;\r\n}\r\n\r\nconst gBi: BuildInfo = {\r\n major: 111111,\r\n minor: 222222,\r\n patch: 333333,\r\n id: 444444,\r\n commit: 'unknownCommit',\r\n version: '',\r\n buildType: 'Prod'\r\n};\r\n\r\n(gBi.version as string) = `${gBi.major}.${gBi.minor}.${gBi.patch}.${gBi.id}-[${gBi.commit}]`;\r\nif (gBi.commit === 'unknownCommit') {\r\n (gBi.buildType as BuildType) = 'Dev';\r\n}\r\n\r\nexport const BUILD_INFO = Object.freeze(gBi);\r\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './BuildInfo';
|
|
2
|
+
export * from './types';
|
|
3
|
+
export { printToSvg } from './printToSvg';
|
|
4
|
+
export { printToPdf, printToSvgFile, type PrintToPdfOptions } from './printToPdf';
|
|
5
|
+
export * from './layout/index';
|
|
6
|
+
export * from './sections';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGlF,cAAc,gBAAgB,CAAC;AAG/B,cAAc,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './BuildInfo';
|
|
2
|
+
export * from './types';
|
|
3
|
+
export { printToSvg } from './printToSvg';
|
|
4
|
+
export { printToPdf, printToSvgFile } from './printToPdf';
|
|
5
|
+
// Print-layout module (template-driven page composition)
|
|
6
|
+
export * from './layout/index';
|
|
7
|
+
// Sections SVG viewport module
|
|
8
|
+
export * from './sections';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,cAAc,EAA0B,MAAM,cAAc,CAAC;AAElF,yDAAyD;AACzD,cAAc,gBAAgB,CAAC;AAE/B,+BAA+B;AAC/B,cAAc,YAAY,CAAC","sourcesContent":["export * from './BuildInfo';\r\nexport * from './types';\r\nexport { printToSvg } from './printToSvg';\r\nexport { printToPdf, printToSvgFile, type PrintToPdfOptions } from './printToPdf';\r\n\r\n// Print-layout module (template-driven page composition)\r\nexport * from './layout/index';\r\n\r\n// Sections SVG viewport module\r\nexport * from './sections';\r\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { LayoutTemplate } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Describes the input requirements inferred from a layout template.
|
|
4
|
+
* Use `analyzeTemplate()` to scan a template and discover what data it needs.
|
|
5
|
+
*/
|
|
6
|
+
export interface TemplateRequirements {
|
|
7
|
+
/** Viewport IDs the template declares. */
|
|
8
|
+
viewportIds: string[];
|
|
9
|
+
/** Property paths referenced by legends, where-filters, and labels.
|
|
10
|
+
* Short-path format: "SetName.propName" (e.g. "BIP.spacename"). */
|
|
11
|
+
propertyPaths: string[];
|
|
12
|
+
/** Class filters referenced (e.g. "space", "walls"). Already lowercase. */
|
|
13
|
+
classFilters: string[];
|
|
14
|
+
/** Asset IDs referenced by image/northArrow elements. */
|
|
15
|
+
assetIds: string[];
|
|
16
|
+
/** Text interpolation variables (e.g. "viewport.main.scaleText"). */
|
|
17
|
+
interpolationVars: string[];
|
|
18
|
+
/** Whether the template references remote (http/https) asset URLs. */
|
|
19
|
+
usesRemoteAssets: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Scan a layout template and return its input requirements.
|
|
23
|
+
*
|
|
24
|
+
* This is a pure, read-only analysis — it does not modify the template or
|
|
25
|
+
* perform any rendering. Use the result to validate inputs before calling
|
|
26
|
+
* `renderDrawing()` or `renderLayout()`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function analyzeTemplate(template: LayoutTemplate): TemplateRequirements;
|
|
29
|
+
//# sourceMappingURL=analyzeTemplate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzeTemplate.d.ts","sourceRoot":"/","sources":["layout/analyzeTemplate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACR,cAAc,EAWjB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACjC,0CAA0C;IAC1C,WAAW,EAAE,MAAM,EAAE,CAAC;IAEtB;wEACoE;IACpE,aAAa,EAAE,MAAM,EAAE,CAAC;IAExB,2EAA2E;IAC3E,YAAY,EAAE,MAAM,EAAE,CAAC;IAEvB,yDAAyD;IACzD,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB,qEAAqE;IACrE,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAE5B,sEAAsE;IACtE,gBAAgB,EAAE,OAAO,CAAC;CAC7B;AAiCD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,cAAc,GAAG,oBAAoB,CA2I9E"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { normalizeClass } from './filters';
|
|
2
|
+
const INTERPOLATION_RE = /\{\{\s*([^}]+?)\s*\}\}/g;
|
|
3
|
+
/** Extract `{{path}}` tokens from a template string. */
|
|
4
|
+
function extractInterpolationVars(text) {
|
|
5
|
+
const vars = [];
|
|
6
|
+
let m;
|
|
7
|
+
INTERPOLATION_RE.lastIndex = 0;
|
|
8
|
+
while ((m = INTERPOLATION_RE.exec(text)) !== null) {
|
|
9
|
+
vars.push(m[1]);
|
|
10
|
+
}
|
|
11
|
+
return vars;
|
|
12
|
+
}
|
|
13
|
+
/** Collect keys from a WhereCondition (each key is a property short-path). */
|
|
14
|
+
function collectWherePaths(where, out) {
|
|
15
|
+
if (!where || typeof where !== 'object')
|
|
16
|
+
return;
|
|
17
|
+
for (const key of Object.keys(where)) {
|
|
18
|
+
out.add(key);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** Collect class filter values, normalizing to lowercase. */
|
|
22
|
+
function collectClassFilter(classFilter, out) {
|
|
23
|
+
if (!classFilter)
|
|
24
|
+
return;
|
|
25
|
+
const classes = Array.isArray(classFilter) ? classFilter : [classFilter];
|
|
26
|
+
for (const c of classes) {
|
|
27
|
+
const normalized = normalizeClass(c);
|
|
28
|
+
if (normalized)
|
|
29
|
+
out.add(normalized);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Scan a layout template and return its input requirements.
|
|
34
|
+
*
|
|
35
|
+
* This is a pure, read-only analysis — it does not modify the template or
|
|
36
|
+
* perform any rendering. Use the result to validate inputs before calling
|
|
37
|
+
* `renderDrawing()` or `renderLayout()`.
|
|
38
|
+
*/
|
|
39
|
+
export function analyzeTemplate(template) {
|
|
40
|
+
const viewportIds = new Set();
|
|
41
|
+
const propertyPaths = new Set();
|
|
42
|
+
const classFilters = new Set();
|
|
43
|
+
const assetIds = new Set();
|
|
44
|
+
const interpolationVars = new Set();
|
|
45
|
+
let usesRemoteAssets = false;
|
|
46
|
+
// Check assets for remote URLs
|
|
47
|
+
if (template.assets) {
|
|
48
|
+
for (const asset of template.assets) {
|
|
49
|
+
if (asset.src && /^https?:\/\//i.test(asset.src)) {
|
|
50
|
+
usesRemoteAssets = true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Walk all elements (recursing into groups)
|
|
55
|
+
const walk = (elements) => {
|
|
56
|
+
for (const el of elements) {
|
|
57
|
+
switch (el.kind) {
|
|
58
|
+
case 'viewport': {
|
|
59
|
+
const vp = el;
|
|
60
|
+
viewportIds.add(vp.id);
|
|
61
|
+
// Clip filter
|
|
62
|
+
if (vp.clip) {
|
|
63
|
+
collectClassFilter(vp.clip.class, classFilters);
|
|
64
|
+
collectWherePaths(vp.clip.where, propertyPaths);
|
|
65
|
+
}
|
|
66
|
+
// Highlight filter
|
|
67
|
+
if (vp.highlight) {
|
|
68
|
+
collectClassFilter(vp.highlight.class, classFilters);
|
|
69
|
+
collectWherePaths(vp.highlight.where, propertyPaths);
|
|
70
|
+
}
|
|
71
|
+
// includeClasses
|
|
72
|
+
if (vp.includeClasses) {
|
|
73
|
+
if (Array.isArray(vp.includeClasses)) {
|
|
74
|
+
for (const c of vp.includeClasses) {
|
|
75
|
+
const normalized = normalizeClass(c);
|
|
76
|
+
if (normalized)
|
|
77
|
+
classFilters.add(normalized);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Preset references are resolved at render time, nothing to collect
|
|
81
|
+
}
|
|
82
|
+
// North arrow asset
|
|
83
|
+
if (vp.northArrow?.assetId) {
|
|
84
|
+
assetIds.add(vp.northArrow.assetId);
|
|
85
|
+
}
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case 'text': {
|
|
89
|
+
const txt = el;
|
|
90
|
+
if (txt.text) {
|
|
91
|
+
for (const v of extractInterpolationVars(txt.text)) {
|
|
92
|
+
interpolationVars.add(v);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
case 'image': {
|
|
98
|
+
const img = el;
|
|
99
|
+
if (img.assetId)
|
|
100
|
+
assetIds.add(img.assetId);
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
case 'qr': {
|
|
104
|
+
const qr = el;
|
|
105
|
+
if (qr.dataTemplate) {
|
|
106
|
+
for (const v of extractInterpolationVars(qr.dataTemplate)) {
|
|
107
|
+
interpolationVars.add(v);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
case 'labels': {
|
|
113
|
+
const sl = el;
|
|
114
|
+
collectClassFilter(sl.class, classFilters);
|
|
115
|
+
collectWherePaths(sl.where, propertyPaths);
|
|
116
|
+
// Extract property paths from text interpolation (skip viewport.* which are computed)
|
|
117
|
+
if (sl.text) {
|
|
118
|
+
for (const v of extractInterpolationVars(sl.text)) {
|
|
119
|
+
if (!v.startsWith('viewport.')) {
|
|
120
|
+
propertyPaths.add(v);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
interpolationVars.add(v);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
case 'legend': {
|
|
130
|
+
const leg = el;
|
|
131
|
+
collectClassFilter(leg.class, classFilters);
|
|
132
|
+
collectWherePaths(leg.where, propertyPaths);
|
|
133
|
+
// Column property paths
|
|
134
|
+
if (leg.columns) {
|
|
135
|
+
for (const col of leg.columns) {
|
|
136
|
+
if (col.property)
|
|
137
|
+
propertyPaths.add(col.property);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
case 'scaleBar': {
|
|
143
|
+
// scaleBar references a viewport by ID (informational)
|
|
144
|
+
const sb = el;
|
|
145
|
+
if (sb.viewport)
|
|
146
|
+
viewportIds.add(sb.viewport);
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
case 'group': {
|
|
150
|
+
const grp = el;
|
|
151
|
+
if (grp.children)
|
|
152
|
+
walk(grp.children);
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
walk(template.elements);
|
|
159
|
+
return {
|
|
160
|
+
viewportIds: [...viewportIds],
|
|
161
|
+
propertyPaths: [...propertyPaths],
|
|
162
|
+
classFilters: [...classFilters],
|
|
163
|
+
assetIds: [...assetIds],
|
|
164
|
+
interpolationVars: [...interpolationVars],
|
|
165
|
+
usesRemoteAssets
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=analyzeTemplate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzeTemplate.js","sourceRoot":"/","sources":["layout/analyzeTemplate.ts"],"names":[],"mappings":"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","sourcesContent":["import { normalizeClass } from './filters';\r\nimport type {\r\n LayoutTemplate,\r\n LayoutElement,\r\n ViewportElement,\r\n TextElement,\r\n ImageElement,\r\n QrElement,\r\n LabelsElement,\r\n LegendElement,\r\n GroupElement,\r\n ScaleBarElement,\r\n WhereCondition\r\n} from './types';\r\n\r\n/**\r\n * Describes the input requirements inferred from a layout template.\r\n * Use `analyzeTemplate()` to scan a template and discover what data it needs.\r\n */\r\nexport interface TemplateRequirements {\r\n /** Viewport IDs the template declares. */\r\n viewportIds: string[];\r\n\r\n /** Property paths referenced by legends, where-filters, and labels.\r\n * Short-path format: \"SetName.propName\" (e.g. \"BIP.spacename\"). */\r\n propertyPaths: string[];\r\n\r\n /** Class filters referenced (e.g. \"space\", \"walls\"). Already lowercase. */\r\n classFilters: string[];\r\n\r\n /** Asset IDs referenced by image/northArrow elements. */\r\n assetIds: string[];\r\n\r\n /** Text interpolation variables (e.g. \"viewport.main.scaleText\"). */\r\n interpolationVars: string[];\r\n\r\n /** Whether the template references remote (http/https) asset URLs. */\r\n usesRemoteAssets: boolean;\r\n}\r\n\r\nconst INTERPOLATION_RE = /\\{\\{\\s*([^}]+?)\\s*\\}\\}/g;\r\n\r\n/** Extract `{{path}}` tokens from a template string. */\r\nfunction extractInterpolationVars(text: string): string[] {\r\n const vars: string[] = [];\r\n let m: RegExpExecArray | null;\r\n INTERPOLATION_RE.lastIndex = 0;\r\n while ((m = INTERPOLATION_RE.exec(text)) !== null) {\r\n vars.push(m[1]);\r\n }\r\n return vars;\r\n}\r\n\r\n/** Collect keys from a WhereCondition (each key is a property short-path). */\r\nfunction collectWherePaths(where: WhereCondition | undefined, out: Set<string>): void {\r\n if (!where || typeof where !== 'object') return;\r\n for (const key of Object.keys(where)) {\r\n out.add(key);\r\n }\r\n}\r\n\r\n/** Collect class filter values, normalizing to lowercase. */\r\nfunction collectClassFilter(classFilter: string | string[] | undefined, out: Set<string>): void {\r\n if (!classFilter) return;\r\n const classes = Array.isArray(classFilter) ? classFilter : [classFilter];\r\n for (const c of classes) {\r\n const normalized = normalizeClass(c);\r\n if (normalized) out.add(normalized);\r\n }\r\n}\r\n\r\n/**\r\n * Scan a layout template and return its input requirements.\r\n *\r\n * This is a pure, read-only analysis — it does not modify the template or\r\n * perform any rendering. Use the result to validate inputs before calling\r\n * `renderDrawing()` or `renderLayout()`.\r\n */\r\nexport function analyzeTemplate(template: LayoutTemplate): TemplateRequirements {\r\n const viewportIds = new Set<string>();\r\n const propertyPaths = new Set<string>();\r\n const classFilters = new Set<string>();\r\n const assetIds = new Set<string>();\r\n const interpolationVars = new Set<string>();\r\n let usesRemoteAssets = false;\r\n\r\n // Check assets for remote URLs\r\n if (template.assets) {\r\n for (const asset of template.assets) {\r\n if (asset.src && /^https?:\\/\\//i.test(asset.src)) {\r\n usesRemoteAssets = true;\r\n }\r\n }\r\n }\r\n\r\n // Walk all elements (recursing into groups)\r\n const walk = (elements: LayoutElement[]): void => {\r\n for (const el of elements) {\r\n switch (el.kind) {\r\n case 'viewport': {\r\n const vp = el as ViewportElement;\r\n viewportIds.add(vp.id);\r\n\r\n // Clip filter\r\n if (vp.clip) {\r\n collectClassFilter(vp.clip.class, classFilters);\r\n collectWherePaths(vp.clip.where, propertyPaths);\r\n }\r\n\r\n // Highlight filter\r\n if (vp.highlight) {\r\n collectClassFilter(vp.highlight.class, classFilters);\r\n collectWherePaths(vp.highlight.where, propertyPaths);\r\n }\r\n\r\n // includeClasses\r\n if (vp.includeClasses) {\r\n if (Array.isArray(vp.includeClasses)) {\r\n for (const c of vp.includeClasses) {\r\n const normalized = normalizeClass(c);\r\n if (normalized) classFilters.add(normalized);\r\n }\r\n }\r\n // Preset references are resolved at render time, nothing to collect\r\n }\r\n\r\n // North arrow asset\r\n if (vp.northArrow?.assetId) {\r\n assetIds.add(vp.northArrow.assetId);\r\n }\r\n break;\r\n }\r\n\r\n case 'text': {\r\n const txt = el as TextElement;\r\n if (txt.text) {\r\n for (const v of extractInterpolationVars(txt.text)) {\r\n interpolationVars.add(v);\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case 'image': {\r\n const img = el as ImageElement;\r\n if (img.assetId) assetIds.add(img.assetId);\r\n break;\r\n }\r\n\r\n case 'qr': {\r\n const qr = el as QrElement;\r\n if (qr.dataTemplate) {\r\n for (const v of extractInterpolationVars(qr.dataTemplate)) {\r\n interpolationVars.add(v);\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case 'labels': {\r\n const sl = el as LabelsElement;\r\n collectClassFilter(sl.class, classFilters);\r\n collectWherePaths(sl.where, propertyPaths);\r\n\r\n // Extract property paths from text interpolation (skip viewport.* which are computed)\r\n if (sl.text) {\r\n for (const v of extractInterpolationVars(sl.text)) {\r\n if (!v.startsWith('viewport.')) {\r\n propertyPaths.add(v);\r\n } else {\r\n interpolationVars.add(v);\r\n }\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case 'legend': {\r\n const leg = el as LegendElement;\r\n collectClassFilter(leg.class, classFilters);\r\n collectWherePaths(leg.where, propertyPaths);\r\n\r\n // Column property paths\r\n if (leg.columns) {\r\n for (const col of leg.columns) {\r\n if (col.property) propertyPaths.add(col.property);\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case 'scaleBar': {\r\n // scaleBar references a viewport by ID (informational)\r\n const sb = el as ScaleBarElement;\r\n if (sb.viewport) viewportIds.add(sb.viewport);\r\n break;\r\n }\r\n\r\n case 'group': {\r\n const grp = el as GroupElement;\r\n if (grp.children) walk(grp.children);\r\n break;\r\n }\r\n }\r\n }\r\n };\r\n\r\n walk(template.elements);\r\n\r\n return {\r\n viewportIds: [...viewportIds],\r\n propertyPaths: [...propertyPaths],\r\n classFilters: [...classFilters],\r\n assetIds: [...assetIds],\r\n interpolationVars: [...interpolationVars],\r\n usesRemoteAssets\r\n };\r\n}\r\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { SvgModelView } from './types';
|
|
2
|
+
export type Point = {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
};
|
|
6
|
+
export type Polygon = Point[];
|
|
7
|
+
export declare const pointInPolygon: (polygon: Polygon, x: number, y: number) => boolean;
|
|
8
|
+
export declare const filterItemsInPolygons: (items: unknown[], polygons: Polygon[], xField: string | undefined, yField: string | undefined, getPathValue: (obj: unknown, path: string) => unknown) => unknown[];
|
|
9
|
+
export declare const filterEntriesByClip: (entries: unknown[], polygons: Array<Array<{
|
|
10
|
+
x: number;
|
|
11
|
+
z: number;
|
|
12
|
+
}>>) => unknown[];
|
|
13
|
+
export declare const offsetPolygons: (polys: Polygon[], delta: number) => Polygon[];
|
|
14
|
+
export declare const projectPolygonsToLocal: (polygonsSource: unknown, xField: string, yField: string, model: SvgModelView, rotationDeg: number, contentOffsetX: number, contentOffsetY: number, mmPerModel: number) => {
|
|
15
|
+
local: Polygon[];
|
|
16
|
+
page: Polygon[];
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=clipUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clipUtils.d.ts","sourceRoot":"/","sources":["layout/clipUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5C,MAAM,MAAM,KAAK,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAC7C,MAAM,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;AAI9B,eAAO,MAAM,cAAc,GAAI,SAAS,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,KAAG,OAWvE,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAC9B,OAAO,OAAO,EAAE,EAChB,UAAU,OAAO,EAAE,EACnB,0BAAY,EACZ,0BAAY,EACZ,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,KACtD,OAAO,EAUT,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC5B,SAAS,OAAO,EAAE,EAClB,UAAU,KAAK,CAAC,KAAK,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,KACjD,OAAO,EA2CT,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,EAAE,EAAE,OAAO,MAAM,KAAG,OAAO,EAuCvE,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAC/B,gBAAgB,OAAO,EACvB,QAAQ,MAAM,EACd,QAAQ,MAAM,EACd,OAAO,YAAY,EACnB,aAAa,MAAM,EACnB,gBAAgB,MAAM,EACtB,gBAAgB,MAAM,EACtB,YAAY,MAAM,KACnB;IAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAAC,IAAI,EAAE,OAAO,EAAE,CAAA;CAuDrC,CAAC"}
|