@reekon-tools/boldr-utils 1.6.39 → 1.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.
Files changed (81) hide show
  1. package/dist/annotation/canvas/elements/BackgroundImageElement.js +2 -7
  2. package/dist/annotation/canvas/tools/measurementLineTool.d.ts +12 -0
  3. package/dist/annotation/canvas/tools/measurementLineTool.js +95 -0
  4. package/dist/annotation/canvas/useAnnotationCanvasState.js +31 -17
  5. package/dist/annotation/data/AnnotationDataProvider.d.ts +6 -1
  6. package/dist/annotation/data/AnnotationDataProvider.js +4 -1
  7. package/dist/calculator/evaluate.d.ts +49 -0
  8. package/dist/calculator/evaluate.js +207 -0
  9. package/dist/calculator/index.d.ts +5 -0
  10. package/dist/calculator/index.js +9 -0
  11. package/dist/calculator/schema.d.ts +163 -0
  12. package/dist/calculator/schema.js +129 -0
  13. package/dist/calculator/solve.d.ts +46 -0
  14. package/dist/calculator/solve.js +227 -0
  15. package/dist/calculator/units.d.ts +50 -0
  16. package/dist/calculator/units.js +137 -0
  17. package/dist/calculator/validate.d.ts +192 -0
  18. package/dist/calculator/validate.js +370 -0
  19. package/dist/exports.d.ts +2 -1
  20. package/dist/exports.js +4 -1
  21. package/package.json +3 -2
  22. package/dist/canvas/AnnotationCanvas.d.ts +0 -11
  23. package/dist/canvas/AnnotationCanvas.js +0 -10
  24. package/dist/canvas/AnnotationCanvas.native.d.ts +0 -8
  25. package/dist/canvas/AnnotationCanvas.native.js +0 -6
  26. package/dist/canvas/AnnotationCanvasInner.d.ts +0 -39
  27. package/dist/canvas/AnnotationCanvasInner.js +0 -219
  28. package/dist/canvas/AnnotationCanvasInner.native.d.ts +0 -35
  29. package/dist/canvas/AnnotationCanvasInner.native.js +0 -138
  30. package/dist/canvas/AnnotationCanvasSkia.d.ts +0 -27
  31. package/dist/canvas/AnnotationCanvasSkia.js +0 -20
  32. package/dist/canvas/Tool.d.ts +0 -38
  33. package/dist/canvas/Tool.js +0 -1
  34. package/dist/canvas/elements/BackgroundImageElement.d.ts +0 -9
  35. package/dist/canvas/elements/BackgroundImageElement.js +0 -37
  36. package/dist/canvas/elements/MeasurementStampElement.d.ts +0 -13
  37. package/dist/canvas/elements/MeasurementStampElement.js +0 -30
  38. package/dist/canvas/elements/ShapeElement.d.ts +0 -7
  39. package/dist/canvas/elements/ShapeElement.js +0 -62
  40. package/dist/canvas/elements/StrokeElement.d.ts +0 -7
  41. package/dist/canvas/elements/StrokeElement.js +0 -18
  42. package/dist/canvas/measurementPicker.d.ts +0 -10
  43. package/dist/canvas/measurementPicker.js +0 -1
  44. package/dist/canvas/measurementStampOverlay.d.ts +0 -11
  45. package/dist/canvas/measurementStampOverlay.js +0 -1
  46. package/dist/canvas/pointerAdapter.d.ts +0 -3
  47. package/dist/canvas/pointerAdapter.js +0 -19
  48. package/dist/canvas/stampLayout.d.ts +0 -5
  49. package/dist/canvas/stampLayout.js +0 -14
  50. package/dist/canvas/tools/measurementStampTool.d.ts +0 -9
  51. package/dist/canvas/tools/measurementStampTool.js +0 -37
  52. package/dist/canvas/tools/panTool.d.ts +0 -5
  53. package/dist/canvas/tools/panTool.js +0 -25
  54. package/dist/canvas/tools/penTool.d.ts +0 -13
  55. package/dist/canvas/tools/penTool.js +0 -68
  56. package/dist/canvas/tools/selectTool.d.ts +0 -2
  57. package/dist/canvas/tools/selectTool.js +0 -182
  58. package/dist/canvas/useAnnotationCanvasState.d.ts +0 -54
  59. package/dist/canvas/useAnnotationCanvasState.js +0 -210
  60. package/dist/canvas/viewport.d.ts +0 -16
  61. package/dist/canvas/viewport.js +0 -54
  62. package/dist/data/AnnotationDataContext.d.ts +0 -8
  63. package/dist/data/AnnotationDataContext.js +0 -11
  64. package/dist/data/AnnotationDataProvider.d.ts +0 -65
  65. package/dist/data/AnnotationDataProvider.js +0 -4
  66. package/dist/data/InMemoryAnnotationProvider.d.ts +0 -30
  67. package/dist/data/InMemoryAnnotationProvider.js +0 -197
  68. package/dist/data/canvasPersistence.d.ts +0 -3
  69. package/dist/data/canvasPersistence.js +0 -26
  70. package/dist/data/hooks/useAnnotationCanvasDoc.d.ts +0 -33
  71. package/dist/data/hooks/useAnnotationCanvasDoc.js +0 -314
  72. package/dist/data/hooks/useAnnotationDoc.d.ts +0 -7
  73. package/dist/data/hooks/useAnnotationDoc.js +0 -33
  74. package/dist/data/hooks/useAnnotationList.d.ts +0 -7
  75. package/dist/data/hooks/useAnnotationList.js +0 -26
  76. package/dist/data/hooks/useAnnotationMutations.d.ts +0 -9
  77. package/dist/data/hooks/useAnnotationMutations.js +0 -11
  78. package/dist/hooks/useParseMeasurement.d.ts +0 -4
  79. package/dist/hooks/useParseMeasurement.js +0 -14
  80. package/dist/utils/evaluateFormula.d.ts +0 -20
  81. package/dist/utils/evaluateFormula.js +0 -31
@@ -0,0 +1,137 @@
1
+ import { create, all } from 'mathjs';
2
+ import { DecimalTolerance, FractionalTolerance, Units, convertUnitsToReadableShort, } from '../types/firestore.js';
3
+ import { convertMicrometers } from '../utils/micrometersToUnit.js';
4
+ import { parseMeasurement } from '../utils/parseMeasurement.js';
5
+ const math = create(all);
6
+ const LENGTH_UNIT_INFO = {
7
+ [Units.Millimeters]: { dimension: 'length', mathUnit: 'mm', label: 'mm' },
8
+ [Units.Centimeters]: { dimension: 'length', mathUnit: 'cm', label: 'cm' },
9
+ [Units.Meters]: { dimension: 'length', mathUnit: 'm', label: 'm' },
10
+ [Units.Inches]: { dimension: 'length', mathUnit: 'in', label: 'in' },
11
+ [Units.FractionalInches]: {
12
+ dimension: 'length',
13
+ mathUnit: 'in',
14
+ label: 'in',
15
+ },
16
+ [Units.Feet]: { dimension: 'length', mathUnit: 'ft', label: 'ft' },
17
+ [Units.FeetInchesDecimal]: {
18
+ dimension: 'length',
19
+ mathUnit: 'ft',
20
+ label: 'ft-in',
21
+ },
22
+ [Units.FeetInchesFractional]: {
23
+ dimension: 'length',
24
+ mathUnit: 'ft',
25
+ label: 'ft-in',
26
+ },
27
+ };
28
+ export const CALCULATOR_UNIT_INFO = {
29
+ ...LENGTH_UNIT_INFO,
30
+ sq_mm: { dimension: 'area', mathUnit: 'mm^2', label: 'mm²' },
31
+ sq_cm: { dimension: 'area', mathUnit: 'cm^2', label: 'cm²' },
32
+ sq_m: { dimension: 'area', mathUnit: 'm^2', label: 'm²' },
33
+ sq_in: { dimension: 'area', mathUnit: 'in^2', label: 'in²' },
34
+ sq_ft: { dimension: 'area', mathUnit: 'ft^2', label: 'ft²' },
35
+ sq_yd: { dimension: 'area', mathUnit: 'yd^2', label: 'yd²' },
36
+ cu_mm: { dimension: 'volume', mathUnit: 'mm^3', label: 'mm³' },
37
+ cu_cm: { dimension: 'volume', mathUnit: 'cm^3', label: 'cm³' },
38
+ cu_m: { dimension: 'volume', mathUnit: 'm^3', label: 'm³' },
39
+ cu_in: { dimension: 'volume', mathUnit: 'in^3', label: 'in³' },
40
+ cu_ft: { dimension: 'volume', mathUnit: 'ft^3', label: 'ft³' },
41
+ cu_yd: { dimension: 'volume', mathUnit: 'yd^3', label: 'yd³' },
42
+ liter: { dimension: 'volume', mathUnit: 'L', label: 'L' },
43
+ gallon: { dimension: 'volume', mathUnit: 'gal', label: 'gal' },
44
+ deg: { dimension: 'angle', mathUnit: 'deg', label: '°' },
45
+ rad: { dimension: 'angle', mathUnit: 'rad', label: 'rad' },
46
+ };
47
+ /** The math.js token for a dimension's canonical unit. '' for dimensionless. */
48
+ export const canonicalMathUnit = (dimension) => {
49
+ switch (dimension) {
50
+ case 'length':
51
+ return 'um';
52
+ case 'area':
53
+ return 'um^2';
54
+ case 'volume':
55
+ return 'um^3';
56
+ case 'angle':
57
+ return 'deg';
58
+ case 'none':
59
+ return '';
60
+ }
61
+ };
62
+ export const unitDimension = (unit) => CALCULATOR_UNIT_INFO[unit]?.dimension ?? 'none';
63
+ export const unitsForDimension = (dimension) => Object.keys(CALCULATOR_UNIT_INFO).filter((u) => CALCULATOR_UNIT_INFO[u].dimension === dimension);
64
+ /** Short label for a unit ('ft³', 'in', '°'). */
65
+ export const calculatorUnitLabel = (unit) => {
66
+ const lengthLabel = convertUnitsToReadableShort(unit);
67
+ return CALCULATOR_UNIT_INFO[unit]?.label ?? lengthLabel ?? String(unit);
68
+ };
69
+ // All units here are pure scale factors relative to their canonical unit
70
+ // (no affine offsets like °F), so conversion is a cached multiply.
71
+ const factorCache = new Map();
72
+ const canonicalFactor = (unit) => {
73
+ const cached = factorCache.get(unit);
74
+ if (cached != null)
75
+ return cached;
76
+ const info = CALCULATOR_UNIT_INFO[unit];
77
+ if (!info)
78
+ throw new Error(`Unknown calculator unit: ${unit}`);
79
+ const canonical = canonicalMathUnit(info.dimension);
80
+ const factor = canonical === '' ? 1 : math.unit(1, info.mathUnit).toNumber(canonical);
81
+ factorCache.set(unit, factor);
82
+ return factor;
83
+ };
84
+ /** Convert a display-unit numeric value to the dimension's canonical unit. */
85
+ export const toCanonical = (value, unit) => value * canonicalFactor(unit);
86
+ /** Convert a canonical value to a display-unit numeric value. */
87
+ export const fromCanonical = (value, unit) => value / canonicalFactor(unit);
88
+ const decimalPlaces = (tolerance) =>
89
+ // '0.5' -> 1, '0.01' -> 2, ... (the string-length trick used app-wide).
90
+ tolerance.length - 2;
91
+ // "12 1/2" -> "12 + 1/2" (same normalization parseMeasurement applies).
92
+ const normalizeMixedFraction = (input) => input.trim().replace(/(\d+)\s+(\d+)\/(\d+)/g, '$1 + $2/$3');
93
+ /**
94
+ * Parse user input in a display unit into a canonical value. Accepts plain
95
+ * numbers, fractions and mixed numbers ("12 1/2"). Length units additionally
96
+ * accept a trailing unit token (delegated to parseMeasurement). Returns null
97
+ * on unparseable input.
98
+ */
99
+ export const parseToCanonical = (input, unit) => {
100
+ const info = CALCULATOR_UNIT_INFO[unit];
101
+ if (!info || input.trim() === '')
102
+ return null;
103
+ if (info.dimension === 'length') {
104
+ // parseMeasurement already returns micrometers (canonical).
105
+ return parseMeasurement(input, info.mathUnit);
106
+ }
107
+ try {
108
+ const result = math.evaluate(normalizeMixedFraction(input));
109
+ if (typeof result !== 'number' || !Number.isFinite(result))
110
+ return null;
111
+ return toCanonical(result, unit);
112
+ }
113
+ catch {
114
+ return null;
115
+ }
116
+ };
117
+ /**
118
+ * Format a canonical value for display in the given unit. Lengths delegate to
119
+ * convertMicrometers (the one place that renders fractional-inch / feet-inch
120
+ * strings); other dimensions format decimally per the decimal tolerance.
121
+ */
122
+ export const formatCanonical = (value, unit, tolerances) => {
123
+ const fractional = tolerances?.fractionalTolerance ?? FractionalTolerance.Sixteenth;
124
+ const decimal = tolerances?.decimalTolerance ?? DecimalTolerance.Hundredth;
125
+ const info = CALCULATOR_UNIT_INFO[unit];
126
+ if (value == null || Number.isNaN(value) || !info) {
127
+ return { value: 'NaN', unit: info?.label ?? '' };
128
+ }
129
+ if (info.dimension === 'length') {
130
+ return convertMicrometers(value, unit, fractional, decimal);
131
+ }
132
+ const display = fromCanonical(value, unit);
133
+ return {
134
+ value: display.toFixed(decimalPlaces(decimal)),
135
+ unit: info.label,
136
+ };
137
+ };
@@ -0,0 +1,192 @@
1
+ import { z } from 'zod';
2
+ import { ColumnType, DecimalTolerance, FractionalTolerance } from '../types/firestore.js';
3
+ export declare const calculatorDefinitionSchema: z.ZodObject<{
4
+ id: z.ZodString;
5
+ schemaVersion: z.ZodNumber;
6
+ version: z.ZodNumber;
7
+ name: z.ZodString;
8
+ description: z.ZodString;
9
+ folderId: z.ZodNullable<z.ZodString>;
10
+ fields: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
11
+ kind: z.ZodLiteral<ColumnType.Number>;
12
+ defaultValue: z.ZodOptional<z.ZodNumber>;
13
+ solve: z.ZodOptional<z.ZodObject<{
14
+ solvable: z.ZodBoolean;
15
+ governingEquationId: z.ZodOptional<z.ZodString>;
16
+ min: z.ZodOptional<z.ZodNumber>;
17
+ max: z.ZodOptional<z.ZodNumber>;
18
+ guess: z.ZodOptional<z.ZodNumber>;
19
+ }, z.core.$strip>>;
20
+ id: z.ZodString;
21
+ name: z.ZodString;
22
+ role: z.ZodEnum<{
23
+ input: "input";
24
+ output: "output";
25
+ }>;
26
+ description: z.ZodOptional<z.ZodString>;
27
+ binding: z.ZodOptional<z.ZodObject<{
28
+ hotspotId: z.ZodString;
29
+ }, z.core.$strip>>;
30
+ }, z.core.$strip>, z.ZodObject<{
31
+ kind: z.ZodLiteral<ColumnType.Measurement>;
32
+ unit: z.ZodObject<{
33
+ dimension: z.ZodEnum<{
34
+ length: "length";
35
+ area: "area";
36
+ volume: "volume";
37
+ }>;
38
+ defaultUnit: z.ZodString;
39
+ allowedUnits: z.ZodArray<z.ZodString>;
40
+ fractionalTolerance: z.ZodOptional<z.ZodEnum<typeof FractionalTolerance>>;
41
+ decimalTolerance: z.ZodOptional<z.ZodEnum<typeof DecimalTolerance>>;
42
+ }, z.core.$strip>;
43
+ defaultValue: z.ZodOptional<z.ZodNumber>;
44
+ solve: z.ZodOptional<z.ZodObject<{
45
+ solvable: z.ZodBoolean;
46
+ governingEquationId: z.ZodOptional<z.ZodString>;
47
+ min: z.ZodOptional<z.ZodNumber>;
48
+ max: z.ZodOptional<z.ZodNumber>;
49
+ guess: z.ZodOptional<z.ZodNumber>;
50
+ }, z.core.$strip>>;
51
+ id: z.ZodString;
52
+ name: z.ZodString;
53
+ role: z.ZodEnum<{
54
+ input: "input";
55
+ output: "output";
56
+ }>;
57
+ description: z.ZodOptional<z.ZodString>;
58
+ binding: z.ZodOptional<z.ZodObject<{
59
+ hotspotId: z.ZodString;
60
+ }, z.core.$strip>>;
61
+ }, z.core.$strip>, z.ZodObject<{
62
+ kind: z.ZodLiteral<ColumnType.Angle>;
63
+ angleUnit: z.ZodOptional<z.ZodEnum<{
64
+ deg: "deg";
65
+ rad: "rad";
66
+ }>>;
67
+ defaultValue: z.ZodOptional<z.ZodNumber>;
68
+ solve: z.ZodOptional<z.ZodObject<{
69
+ solvable: z.ZodBoolean;
70
+ governingEquationId: z.ZodOptional<z.ZodString>;
71
+ min: z.ZodOptional<z.ZodNumber>;
72
+ max: z.ZodOptional<z.ZodNumber>;
73
+ guess: z.ZodOptional<z.ZodNumber>;
74
+ }, z.core.$strip>>;
75
+ id: z.ZodString;
76
+ name: z.ZodString;
77
+ role: z.ZodEnum<{
78
+ input: "input";
79
+ output: "output";
80
+ }>;
81
+ description: z.ZodOptional<z.ZodString>;
82
+ binding: z.ZodOptional<z.ZodObject<{
83
+ hotspotId: z.ZodString;
84
+ }, z.core.$strip>>;
85
+ }, z.core.$strip>, z.ZodObject<{
86
+ kind: z.ZodLiteral<ColumnType.SingleSelect>;
87
+ columnData: z.ZodObject<{
88
+ options: z.ZodArray<z.ZodString>;
89
+ }, z.core.$strip>;
90
+ defaultValue: z.ZodOptional<z.ZodString>;
91
+ id: z.ZodString;
92
+ name: z.ZodString;
93
+ role: z.ZodEnum<{
94
+ input: "input";
95
+ output: "output";
96
+ }>;
97
+ description: z.ZodOptional<z.ZodString>;
98
+ binding: z.ZodOptional<z.ZodObject<{
99
+ hotspotId: z.ZodString;
100
+ }, z.core.$strip>>;
101
+ }, z.core.$strip>, z.ZodObject<{
102
+ kind: z.ZodLiteral<ColumnType.MultiSelect>;
103
+ columnData: z.ZodObject<{
104
+ options: z.ZodArray<z.ZodString>;
105
+ }, z.core.$strip>;
106
+ defaultValue: z.ZodOptional<z.ZodArray<z.ZodString>>;
107
+ id: z.ZodString;
108
+ name: z.ZodString;
109
+ role: z.ZodEnum<{
110
+ input: "input";
111
+ output: "output";
112
+ }>;
113
+ description: z.ZodOptional<z.ZodString>;
114
+ binding: z.ZodOptional<z.ZodObject<{
115
+ hotspotId: z.ZodString;
116
+ }, z.core.$strip>>;
117
+ }, z.core.$strip>, z.ZodObject<{
118
+ kind: z.ZodLiteral<ColumnType.ConversionTable>;
119
+ columnData: z.ZodObject<{
120
+ conversions: z.ZodArray<z.ZodObject<{
121
+ label: z.ZodString;
122
+ value: z.ZodString;
123
+ }, z.core.$strip>>;
124
+ }, z.core.$strip>;
125
+ defaultValue: z.ZodOptional<z.ZodString>;
126
+ id: z.ZodString;
127
+ name: z.ZodString;
128
+ role: z.ZodEnum<{
129
+ input: "input";
130
+ output: "output";
131
+ }>;
132
+ description: z.ZodOptional<z.ZodString>;
133
+ binding: z.ZodOptional<z.ZodObject<{
134
+ hotspotId: z.ZodString;
135
+ }, z.core.$strip>>;
136
+ }, z.core.$strip>, z.ZodObject<{
137
+ kind: z.ZodLiteral<ColumnType.Instructions>;
138
+ columnData: z.ZodObject<{
139
+ text: z.ZodString;
140
+ textColor: z.ZodString;
141
+ backgroundColor: z.ZodString;
142
+ }, z.core.$strip>;
143
+ id: z.ZodString;
144
+ name: z.ZodString;
145
+ role: z.ZodEnum<{
146
+ input: "input";
147
+ output: "output";
148
+ }>;
149
+ description: z.ZodOptional<z.ZodString>;
150
+ binding: z.ZodOptional<z.ZodObject<{
151
+ hotspotId: z.ZodString;
152
+ }, z.core.$strip>>;
153
+ }, z.core.$strip>], "kind">>;
154
+ equations: z.ZodArray<z.ZodObject<{
155
+ id: z.ZodString;
156
+ targetFieldId: z.ZodString;
157
+ expression: z.ZodString;
158
+ variableToFieldId: z.ZodRecord<z.ZodString, z.ZodString>;
159
+ }, z.core.$strip>>;
160
+ diagramFileId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
161
+ isPublic: z.ZodBoolean;
162
+ sharedUserIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
163
+ sharedOrgIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
164
+ createdBy: z.ZodOptional<z.ZodObject<{
165
+ userId: z.ZodString;
166
+ firstName: z.ZodOptional<z.ZodString>;
167
+ lastName: z.ZodOptional<z.ZodString>;
168
+ }, z.core.$strip>>;
169
+ createdAt: z.ZodOptional<z.ZodUnknown>;
170
+ updatedAt: z.ZodOptional<z.ZodUnknown>;
171
+ }, z.core.$strip>;
172
+ export type IssueSeverity = 'error' | 'warning';
173
+ export interface ValidationIssue {
174
+ code: string;
175
+ path: string;
176
+ message: string;
177
+ severity: IssueSeverity;
178
+ }
179
+ export interface ValidationResult {
180
+ /** True when there are no error-severity issues (warnings allowed). */
181
+ ok: boolean;
182
+ issues: ValidationIssue[];
183
+ }
184
+ /** Free variables of an expression (function names and constants excluded). */
185
+ export declare const expressionSymbols: (expression: string) => {
186
+ ok: true;
187
+ symbols: string[];
188
+ } | {
189
+ ok: false;
190
+ error: string;
191
+ };
192
+ export declare const validateCalculatorDefinition: (input: unknown) => ValidationResult;