@twinfinity/printing 6.0.1-ci.28952-beta → 6.0.2-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.
Files changed (82) hide show
  1. package/README.md +3 -3
  2. package/dist/BuildInfo.js +3 -3
  3. package/dist/BuildInfo.js.map +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/layout/analyzeTemplate.js.map +1 -1
  6. package/dist/layout/clipUtils.js.map +1 -1
  7. package/dist/layout/colorConstants.js.map +1 -1
  8. package/dist/layout/elementKinds.js.map +1 -1
  9. package/dist/layout/exportDrawing.js.map +1 -1
  10. package/dist/layout/filters.js.map +1 -1
  11. package/dist/layout/geometryConstants.js.map +1 -1
  12. package/dist/layout/index.js.map +1 -1
  13. package/dist/layout/itemBuilders.js.map +1 -1
  14. package/dist/layout/labelsRender.js.map +1 -1
  15. package/dist/layout/legendConstants.js.map +1 -1
  16. package/dist/layout/legendRender.js.map +1 -1
  17. package/dist/layout/legendRows.js.map +1 -1
  18. package/dist/layout/legendUtils.js.map +1 -1
  19. package/dist/layout/metadata.js.map +1 -1
  20. package/dist/layout/model.js.map +1 -1
  21. package/dist/layout/options.js.map +1 -1
  22. package/dist/layout/presets.js.map +1 -1
  23. package/dist/layout/qrRender.js.map +1 -1
  24. package/dist/layout/renderDrawing.js.map +1 -1
  25. package/dist/layout/renderUtils.js.map +1 -1
  26. package/dist/layout/sectionValidation.js.map +1 -1
  27. package/dist/layout/templateVariables.js.map +1 -1
  28. package/dist/layout/typeGuards.js.map +1 -1
  29. package/dist/layout/types.js.map +1 -1
  30. package/dist/layout/utils.js.map +1 -1
  31. package/dist/layout/validation.js.map +1 -1
  32. package/dist/layout/validationHelpers.js.map +1 -1
  33. package/dist/layout/validationUtils.js.map +1 -1
  34. package/dist/layout/viewportPrep.js.map +1 -1
  35. package/dist/layout/viewportRender.js.map +1 -1
  36. package/dist/layout/viewportUtils.js.map +1 -1
  37. package/dist/layout/warnings.js.map +1 -1
  38. package/dist/printToPdf.js.map +1 -1
  39. package/dist/printToSvg.js.map +1 -1
  40. package/dist/sections.js.map +1 -1
  41. package/dist/types.js.map +1 -1
  42. package/package.json +2 -2
  43. package/src/BuildInfo.ts +41 -41
  44. package/src/index.ts +10 -10
  45. package/src/layout/analyzeTemplate.ts +218 -218
  46. package/src/layout/clipUtils.ts +193 -193
  47. package/src/layout/colorConstants.ts +16 -16
  48. package/src/layout/elementKinds.ts +35 -35
  49. package/src/layout/exportDrawing.ts +206 -206
  50. package/src/layout/filters.ts +80 -80
  51. package/src/layout/geometryConstants.ts +11 -11
  52. package/src/layout/index.ts +671 -671
  53. package/src/layout/itemBuilders.ts +159 -159
  54. package/src/layout/labelsRender.ts +170 -170
  55. package/src/layout/legendConstants.ts +11 -11
  56. package/src/layout/legendRender.ts +543 -543
  57. package/src/layout/legendRows.ts +62 -62
  58. package/src/layout/legendUtils.ts +144 -144
  59. package/src/layout/metadata.ts +210 -210
  60. package/src/layout/model.ts +372 -372
  61. package/src/layout/options.ts +17 -17
  62. package/src/layout/presets.ts +51 -51
  63. package/src/layout/qrRender.ts +126 -126
  64. package/src/layout/qrcode.d.ts +2 -2
  65. package/src/layout/renderDrawing.ts +710 -710
  66. package/src/layout/renderUtils.ts +138 -138
  67. package/src/layout/sectionValidation.ts +2 -2
  68. package/src/layout/templateVariables.ts +317 -317
  69. package/src/layout/typeGuards.ts +9 -9
  70. package/src/layout/types.ts +835 -835
  71. package/src/layout/utils.ts +85 -85
  72. package/src/layout/validation.ts +392 -392
  73. package/src/layout/validationHelpers.ts +59 -59
  74. package/src/layout/validationUtils.ts +6 -6
  75. package/src/layout/viewportPrep.ts +351 -351
  76. package/src/layout/viewportRender.ts +442 -442
  77. package/src/layout/viewportUtils.ts +50 -50
  78. package/src/layout/warnings.ts +3 -3
  79. package/src/printToPdf.ts +108 -108
  80. package/src/printToSvg.ts +188 -188
  81. package/src/sections.ts +1019 -1019
  82. package/src/types.ts +49 -49
@@ -1,193 +1,193 @@
1
- import type { SvgModelView } from './types';
2
- import { EPSILON_DIVISION_SAFETY, CENTER_FRACTION } from './geometryConstants';
3
-
4
- export type Point = { x: number; y: number };
5
- export type Polygon = Point[];
6
-
7
- import { isRecord, getProp } from './typeGuards';
8
-
9
- export const pointInPolygon = (polygon: Polygon, x: number, y: number): boolean => {
10
- let inside = false;
11
- for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
12
- const xi = polygon[i].x,
13
- yi = polygon[i].y;
14
- const xj = polygon[j].x,
15
- yj = polygon[j].y;
16
- const intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;
17
- if (intersect) inside = !inside;
18
- }
19
- return inside;
20
- };
21
-
22
- export const filterItemsInPolygons = (
23
- items: unknown[],
24
- polygons: Polygon[],
25
- xField = 'x',
26
- yField = 'z',
27
- getPathValue: (obj: unknown, path: string) => unknown
28
- ): unknown[] => {
29
- if (!Array.isArray(items) || !Array.isArray(polygons) || polygons.length === 0) return items ?? [];
30
- return items.filter((item) => {
31
- const xVal = getPathValue(item, xField);
32
- const yVal = getPathValue(item, yField);
33
- if (!Number.isFinite(xVal) || !Number.isFinite(yVal)) return false;
34
- const x = Number(xVal);
35
- const y = Number(yVal);
36
- return polygons.some((poly) => pointInPolygon(poly, x, y));
37
- });
38
- };
39
-
40
- export const filterEntriesByClip = (
41
- entries: unknown[],
42
- polygons: Array<Array<{ x: number; z: number }>>
43
- ): unknown[] => {
44
- if (!Array.isArray(entries) || !Array.isArray(polygons) || polygons.length === 0) return entries ?? [];
45
-
46
- const getCenter = (entry: unknown): { x: number | null; z: number | null } => {
47
- const product = getProp(entry, 'product') ?? entry;
48
- try {
49
- const boundingInfoFn = getProp(product, 'boundingInfo');
50
- const boundingInfo = typeof boundingInfoFn === 'function' ? boundingInfoFn() : null;
51
- const bbox = isRecord(boundingInfo) ? getProp(boundingInfo, 'boundingBox') : null;
52
- const min = isRecord(bbox) ? (getProp(bbox, 'minimumWorld') ?? getProp(bbox, 'minimum')) : null;
53
- const max = isRecord(bbox) ? (getProp(bbox, 'maximumWorld') ?? getProp(bbox, 'maximum')) : null;
54
- const minX = isRecord(min) ? getProp(min, 'x') : null;
55
- const maxX = isRecord(max) ? getProp(max, 'x') : null;
56
- const minZ = isRecord(min) ? getProp(min, 'z') : null;
57
- const maxZ = isRecord(max) ? getProp(max, 'z') : null;
58
- if (Number.isFinite(minX) && Number.isFinite(maxX) && Number.isFinite(minZ) && Number.isFinite(maxZ)) {
59
- return {
60
- x: (Number(minX) + Number(maxX)) * CENTER_FRACTION,
61
- z: (Number(minZ) + Number(maxZ)) * CENTER_FRACTION
62
- };
63
- }
64
- } catch {
65
- // Bounding info access may fail for products without geometry or with malformed data structures.
66
- // This is expected behavior - we fall back to entry.x/z properties below.
67
- }
68
- const x = getProp(entry, 'x');
69
- const z = getProp(entry, 'z');
70
- return { x: typeof x === 'number' ? x : null, z: typeof z === 'number' ? z : null };
71
- };
72
-
73
- return entries.filter((entry) => {
74
- const center = getCenter(entry);
75
- if (!Number.isFinite(center.x) || !Number.isFinite(center.z)) return false;
76
- const x = Number(center.x);
77
- const z = Number(center.z);
78
- return polygons.some((poly) =>
79
- pointInPolygon(
80
- poly.map((p) => ({ x: p.x, y: p.z })),
81
- x,
82
- z
83
- )
84
- );
85
- });
86
- };
87
-
88
- export const offsetPolygons = (polys: Polygon[], delta: number): Polygon[] => {
89
- if (!Array.isArray(polys) || !polys.length || !Number.isFinite(delta) || delta === 0) return polys ?? [];
90
- const intersectLines = (p: Point, r: Point, q: Point, s: Point): Point | null => {
91
- const rxs = r.x * s.y - r.y * s.x;
92
- if (Math.abs(rxs) < EPSILON_DIVISION_SAFETY) return null; // parallel
93
- const t = ((q.x - p.x) * s.y - (q.y - p.y) * s.x) / rxs;
94
- return { x: p.x + t * r.x, y: p.y + t * r.y };
95
- };
96
- const offsetPoly = (poly: Polygon): Polygon => {
97
- const n = poly.length;
98
- if (n < 3) return poly;
99
- const area = poly.reduce((sum, p, i) => {
100
- const q = poly[(i + 1) % n];
101
- return sum + p.x * q.y - q.x * p.y;
102
- }, 0);
103
- const orient = area >= 0 ? 1 : -1; // ccw => outward is right normal
104
- const out: Polygon = [];
105
- for (let i = 0; i < n; i++) {
106
- const p0 = poly[(i + n - 1) % n];
107
- const p1 = poly[i];
108
- const p2 = poly[(i + 1) % n];
109
- const e1x = p1.x - p0.x;
110
- const e1y = p1.y - p0.y;
111
- const e2x = p2.x - p1.x;
112
- const e2y = p2.y - p1.y;
113
- const len1 = Math.hypot(e1x, e1y) || EPSILON_DIVISION_SAFETY;
114
- const len2 = Math.hypot(e2x, e2y) || EPSILON_DIVISION_SAFETY;
115
- const n1x = (orient * e1y) / len1;
116
- const n1y = (orient * -e1x) / len1;
117
- const n2x = (orient * e2y) / len2;
118
- const n2y = (orient * -e2x) / len2;
119
- const line1Point = { x: p1.x + n1x * delta, y: p1.y + n1y * delta };
120
- const line2Point = { x: p1.x + n2x * delta, y: p1.y + n2y * delta };
121
- const inter = intersectLines(line1Point, { x: e1x, y: e1y }, line2Point, { x: e2x, y: e2y });
122
- out.push(inter ?? line2Point);
123
- }
124
- return out;
125
- };
126
- return polys.map(offsetPoly);
127
- };
128
-
129
- export const projectPolygonsToLocal = (
130
- polygonsSource: unknown,
131
- xField: string,
132
- yField: string,
133
- model: SvgModelView,
134
- rotationDeg: number,
135
- contentOffsetX: number,
136
- contentOffsetY: number,
137
- mmPerModel: number
138
- ): { local: Polygon[]; page: Polygon[] } => {
139
- const cosA = Math.cos((rotationDeg * Math.PI) / 180);
140
- const sinA = Math.sin((rotationDeg * Math.PI) / 180);
141
- const toLocal = (px: number, py: number): Point => {
142
- const viewX = px - model.transform!.viewMinX;
143
- const viewY = model.transform!.viewMaxZ - py;
144
- const x0 = viewX - model.widthModel / 2;
145
- const y0 = viewY - model.heightModel / 2;
146
- const x1 = x0 * cosA - y0 * sinA;
147
- const y1 = x0 * sinA + y0 * cosA;
148
- return { x: x1, y: y1 };
149
- };
150
- const toPage = (px: number, py: number): Point => {
151
- const viewX = px - model.transform!.viewMinX;
152
- const viewY = model.transform!.viewMaxZ - py;
153
- const x0 = viewX - model.widthModel / 2;
154
- const y0 = viewY - model.heightModel / 2;
155
- const x1 = x0 * cosA - y0 * sinA;
156
- const y1 = x0 * sinA + y0 * cosA;
157
- return { x: contentOffsetX + x1 * mmPerModel, y: contentOffsetY + y1 * mmPerModel };
158
- };
159
- const projectPolyLocal = (poly: unknown[]): Polygon =>
160
- poly
161
- .map((pt: unknown) => {
162
- const px = Number(getProp(pt, xField));
163
- const py = Number(getProp(pt, yField));
164
- if (!Number.isFinite(px) || !Number.isFinite(py)) return null;
165
- return toLocal(px, py);
166
- })
167
- .filter(Boolean) as Polygon;
168
- const projectPoly = (poly: unknown[]): Polygon =>
169
- poly
170
- .map((pt: unknown) => {
171
- const px = Number(getProp(pt, xField));
172
- const py = Number(getProp(pt, yField));
173
- if (!Number.isFinite(px) || !Number.isFinite(py)) return null;
174
- return toPage(px, py);
175
- })
176
- .filter(Boolean) as Polygon;
177
-
178
- const local: Polygon[] = [];
179
- const page: Polygon[] = [];
180
- if (Array.isArray(polygonsSource)) {
181
- polygonsSource.forEach((poly: unknown) => {
182
- const points = getProp(poly, 'points');
183
- const pl = Array.isArray(points) ? points : Array.isArray(poly) ? poly : null;
184
- if (!pl || pl.length < 3) return;
185
- const projectedLocal = projectPolyLocal(pl);
186
- if (projectedLocal.length >= 3) {
187
- local.push(projectedLocal);
188
- page.push(projectPoly(pl));
189
- }
190
- });
191
- }
192
- return { local, page };
193
- };
1
+ import type { SvgModelView } from './types';
2
+ import { EPSILON_DIVISION_SAFETY, CENTER_FRACTION } from './geometryConstants';
3
+
4
+ export type Point = { x: number; y: number };
5
+ export type Polygon = Point[];
6
+
7
+ import { isRecord, getProp } from './typeGuards';
8
+
9
+ export const pointInPolygon = (polygon: Polygon, x: number, y: number): boolean => {
10
+ let inside = false;
11
+ for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
12
+ const xi = polygon[i].x,
13
+ yi = polygon[i].y;
14
+ const xj = polygon[j].x,
15
+ yj = polygon[j].y;
16
+ const intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;
17
+ if (intersect) inside = !inside;
18
+ }
19
+ return inside;
20
+ };
21
+
22
+ export const filterItemsInPolygons = (
23
+ items: unknown[],
24
+ polygons: Polygon[],
25
+ xField = 'x',
26
+ yField = 'z',
27
+ getPathValue: (obj: unknown, path: string) => unknown
28
+ ): unknown[] => {
29
+ if (!Array.isArray(items) || !Array.isArray(polygons) || polygons.length === 0) return items ?? [];
30
+ return items.filter((item) => {
31
+ const xVal = getPathValue(item, xField);
32
+ const yVal = getPathValue(item, yField);
33
+ if (!Number.isFinite(xVal) || !Number.isFinite(yVal)) return false;
34
+ const x = Number(xVal);
35
+ const y = Number(yVal);
36
+ return polygons.some((poly) => pointInPolygon(poly, x, y));
37
+ });
38
+ };
39
+
40
+ export const filterEntriesByClip = (
41
+ entries: unknown[],
42
+ polygons: Array<Array<{ x: number; z: number }>>
43
+ ): unknown[] => {
44
+ if (!Array.isArray(entries) || !Array.isArray(polygons) || polygons.length === 0) return entries ?? [];
45
+
46
+ const getCenter = (entry: unknown): { x: number | null; z: number | null } => {
47
+ const product = getProp(entry, 'product') ?? entry;
48
+ try {
49
+ const boundingInfoFn = getProp(product, 'boundingInfo');
50
+ const boundingInfo = typeof boundingInfoFn === 'function' ? boundingInfoFn() : null;
51
+ const bbox = isRecord(boundingInfo) ? getProp(boundingInfo, 'boundingBox') : null;
52
+ const min = isRecord(bbox) ? (getProp(bbox, 'minimumWorld') ?? getProp(bbox, 'minimum')) : null;
53
+ const max = isRecord(bbox) ? (getProp(bbox, 'maximumWorld') ?? getProp(bbox, 'maximum')) : null;
54
+ const minX = isRecord(min) ? getProp(min, 'x') : null;
55
+ const maxX = isRecord(max) ? getProp(max, 'x') : null;
56
+ const minZ = isRecord(min) ? getProp(min, 'z') : null;
57
+ const maxZ = isRecord(max) ? getProp(max, 'z') : null;
58
+ if (Number.isFinite(minX) && Number.isFinite(maxX) && Number.isFinite(minZ) && Number.isFinite(maxZ)) {
59
+ return {
60
+ x: (Number(minX) + Number(maxX)) * CENTER_FRACTION,
61
+ z: (Number(minZ) + Number(maxZ)) * CENTER_FRACTION
62
+ };
63
+ }
64
+ } catch {
65
+ // Bounding info access may fail for products without geometry or with malformed data structures.
66
+ // This is expected behavior - we fall back to entry.x/z properties below.
67
+ }
68
+ const x = getProp(entry, 'x');
69
+ const z = getProp(entry, 'z');
70
+ return { x: typeof x === 'number' ? x : null, z: typeof z === 'number' ? z : null };
71
+ };
72
+
73
+ return entries.filter((entry) => {
74
+ const center = getCenter(entry);
75
+ if (!Number.isFinite(center.x) || !Number.isFinite(center.z)) return false;
76
+ const x = Number(center.x);
77
+ const z = Number(center.z);
78
+ return polygons.some((poly) =>
79
+ pointInPolygon(
80
+ poly.map((p) => ({ x: p.x, y: p.z })),
81
+ x,
82
+ z
83
+ )
84
+ );
85
+ });
86
+ };
87
+
88
+ export const offsetPolygons = (polys: Polygon[], delta: number): Polygon[] => {
89
+ if (!Array.isArray(polys) || !polys.length || !Number.isFinite(delta) || delta === 0) return polys ?? [];
90
+ const intersectLines = (p: Point, r: Point, q: Point, s: Point): Point | null => {
91
+ const rxs = r.x * s.y - r.y * s.x;
92
+ if (Math.abs(rxs) < EPSILON_DIVISION_SAFETY) return null; // parallel
93
+ const t = ((q.x - p.x) * s.y - (q.y - p.y) * s.x) / rxs;
94
+ return { x: p.x + t * r.x, y: p.y + t * r.y };
95
+ };
96
+ const offsetPoly = (poly: Polygon): Polygon => {
97
+ const n = poly.length;
98
+ if (n < 3) return poly;
99
+ const area = poly.reduce((sum, p, i) => {
100
+ const q = poly[(i + 1) % n];
101
+ return sum + p.x * q.y - q.x * p.y;
102
+ }, 0);
103
+ const orient = area >= 0 ? 1 : -1; // ccw => outward is right normal
104
+ const out: Polygon = [];
105
+ for (let i = 0; i < n; i++) {
106
+ const p0 = poly[(i + n - 1) % n];
107
+ const p1 = poly[i];
108
+ const p2 = poly[(i + 1) % n];
109
+ const e1x = p1.x - p0.x;
110
+ const e1y = p1.y - p0.y;
111
+ const e2x = p2.x - p1.x;
112
+ const e2y = p2.y - p1.y;
113
+ const len1 = Math.hypot(e1x, e1y) || EPSILON_DIVISION_SAFETY;
114
+ const len2 = Math.hypot(e2x, e2y) || EPSILON_DIVISION_SAFETY;
115
+ const n1x = (orient * e1y) / len1;
116
+ const n1y = (orient * -e1x) / len1;
117
+ const n2x = (orient * e2y) / len2;
118
+ const n2y = (orient * -e2x) / len2;
119
+ const line1Point = { x: p1.x + n1x * delta, y: p1.y + n1y * delta };
120
+ const line2Point = { x: p1.x + n2x * delta, y: p1.y + n2y * delta };
121
+ const inter = intersectLines(line1Point, { x: e1x, y: e1y }, line2Point, { x: e2x, y: e2y });
122
+ out.push(inter ?? line2Point);
123
+ }
124
+ return out;
125
+ };
126
+ return polys.map(offsetPoly);
127
+ };
128
+
129
+ export const projectPolygonsToLocal = (
130
+ polygonsSource: unknown,
131
+ xField: string,
132
+ yField: string,
133
+ model: SvgModelView,
134
+ rotationDeg: number,
135
+ contentOffsetX: number,
136
+ contentOffsetY: number,
137
+ mmPerModel: number
138
+ ): { local: Polygon[]; page: Polygon[] } => {
139
+ const cosA = Math.cos((rotationDeg * Math.PI) / 180);
140
+ const sinA = Math.sin((rotationDeg * Math.PI) / 180);
141
+ const toLocal = (px: number, py: number): Point => {
142
+ const viewX = px - model.transform!.viewMinX;
143
+ const viewY = model.transform!.viewMaxZ - py;
144
+ const x0 = viewX - model.widthModel / 2;
145
+ const y0 = viewY - model.heightModel / 2;
146
+ const x1 = x0 * cosA - y0 * sinA;
147
+ const y1 = x0 * sinA + y0 * cosA;
148
+ return { x: x1, y: y1 };
149
+ };
150
+ const toPage = (px: number, py: number): Point => {
151
+ const viewX = px - model.transform!.viewMinX;
152
+ const viewY = model.transform!.viewMaxZ - py;
153
+ const x0 = viewX - model.widthModel / 2;
154
+ const y0 = viewY - model.heightModel / 2;
155
+ const x1 = x0 * cosA - y0 * sinA;
156
+ const y1 = x0 * sinA + y0 * cosA;
157
+ return { x: contentOffsetX + x1 * mmPerModel, y: contentOffsetY + y1 * mmPerModel };
158
+ };
159
+ const projectPolyLocal = (poly: unknown[]): Polygon =>
160
+ poly
161
+ .map((pt: unknown) => {
162
+ const px = Number(getProp(pt, xField));
163
+ const py = Number(getProp(pt, yField));
164
+ if (!Number.isFinite(px) || !Number.isFinite(py)) return null;
165
+ return toLocal(px, py);
166
+ })
167
+ .filter(Boolean) as Polygon;
168
+ const projectPoly = (poly: unknown[]): Polygon =>
169
+ poly
170
+ .map((pt: unknown) => {
171
+ const px = Number(getProp(pt, xField));
172
+ const py = Number(getProp(pt, yField));
173
+ if (!Number.isFinite(px) || !Number.isFinite(py)) return null;
174
+ return toPage(px, py);
175
+ })
176
+ .filter(Boolean) as Polygon;
177
+
178
+ const local: Polygon[] = [];
179
+ const page: Polygon[] = [];
180
+ if (Array.isArray(polygonsSource)) {
181
+ polygonsSource.forEach((poly: unknown) => {
182
+ const points = getProp(poly, 'points');
183
+ const pl = Array.isArray(points) ? points : Array.isArray(poly) ? poly : null;
184
+ if (!pl || pl.length < 3) return;
185
+ const projectedLocal = projectPolyLocal(pl);
186
+ if (projectedLocal.length >= 3) {
187
+ local.push(projectedLocal);
188
+ page.push(projectPoly(pl));
189
+ }
190
+ });
191
+ }
192
+ return { local, page };
193
+ };
@@ -1,16 +1,16 @@
1
- /**
2
- * Color computation constants
3
- */
4
-
5
- // RGB color value limits
6
- export const RGB_MAX = 255; // Maximum value for RGB color components (0-255)
7
- export const RGB_MIN = 0; // Minimum value for RGB color components
8
-
9
- // Bit shift offsets for color packing/unpacking
10
- export const RED_SHIFT = 16; // Shift for red component in 24-bit color
11
- export const GREEN_SHIFT = 8; // Shift for green component in 24-bit color
12
-
13
- // Color modulo for hash-based color generation
14
- export const HASH_COLOR_MODULO = 255; // Modulo for generating colors from hash values
15
- export const HASH_GREEN_SHIFT = 4; // Bit shift for green in hash-based colors
16
- export const HASH_BLUE_SHIFT = 8; // Bit shift for blue in hash-based colors
1
+ /**
2
+ * Color computation constants
3
+ */
4
+
5
+ // RGB color value limits
6
+ export const RGB_MAX = 255; // Maximum value for RGB color components (0-255)
7
+ export const RGB_MIN = 0; // Minimum value for RGB color components
8
+
9
+ // Bit shift offsets for color packing/unpacking
10
+ export const RED_SHIFT = 16; // Shift for red component in 24-bit color
11
+ export const GREEN_SHIFT = 8; // Shift for green component in 24-bit color
12
+
13
+ // Color modulo for hash-based color generation
14
+ export const HASH_COLOR_MODULO = 255; // Modulo for generating colors from hash values
15
+ export const HASH_GREEN_SHIFT = 4; // Bit shift for green in hash-based colors
16
+ export const HASH_BLUE_SHIFT = 8; // Bit shift for blue in hash-based colors
@@ -1,35 +1,35 @@
1
- /**
2
- * Constants for layout element kinds
3
- */
4
-
5
- export const ELEMENT_KIND_VIEWPORT = 'viewport';
6
- export const ELEMENT_KIND_TEXT = 'text';
7
- export const ELEMENT_KIND_IMAGE = 'image';
8
- export const ELEMENT_KIND_LINE = 'line';
9
- export const ELEMENT_KIND_RECT = 'rect';
10
- export const ELEMENT_KIND_CIRCLE = 'circle';
11
- export const ELEMENT_KIND_POLYLINE = 'polyline';
12
- export const ELEMENT_KIND_POLYGON = 'polygon';
13
- export const ELEMENT_KIND_SCALE_BAR = 'scaleBar';
14
- export const ELEMENT_KIND_QR = 'qr';
15
- export const ELEMENT_KIND_LABELS = 'labels';
16
- export const ELEMENT_KIND_LEGEND = 'legend';
17
- export const ELEMENT_KIND_GROUP = 'group';
18
-
19
- /**
20
- * Union type of all valid element kinds
21
- */
22
- export type ElementKind =
23
- | typeof ELEMENT_KIND_VIEWPORT
24
- | typeof ELEMENT_KIND_TEXT
25
- | typeof ELEMENT_KIND_IMAGE
26
- | typeof ELEMENT_KIND_LINE
27
- | typeof ELEMENT_KIND_RECT
28
- | typeof ELEMENT_KIND_CIRCLE
29
- | typeof ELEMENT_KIND_POLYLINE
30
- | typeof ELEMENT_KIND_POLYGON
31
- | typeof ELEMENT_KIND_SCALE_BAR
32
- | typeof ELEMENT_KIND_QR
33
- | typeof ELEMENT_KIND_LABELS
34
- | typeof ELEMENT_KIND_LEGEND
35
- | typeof ELEMENT_KIND_GROUP;
1
+ /**
2
+ * Constants for layout element kinds
3
+ */
4
+
5
+ export const ELEMENT_KIND_VIEWPORT = 'viewport';
6
+ export const ELEMENT_KIND_TEXT = 'text';
7
+ export const ELEMENT_KIND_IMAGE = 'image';
8
+ export const ELEMENT_KIND_LINE = 'line';
9
+ export const ELEMENT_KIND_RECT = 'rect';
10
+ export const ELEMENT_KIND_CIRCLE = 'circle';
11
+ export const ELEMENT_KIND_POLYLINE = 'polyline';
12
+ export const ELEMENT_KIND_POLYGON = 'polygon';
13
+ export const ELEMENT_KIND_SCALE_BAR = 'scaleBar';
14
+ export const ELEMENT_KIND_QR = 'qr';
15
+ export const ELEMENT_KIND_LABELS = 'labels';
16
+ export const ELEMENT_KIND_LEGEND = 'legend';
17
+ export const ELEMENT_KIND_GROUP = 'group';
18
+
19
+ /**
20
+ * Union type of all valid element kinds
21
+ */
22
+ export type ElementKind =
23
+ | typeof ELEMENT_KIND_VIEWPORT
24
+ | typeof ELEMENT_KIND_TEXT
25
+ | typeof ELEMENT_KIND_IMAGE
26
+ | typeof ELEMENT_KIND_LINE
27
+ | typeof ELEMENT_KIND_RECT
28
+ | typeof ELEMENT_KIND_CIRCLE
29
+ | typeof ELEMENT_KIND_POLYLINE
30
+ | typeof ELEMENT_KIND_POLYGON
31
+ | typeof ELEMENT_KIND_SCALE_BAR
32
+ | typeof ELEMENT_KIND_QR
33
+ | typeof ELEMENT_KIND_LABELS
34
+ | typeof ELEMENT_KIND_LEGEND
35
+ | typeof ELEMENT_KIND_GROUP;