@reekon-tools/boldr-utils 1.0.4 → 1.0.6
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/dist/formulas/createFormulaScope.d.ts +7 -0
- package/dist/formulas/createFormulaScope.js +27 -0
- package/dist/formulas/createFormulaScope.js.map +1 -0
- package/dist/formulas/evaluateColumnValue.d.ts +9 -0
- package/dist/formulas/evaluateColumnValue.js +48 -0
- package/dist/formulas/evaluateColumnValue.js.map +1 -0
- package/dist/formulas/mathUnitMap.d.ts +2 -0
- package/dist/formulas/mathUnitMap.js +26 -0
- package/dist/formulas/mathUnitMap.js.map +1 -0
- package/dist/index.d.ts +84 -49
- package/dist/index.js +13 -5
- package/dist/index.js.map +1 -1
- package/dist/utils/evaluateFormula.d.ts +20 -0
- package/dist/utils/evaluateFormula.js +32 -0
- package/dist/utils/evaluateFormula.js.map +1 -0
- package/dist/utils/parseMeasurement.d.ts +1 -0
- package/dist/utils/parseMeasurement.js +9 -0
- package/dist/utils/parseMeasurement.js.map +1 -1
- package/package.json +8 -2
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { FractionalTolerance, DecimalTolerance } from '..';
|
|
2
|
+
import { ColumnType } from '..';
|
|
3
|
+
import { convertMicrometers } from '../utils/micrometersToUnit';
|
|
4
|
+
export function createFormulaScope({ group, mappings, columns, measurementMap, unit, // user preferred unit, e.g., 'in' or 'cm'
|
|
5
|
+
}) {
|
|
6
|
+
const scope = {};
|
|
7
|
+
for (const [variable, columnId] of Object.entries(mappings)) {
|
|
8
|
+
const rawValue = group.columns.get(columnId);
|
|
9
|
+
const columnDef = columns.find((c) => c.id === columnId);
|
|
10
|
+
let parsedValue;
|
|
11
|
+
if ((columnDef === null || columnDef === void 0 ? void 0 : columnDef.type) === ColumnType.Measurement) {
|
|
12
|
+
const groupMeasurements = measurementMap.get(group.id) || [];
|
|
13
|
+
const measurement = groupMeasurements.find((m) => m.id === rawValue);
|
|
14
|
+
if ((measurement === null || measurement === void 0 ? void 0 : measurement.value) !== undefined) {
|
|
15
|
+
// Here, the unit
|
|
16
|
+
parsedValue = parseFloat(convertMicrometers(measurement.value, unit, FractionalTolerance.Sixteenth, DecimalTolerance.Hundredth).value);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
parsedValue =
|
|
21
|
+
typeof rawValue === 'number' ? rawValue : parseFloat(rawValue || '');
|
|
22
|
+
}
|
|
23
|
+
scope[variable] = isNaN(parsedValue) ? 0 : parsedValue;
|
|
24
|
+
}
|
|
25
|
+
return scope;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=createFormulaScope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createFormulaScope.js","sourceRoot":"","sources":["../../src/formulas/createFormulaScope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAS,MAAM,IAAI,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,MAAM,UAAU,kBAAkB,CAAC,EACjC,KAAK,EACL,QAAQ,EACR,OAAO,EACP,cAAc,EACd,IAAI,EAAE,0CAA0C;EAOjD;IACC,MAAM,KAAK,GAA2B,EAAE,CAAC;IAEzC,KAAK,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5D,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;QAEzD,IAAI,WAA+B,CAAC;QAEpC,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,MAAK,UAAU,CAAC,WAAW,EAAE,CAAC;YAC/C,MAAM,iBAAiB,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;YAC7D,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;YACrE,IAAI,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK,MAAK,SAAS,EAAE,CAAC;gBACrC,kBAAkB;gBAClB,WAAW,GAAG,UAAU,CAAC,kBAAkB,CACvC,WAAW,CAAC,KAAK,EACjB,IAAa,EACb,mBAAmB,CAAC,SAAS,EAC7B,gBAAgB,CAAC,SAAS,CAC3B,CAAC,KAAK,CAAC,CAAC;YACb,CAAC;QACH,CAAC;aAAM,CAAC;YACN,WAAW;gBACT,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;QAED,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,WAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAY,CAAC;IAC3D,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ColumnConfig, Group, Units } from '..';
|
|
2
|
+
export declare function evaluateColumnValue({ group, col, formulas, columns, measurementMap, userUnit, }: {
|
|
3
|
+
group: Group;
|
|
4
|
+
col: ColumnConfig;
|
|
5
|
+
formulas: any[];
|
|
6
|
+
columns: any[];
|
|
7
|
+
measurementMap: Map<string, any[]>;
|
|
8
|
+
userUnit: Units;
|
|
9
|
+
}): any;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ColumnType } from '..';
|
|
2
|
+
import { createFormulaScope } from './createFormulaScope';
|
|
3
|
+
import { compile, unit as mathUnit } from 'mathjs';
|
|
4
|
+
import { normalizeUnitForMathJS } from './mathUnitMap';
|
|
5
|
+
export function evaluateColumnValue({ group, col, formulas, columns, measurementMap, userUnit, }) {
|
|
6
|
+
var _a;
|
|
7
|
+
// Normalize immediately
|
|
8
|
+
const normalizedUnit = normalizeUnitForMathJS(userUnit);
|
|
9
|
+
if (col.type === ColumnType.Measurement) {
|
|
10
|
+
const value = group.columns.get(col.id);
|
|
11
|
+
const groupMeasurements = measurementMap.get(group.id) || [];
|
|
12
|
+
const measurement = groupMeasurements.find((m) => m.id === value);
|
|
13
|
+
return measurement !== null && measurement !== void 0 ? measurement : value;
|
|
14
|
+
}
|
|
15
|
+
if (col.type === ColumnType.Formula) {
|
|
16
|
+
const formula = formulas.find((f) => f.id === col.formulaId);
|
|
17
|
+
if (!formula) {
|
|
18
|
+
console.warn(`Missing formula with id ${col.formulaId}`);
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
if (col.mappings === undefined) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const scope = createFormulaScope({
|
|
26
|
+
group,
|
|
27
|
+
mappings: col.mappings,
|
|
28
|
+
columns,
|
|
29
|
+
measurementMap,
|
|
30
|
+
unit: normalizedUnit, // ✅ normalized!
|
|
31
|
+
});
|
|
32
|
+
console.log('Evaluating:', formula.expression, scope);
|
|
33
|
+
const compiled = compile(formula.expression);
|
|
34
|
+
const result = compiled.evaluate(scope);
|
|
35
|
+
const asUnit = mathUnit(result, normalizedUnit);
|
|
36
|
+
if (!asUnit.equalBase(mathUnit('1 um'))) {
|
|
37
|
+
throw new Error(`Incompatible unit: ${asUnit.formatUnits()} is not compatible with ${normalizedUnit}`);
|
|
38
|
+
}
|
|
39
|
+
return Math.round(asUnit.toNumber('um'));
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.error(`Failed to evaluate formula: ${col.name}`, error);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return (_a = group.columns.get(col.id)) !== null && _a !== void 0 ? _a : '';
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=evaluateColumnValue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluateColumnValue.js","sourceRoot":"","sources":["../../src/formulas/evaluateColumnValue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,UAAU,EAAgB,MAAM,IAAI,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAEvD,MAAM,UAAU,mBAAmB,CAAC,EAClC,KAAK,EACL,GAAG,EACH,QAAQ,EACR,OAAO,EACP,cAAc,EACd,QAAQ,GAQT;;IACC,wBAAwB;IACxB,MAAM,cAAc,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAExD,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,WAAW,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,iBAAiB,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;QAC7D,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;QAClE,OAAO,WAAW,aAAX,WAAW,cAAX,WAAW,GAAI,KAAK,CAAC;IAC9B,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,2BAA2B,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;YACzD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,kBAAkB,CAAC;gBAC/B,KAAK;gBACL,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,OAAO;gBACP,cAAc;gBACd,IAAI,EAAE,cAAc,EAAE,gBAAgB;aACvC,CAAC,CAAC;YAEH,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAEtD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAExC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YAEhD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;gBACxC,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,CAAC,WAAW,EAAE,2BAA2B,cAAc,EAAE,CAAC,CAAC;YACzG,CAAC;YAED,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;YAChE,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,MAAA,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,mCAAI,EAAE,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Units } from "..";
|
|
2
|
+
// Must convert our custom unit types
|
|
3
|
+
export function normalizeUnitForMathJS(unit) {
|
|
4
|
+
switch (unit) {
|
|
5
|
+
case Units.Centimeters:
|
|
6
|
+
case 'cm':
|
|
7
|
+
return 'cm';
|
|
8
|
+
case Units.Millimeters:
|
|
9
|
+
case 'mm':
|
|
10
|
+
return 'mm';
|
|
11
|
+
case Units.Meters:
|
|
12
|
+
case 'm':
|
|
13
|
+
return 'm';
|
|
14
|
+
case Units.Inches:
|
|
15
|
+
case Units.FractionalInches:
|
|
16
|
+
return 'in';
|
|
17
|
+
case Units.Feet:
|
|
18
|
+
case Units.FeetInchesDecimal:
|
|
19
|
+
case Units.FeetInchesFractional:
|
|
20
|
+
return 'ft';
|
|
21
|
+
default:
|
|
22
|
+
console.warn(`Unknown or unsupported unit: ${unit}, falling back to 'mm'`);
|
|
23
|
+
return 'mm'; // fallback
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=mathUnitMap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mathUnitMap.js","sourceRoot":"","sources":["../../src/formulas/mathUnitMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC;AAE3B,sCAAsC;AACtC,MAAM,UAAU,sBAAsB,CAAC,IAAoB;IACzD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK,CAAC,WAAW,CAAC;QACvB,KAAK,IAAI;YACP,OAAO,IAAI,CAAC;QACd,KAAK,KAAK,CAAC,WAAW,CAAC;QACvB,KAAK,IAAI;YACP,OAAO,IAAI,CAAC;QACd,KAAK,KAAK,CAAC,MAAM,CAAC;QAClB,KAAK,GAAG;YACN,OAAO,GAAG,CAAC;QACb,KAAK,KAAK,CAAC,MAAM,CAAC;QAClB,KAAK,KAAK,CAAC,gBAAgB;YACzB,OAAO,IAAI,CAAC;QACd,KAAK,KAAK,CAAC,IAAI,CAAC;QAChB,KAAK,KAAK,CAAC,iBAAiB,CAAC;QAC7B,KAAK,KAAK,CAAC,oBAAoB;YAC7B,OAAO,IAAI,CAAC;QACd;YACE,OAAO,CAAC,IAAI,CAAC,gCAAgC,IAAI,wBAAwB,CAAC,CAAC;YAC3E,OAAO,IAAI,CAAC,CAAC,WAAW;IAC5B,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,29 +1,49 @@
|
|
|
1
|
-
|
|
1
|
+
interface FirestoreDoc {
|
|
2
2
|
id: string;
|
|
3
|
-
|
|
3
|
+
}
|
|
4
|
+
interface Timestamps {
|
|
4
5
|
createdAt: Date;
|
|
5
|
-
}
|
|
6
|
+
}
|
|
7
|
+
interface CreatedBy {
|
|
8
|
+
firstName: string;
|
|
9
|
+
lastName: string;
|
|
10
|
+
userId: string;
|
|
11
|
+
}
|
|
12
|
+
export interface Organization extends FirestoreDoc, Timestamps {
|
|
13
|
+
name: string;
|
|
14
|
+
createdBy: string;
|
|
15
|
+
}
|
|
6
16
|
export declare enum OrganizationRole {
|
|
7
|
-
|
|
8
|
-
|
|
17
|
+
Admin = "admin",
|
|
18
|
+
Member = "member"
|
|
9
19
|
}
|
|
10
20
|
export declare enum InvitationStatus {
|
|
11
21
|
Pending = "pending",
|
|
12
22
|
Accepted = "accepted"
|
|
13
23
|
}
|
|
14
|
-
export
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
export interface Invitation extends FirestoreDoc, Timestamps {
|
|
25
|
+
delivery?: unknown;
|
|
26
|
+
invitationCode: string;
|
|
27
|
+
inviteeEmail: string;
|
|
28
|
+
inviteeUid: string;
|
|
29
|
+
inviterId: string;
|
|
30
|
+
message: {
|
|
31
|
+
subject: string;
|
|
32
|
+
text: string;
|
|
33
|
+
};
|
|
18
34
|
organizationId: string;
|
|
19
|
-
senderId: string;
|
|
20
35
|
role: OrganizationRole;
|
|
21
|
-
message: string;
|
|
22
36
|
status: InvitationStatus;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
37
|
+
}
|
|
38
|
+
export interface OrganizationMember extends FirestoreDoc {
|
|
39
|
+
email: string;
|
|
40
|
+
firstName: string;
|
|
41
|
+
lastName: string;
|
|
42
|
+
joinedAt: Date;
|
|
43
|
+
role: OrganizationRole;
|
|
44
|
+
userId: string;
|
|
45
|
+
}
|
|
46
|
+
export interface Project extends FirestoreDoc, Timestamps {
|
|
27
47
|
name: string;
|
|
28
48
|
description: string;
|
|
29
49
|
imageUrl: string | null;
|
|
@@ -31,17 +51,24 @@ export interface Project {
|
|
|
31
51
|
city: string;
|
|
32
52
|
zipCode: string;
|
|
33
53
|
state: string;
|
|
34
|
-
createdAt: any;
|
|
35
54
|
}
|
|
36
|
-
export
|
|
37
|
-
|
|
55
|
+
export declare enum FolderType {
|
|
56
|
+
Project = "project",
|
|
57
|
+
Job = "job"
|
|
58
|
+
}
|
|
59
|
+
export interface Folder extends FirestoreDoc {
|
|
38
60
|
name: string;
|
|
39
|
-
|
|
61
|
+
index: number;
|
|
62
|
+
parentFolderId?: string | null;
|
|
63
|
+
projectId: string | null;
|
|
64
|
+
type: FolderType;
|
|
40
65
|
}
|
|
41
|
-
export interface Job {
|
|
42
|
-
id: string;
|
|
66
|
+
export interface Job extends FirestoreDoc, Timestamps {
|
|
43
67
|
name: string;
|
|
44
|
-
|
|
68
|
+
folderId: string;
|
|
69
|
+
progress: number;
|
|
70
|
+
projectId: string;
|
|
71
|
+
totalTasks: string;
|
|
45
72
|
}
|
|
46
73
|
export interface Section {
|
|
47
74
|
id: string;
|
|
@@ -51,28 +78,46 @@ export interface Section {
|
|
|
51
78
|
projectId: string;
|
|
52
79
|
jobId: string;
|
|
53
80
|
}
|
|
54
|
-
export interface Group {
|
|
55
|
-
|
|
81
|
+
export interface Group extends FirestoreDoc, Timestamps {
|
|
82
|
+
projectId: string;
|
|
83
|
+
jobId: string;
|
|
56
84
|
sectionId: string;
|
|
85
|
+
name: string;
|
|
86
|
+
sortIndex: number;
|
|
57
87
|
columns: Record<string, any>;
|
|
58
|
-
|
|
59
|
-
|
|
88
|
+
}
|
|
89
|
+
export declare enum ColumnType {
|
|
90
|
+
Text = "text",
|
|
91
|
+
Number = "number",
|
|
92
|
+
Measurement = "measurement",
|
|
93
|
+
Boolean = "boolean",
|
|
94
|
+
Formula = "formula"
|
|
95
|
+
}
|
|
96
|
+
export interface Formula extends FirestoreDoc, Timestamps {
|
|
97
|
+
expression: string;
|
|
98
|
+
name: string;
|
|
99
|
+
varaibles: string[];
|
|
60
100
|
}
|
|
61
101
|
export interface ColumnConfig {
|
|
62
102
|
id: string;
|
|
63
103
|
name: string;
|
|
64
104
|
type: ColumnType;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
Text = "text",// Text input
|
|
68
|
-
Number = "number",// Numeric input
|
|
69
|
-
Measurement = "measurement",// Measurement input
|
|
70
|
-
Boolean = "boolean"
|
|
105
|
+
formulaId?: string;
|
|
106
|
+
mappings?: Record<string, string>;
|
|
71
107
|
}
|
|
72
108
|
export interface Row {
|
|
73
109
|
[key: string]: any;
|
|
74
110
|
}
|
|
75
|
-
export
|
|
111
|
+
export interface Measurement extends FirestoreDoc, Timestamps, CreatedBy {
|
|
112
|
+
projectId: string;
|
|
113
|
+
jobId: string;
|
|
114
|
+
groupId: string;
|
|
115
|
+
sectionId: string;
|
|
116
|
+
value: number;
|
|
117
|
+
index: number;
|
|
118
|
+
label: string;
|
|
119
|
+
measurementIndex: number;
|
|
120
|
+
unit: Units;
|
|
76
121
|
}
|
|
77
122
|
export declare enum Units {
|
|
78
123
|
Centimeters = "cm",
|
|
@@ -84,18 +129,7 @@ export declare enum Units {
|
|
|
84
129
|
FeetInchesDecimal = "ft_in_decimal",
|
|
85
130
|
FeetInchesFractional = "ft_in_frac"
|
|
86
131
|
}
|
|
87
|
-
export declare const convertUnitsToReadable: (targetUnit: Units) => "
|
|
88
|
-
export interface Measurement {
|
|
89
|
-
type: MeasurementType;
|
|
90
|
-
id: string;
|
|
91
|
-
value: number;
|
|
92
|
-
index: number;
|
|
93
|
-
label: string;
|
|
94
|
-
groupId: string;
|
|
95
|
-
projectId: string;
|
|
96
|
-
jobId: string;
|
|
97
|
-
sectionId: string;
|
|
98
|
-
}
|
|
132
|
+
export declare const convertUnitsToReadable: (targetUnit: Units) => "in" | "ft" | "m" | "mm" | "cm" | "in (fractional)" | "ft-in (decimal)" | "ft-in (fractional)" | null;
|
|
99
133
|
export declare enum FractionalTolerance {
|
|
100
134
|
Fourth = "4",
|
|
101
135
|
Eighth = "8",
|
|
@@ -110,15 +144,16 @@ export declare enum DecimalTolerance {
|
|
|
110
144
|
Hundredth = "0.01",
|
|
111
145
|
Thousandth = "0.001"
|
|
112
146
|
}
|
|
113
|
-
export
|
|
114
|
-
createdAt: any;
|
|
147
|
+
export interface UserDocument extends FirestoreDoc, Timestamps {
|
|
115
148
|
defaultOrganization: string;
|
|
116
149
|
displayName: string;
|
|
117
150
|
email: string;
|
|
118
|
-
imageUri: string;
|
|
119
151
|
firstName: string;
|
|
120
152
|
lastName: string;
|
|
121
153
|
defaultUnit: Units;
|
|
122
154
|
decimalTolerance: DecimalTolerance;
|
|
123
155
|
fractionalTolerance: FractionalTolerance;
|
|
124
|
-
|
|
156
|
+
showWizard: boolean;
|
|
157
|
+
printLabelSize: string;
|
|
158
|
+
}
|
|
159
|
+
export { evaluateColumnValue } from './formulas/evaluateColumnValue';
|
package/dist/index.js
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
|
+
;
|
|
1
2
|
export var OrganizationRole;
|
|
2
3
|
(function (OrganizationRole) {
|
|
3
|
-
OrganizationRole["
|
|
4
|
-
OrganizationRole["
|
|
4
|
+
OrganizationRole["Admin"] = "admin";
|
|
5
|
+
OrganizationRole["Member"] = "member";
|
|
5
6
|
})(OrganizationRole || (OrganizationRole = {}));
|
|
6
7
|
export var InvitationStatus;
|
|
7
8
|
(function (InvitationStatus) {
|
|
8
9
|
InvitationStatus["Pending"] = "pending";
|
|
9
10
|
InvitationStatus["Accepted"] = "accepted";
|
|
10
11
|
})(InvitationStatus || (InvitationStatus = {}));
|
|
12
|
+
;
|
|
13
|
+
;
|
|
14
|
+
export var FolderType;
|
|
15
|
+
(function (FolderType) {
|
|
16
|
+
FolderType["Project"] = "project";
|
|
17
|
+
FolderType["Job"] = "job";
|
|
18
|
+
})(FolderType || (FolderType = {}));
|
|
11
19
|
export var ColumnType;
|
|
12
20
|
(function (ColumnType) {
|
|
13
21
|
ColumnType["Text"] = "text";
|
|
14
22
|
ColumnType["Number"] = "number";
|
|
15
23
|
ColumnType["Measurement"] = "measurement";
|
|
16
24
|
ColumnType["Boolean"] = "boolean";
|
|
25
|
+
ColumnType["Formula"] = "formula";
|
|
17
26
|
})(ColumnType || (ColumnType = {}));
|
|
18
|
-
export var MeasurementType;
|
|
19
|
-
(function (MeasurementType) {
|
|
20
|
-
})(MeasurementType || (MeasurementType = {}));
|
|
21
27
|
export var Units;
|
|
22
28
|
(function (Units) {
|
|
23
29
|
Units["Centimeters"] = "cm";
|
|
@@ -67,4 +73,6 @@ export var DecimalTolerance;
|
|
|
67
73
|
DecimalTolerance["Hundredth"] = "0.01";
|
|
68
74
|
DecimalTolerance["Thousandth"] = "0.001";
|
|
69
75
|
})(DecimalTolerance || (DecimalTolerance = {}));
|
|
76
|
+
;
|
|
77
|
+
export { evaluateColumnValue } from './formulas/evaluateColumnValue';
|
|
70
78
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiBC,CAAC;AAEF,MAAM,CAAN,IAAY,gBAGX;AAHD,WAAY,gBAAgB;IAC1B,mCAAe,CAAA;IACf,qCAAiB,CAAA;AACnB,CAAC,EAHW,gBAAgB,KAAhB,gBAAgB,QAG3B;AAED,MAAM,CAAN,IAAY,gBAGX;AAHD,WAAY,gBAAgB;IAC1B,uCAAmB,CAAA;IACnB,yCAAqB,CAAA;AACvB,CAAC,EAHW,gBAAgB,KAAhB,gBAAgB,QAG3B;AAeA,CAAC;AASD,CAAC;AAYF,MAAM,CAAN,IAAY,UAGX;AAHD,WAAY,UAAU;IACpB,iCAAmB,CAAA;IACnB,yBAAW,CAAA;AACb,CAAC,EAHW,UAAU,KAAV,UAAU,QAGrB;AAoCD,MAAM,CAAN,IAAY,UAMX;AAND,WAAY,UAAU;IACpB,2BAAa,CAAA;IACb,+BAAiB,CAAA;IACjB,yCAA2B,CAAA;IAC3B,iCAAmB,CAAA;IACnB,iCAAmB,CAAA;AACrB,CAAC,EANW,UAAU,KAAV,UAAU,QAMrB;AAgCD,MAAM,CAAN,IAAY,KASX;AATD,WAAY,KAAK;IACf,2BAAkB,CAAA;IAClB,2BAAkB,CAAA;IAClB,qBAAY,CAAA;IACZ,sBAAa,CAAA;IACb,qCAA4B,CAAA;IAC5B,oBAAW,CAAA;IACX,4CAAmC,CAAA;IACnC,4CAAmC,CAAA;AACrC,CAAC,EATW,KAAK,KAAL,KAAK,QAShB;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,UAAiB,EAAE,EAAE;IAC1D,QAAQ,UAAU,EAAE,CAAC;QACnB,KAAK,KAAK,CAAC,MAAM;YACf,OAAO,GAAG,CAAC;QACb,KAAK,KAAK,CAAC,WAAW;YACpB,OAAO,IAAI,CAAC;QACd,KAAK,KAAK,CAAC,WAAW;YACpB,OAAO,IAAI,CAAC;QACd,KAAK,KAAK,CAAC,IAAI;YACb,OAAO,IAAI,CAAC;QACd,KAAK,KAAK,CAAC,gBAAgB;YACzB,OAAO,iBAAiB,CAAC;QAC3B,KAAK,KAAK,CAAC,MAAM;YACf,OAAO,IAAI,CAAC;QACd,KAAK,KAAK,CAAC,iBAAiB;YAC1B,OAAO,iBAAiB,CAAC;QAC3B,KAAK,KAAK,CAAC,oBAAoB;YAC7B,OAAO,oBAAoB,CAAC;QAC9B;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAN,IAAY,mBAOX;AAPD,WAAY,mBAAmB;IAC7B,mCAAY,CAAA;IACZ,mCAAY,CAAA;IACZ,uCAAgB,CAAA;IAChB,0CAAmB,CAAA;IACnB,yCAAkB,CAAA;IAClB,8CAAuB,CAAA;AACzB,CAAC,EAPW,mBAAmB,KAAnB,mBAAmB,QAO9B;AAED,MAAM,CAAN,IAAY,gBAKX;AALD,WAAY,gBAAgB;IAC1B,gCAAY,CAAA;IACZ,iCAAa,CAAA;IACb,sCAAkB,CAAA;IAClB,wCAAoB,CAAA;AACtB,CAAC,EALW,gBAAgB,KAAhB,gBAAgB,QAK3B;AAaA,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
type MeasurementMap = Map<string, {
|
|
2
|
+
id: string;
|
|
3
|
+
value: number;
|
|
4
|
+
}[]>;
|
|
5
|
+
interface FormulaEvaluationOptions {
|
|
6
|
+
expression: string;
|
|
7
|
+
mappings: Record<string, string>;
|
|
8
|
+
group: {
|
|
9
|
+
id: string;
|
|
10
|
+
columns: Map<string, any>;
|
|
11
|
+
};
|
|
12
|
+
columns: {
|
|
13
|
+
id: string;
|
|
14
|
+
type: string;
|
|
15
|
+
}[];
|
|
16
|
+
measurementMap: MeasurementMap;
|
|
17
|
+
defaultUnit?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function evaluateFormula({ expression, mappings, group, columns, measurementMap, defaultUnit, }: FormulaEvaluationOptions): number | string;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { create, all } from 'mathjs';
|
|
2
|
+
const math = create(all);
|
|
3
|
+
export function evaluateFormula({ expression, mappings, group, columns, measurementMap, defaultUnit = 'um', }) {
|
|
4
|
+
const scope = {};
|
|
5
|
+
for (const [variable, columnId] of Object.entries(mappings)) {
|
|
6
|
+
const rawValue = group.columns.get(columnId);
|
|
7
|
+
const columnDef = columns.find((c) => c.id === columnId);
|
|
8
|
+
if ((columnDef === null || columnDef === void 0 ? void 0 : columnDef.type) === 'Measurement') {
|
|
9
|
+
const groupMeasurements = measurementMap.get(group.id) || [];
|
|
10
|
+
const measurement = groupMeasurements.find((m) => m.id === rawValue);
|
|
11
|
+
if ((measurement === null || measurement === void 0 ? void 0 : measurement.value) !== undefined) {
|
|
12
|
+
scope[variable] = math.unit(measurement.value, defaultUnit);
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const parsedValue = typeof rawValue === 'number' ? rawValue : parseFloat(rawValue || '');
|
|
17
|
+
scope[variable] = isNaN(parsedValue) ? 0 : parsedValue;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const compiled = math.compile(expression);
|
|
21
|
+
const result = compiled.evaluate(scope);
|
|
22
|
+
if (math.typeOf(result) === 'Unit') {
|
|
23
|
+
return result.toNumber(defaultUnit);
|
|
24
|
+
}
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
console.error(`Formula evaluation failed:`, err);
|
|
29
|
+
return 'Error';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=evaluateFormula.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluateFormula.js","sourceRoot":"","sources":["../../src/utils/evaluateFormula.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,GAAG,EAAQ,MAAM,QAAQ,CAAC;AAE3C,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;AAazB,MAAM,UAAU,eAAe,CAAC,EAC9B,UAAU,EACV,QAAQ,EACR,KAAK,EACL,OAAO,EACP,cAAc,EACd,WAAW,GAAG,IAAI,GACO;IACzB,MAAM,KAAK,GAAwB,EAAE,CAAC;IAEtC,KAAK,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5D,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;QAEzD,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,MAAK,aAAa,EAAE,CAAC;YACtC,MAAM,iBAAiB,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;YAC7D,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;YACrE,IAAI,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK,MAAK,SAAS,EAAE,CAAC;gBACrC,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;gBAC5D,SAAS;YACX,CAAC;QACH,CAAC;QAED,MAAM,WAAW,GACf,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QACvE,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;IACzD,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAExC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,MAAM,EAAE,CAAC;YACnC,OAAO,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACtC,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;QACjD,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC"}
|
|
@@ -29,4 +29,13 @@ export const parseMeasurement = (input, defaultUnit = 'mm') => {
|
|
|
29
29
|
return null;
|
|
30
30
|
}
|
|
31
31
|
};
|
|
32
|
+
export const numberToLetterIndex = (index) => {
|
|
33
|
+
let result = '';
|
|
34
|
+
while (index > 0) {
|
|
35
|
+
index--; // Adjust for 0-based index
|
|
36
|
+
result = String.fromCharCode((index % 26) + 65) + result;
|
|
37
|
+
index = Math.floor(index / 26);
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
32
41
|
//# sourceMappingURL=parseMeasurement.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseMeasurement.js","sourceRoot":"","sources":["../../src/utils/parseMeasurement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;AAEzB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,KAAa,EACb,cAAsB,IAAI,EACX,EAAE;IACjB,IAAI,CAAC;QACH,4BAA4B;QAC5B,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAE1D,4DAA4D;QAC5D,MAAM,cAAc,GAAG,eAAe,CAAC,OAAO,CAC5C,qBAAqB,EACrB,SAAS,CACV,CAAC;QAEF,wCAAwC;QACxC,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAEjE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QAED,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;QAE/B,gDAAgD;QAChD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAEjD,wDAAwD;QACxD,MAAM,UAAU,GAAG,IAAI,IAAI,WAAW,CAAC;QAEvC,yBAAyB;QACzB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"parseMeasurement.js","sourceRoot":"","sources":["../../src/utils/parseMeasurement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;AAEzB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,KAAa,EACb,cAAsB,IAAI,EACX,EAAE;IACjB,IAAI,CAAC;QACH,4BAA4B;QAC5B,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAE1D,4DAA4D;QAC5D,MAAM,cAAc,GAAG,eAAe,CAAC,OAAO,CAC5C,qBAAqB,EACrB,SAAS,CACV,CAAC;QAEF,wCAAwC;QACxC,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAEjE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QAED,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;QAE/B,gDAAgD;QAChD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAEjD,wDAAwD;QACxD,MAAM,UAAU,GAAG,IAAI,IAAI,WAAW,CAAC;QAEvC,yBAAyB;QACzB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAa,EAAU,EAAE;IAC3D,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,OAAO,KAAK,GAAG,CAAC,EAAE,CAAC;QACjB,KAAK,EAAE,CAAC,CAAC,2BAA2B;QACpC,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,MAAM,CAAC;QACzD,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reekon-tools/boldr-utils",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Shared utilities for Boldr projects in Reekon Tools",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"dist"
|
|
9
9
|
],
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "tsc"
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"test": "jest"
|
|
12
13
|
},
|
|
13
14
|
"keywords": [],
|
|
14
15
|
"author": "",
|
|
@@ -21,7 +22,12 @@
|
|
|
21
22
|
"react": "^18.0.0"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
25
|
+
"@types/jest": "^29.5.14",
|
|
26
|
+
"@types/node": "^22.15.18",
|
|
24
27
|
"@types/react": "^19.0.8",
|
|
28
|
+
"jest": "^29.7.0",
|
|
29
|
+
"ts-jest": "^29.3.3",
|
|
30
|
+
"ts-node": "^10.9.2",
|
|
25
31
|
"typescript": "^5.7.3"
|
|
26
32
|
},
|
|
27
33
|
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|