easyeda 0.0.250 → 0.0.251
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/browser/index.d.ts +8 -3
- package/dist/browser/index.js +1596 -1565
- package/dist/browser/index.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +199 -170
- package/dist/index.js.map +1 -1
- package/dist/main.cjs +2585 -2556
- package/dist/main.cjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
1
|
import { AnyCircuitElement } from 'circuit-json';
|
|
2
|
+
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
declare const maybeNumber: z.ZodPipeline<z.ZodEffects<z.ZodAny, any, any>, z.ZodOptional<z.ZodNullable<z.ZodNumber>>>;
|
|
5
5
|
declare const SzlcscSchema: z.ZodObject<{
|
|
@@ -4870,7 +4870,10 @@ declare function fetchEasyEDAComponent(jlcpcbPartNumber: string, { fetch, includ
|
|
|
4870
4870
|
includeModelMetadata?: boolean;
|
|
4871
4871
|
}): Promise<RawEasyEdaJson>;
|
|
4872
4872
|
|
|
4873
|
-
declare const convertRawEasyToTsx: (rawEasy
|
|
4873
|
+
declare const convertRawEasyToTsx: ({ rawEasy, format, }: {
|
|
4874
|
+
rawEasy: any;
|
|
4875
|
+
format?: "obj" | "step";
|
|
4876
|
+
}) => Promise<string>;
|
|
4874
4877
|
|
|
4875
4878
|
declare function normalizeManufacturerPartNumber(partNumber: string): string;
|
|
4876
4879
|
|
package/dist/index.js
CHANGED
|
@@ -3643,51 +3643,6 @@ var any_soup_element = any_circuit_element;
|
|
|
3643
3643
|
expectTypesMatch(true);
|
|
3644
3644
|
expectStringUnionsMatch(true);
|
|
3645
3645
|
|
|
3646
|
-
// lib/math/arc-utils.ts
|
|
3647
|
-
function generateArcFromSweep(startX, startY, endX, endY, radius, largeArcFlag, sweepFlag) {
|
|
3648
|
-
const start = { x: startX, y: startY };
|
|
3649
|
-
const end = { x: endX, y: endY };
|
|
3650
|
-
const midX = (startX + endX) / 2;
|
|
3651
|
-
const midY = (startY + endY) / 2;
|
|
3652
|
-
const dx = endX - startX;
|
|
3653
|
-
const dy = endY - startY;
|
|
3654
|
-
const distance2 = Math.sqrt(dx * dx + dy * dy);
|
|
3655
|
-
if (distance2 === 0 || radius < distance2 / 2) {
|
|
3656
|
-
return [start, end];
|
|
3657
|
-
}
|
|
3658
|
-
const h = Math.sqrt(radius * radius - distance2 * distance2 / 4);
|
|
3659
|
-
const angle = Math.atan2(dy, dx);
|
|
3660
|
-
const centerX = midX + h * Math.sin(angle) * (sweepFlag ? -1 : 1);
|
|
3661
|
-
const centerY = midY - h * Math.cos(angle) * (sweepFlag ? -1 : 1);
|
|
3662
|
-
const startAngle = Math.atan2(startY - centerY, startX - centerX);
|
|
3663
|
-
let endAngle = Math.atan2(endY - centerY, endX - centerX);
|
|
3664
|
-
if (sweepFlag && endAngle > startAngle) {
|
|
3665
|
-
endAngle -= 2 * Math.PI;
|
|
3666
|
-
} else if (!sweepFlag && endAngle < startAngle) {
|
|
3667
|
-
endAngle += 2 * Math.PI;
|
|
3668
|
-
}
|
|
3669
|
-
if (!largeArcFlag && Math.abs(endAngle - startAngle) > Math.PI || largeArcFlag && Math.abs(endAngle - startAngle) < Math.PI) {
|
|
3670
|
-
if (endAngle > startAngle) {
|
|
3671
|
-
endAngle -= 2 * Math.PI;
|
|
3672
|
-
} else {
|
|
3673
|
-
endAngle += 2 * Math.PI;
|
|
3674
|
-
}
|
|
3675
|
-
}
|
|
3676
|
-
const numPoints = Math.max(
|
|
3677
|
-
2,
|
|
3678
|
-
Math.ceil(Math.abs(endAngle - startAngle) * radius)
|
|
3679
|
-
);
|
|
3680
|
-
const path2 = [];
|
|
3681
|
-
for (let i = 0; i <= numPoints; i++) {
|
|
3682
|
-
const t = i / numPoints;
|
|
3683
|
-
const angle2 = startAngle + t * (endAngle - startAngle);
|
|
3684
|
-
const x = centerX + radius * Math.cos(angle2);
|
|
3685
|
-
const y = centerY + radius * Math.sin(angle2);
|
|
3686
|
-
path2.push({ x, y });
|
|
3687
|
-
}
|
|
3688
|
-
return path2;
|
|
3689
|
-
}
|
|
3690
|
-
|
|
3691
3646
|
// node_modules/transformation-matrix/src/applyToPoint.js
|
|
3692
3647
|
function applyToPoint(matrix, point2) {
|
|
3693
3648
|
return Array.isArray(point2) ? [
|
|
@@ -5058,6 +5013,54 @@ var mmStr = (n) => {
|
|
|
5058
5013
|
return `${mm(n)}mm`;
|
|
5059
5014
|
};
|
|
5060
5015
|
|
|
5016
|
+
// lib/constants.ts
|
|
5017
|
+
var DEFAULT_PCB_THICKNESS_MM = 1.6;
|
|
5018
|
+
|
|
5019
|
+
// lib/math/arc-utils.ts
|
|
5020
|
+
function generateArcFromSweep(startX, startY, endX, endY, radius, largeArcFlag, sweepFlag) {
|
|
5021
|
+
const start = { x: startX, y: startY };
|
|
5022
|
+
const end = { x: endX, y: endY };
|
|
5023
|
+
const midX = (startX + endX) / 2;
|
|
5024
|
+
const midY = (startY + endY) / 2;
|
|
5025
|
+
const dx = endX - startX;
|
|
5026
|
+
const dy = endY - startY;
|
|
5027
|
+
const distance2 = Math.sqrt(dx * dx + dy * dy);
|
|
5028
|
+
if (distance2 === 0 || radius < distance2 / 2) {
|
|
5029
|
+
return [start, end];
|
|
5030
|
+
}
|
|
5031
|
+
const h = Math.sqrt(radius * radius - distance2 * distance2 / 4);
|
|
5032
|
+
const angle = Math.atan2(dy, dx);
|
|
5033
|
+
const centerX = midX + h * Math.sin(angle) * (sweepFlag ? -1 : 1);
|
|
5034
|
+
const centerY = midY - h * Math.cos(angle) * (sweepFlag ? -1 : 1);
|
|
5035
|
+
const startAngle = Math.atan2(startY - centerY, startX - centerX);
|
|
5036
|
+
let endAngle = Math.atan2(endY - centerY, endX - centerX);
|
|
5037
|
+
if (sweepFlag && endAngle > startAngle) {
|
|
5038
|
+
endAngle -= 2 * Math.PI;
|
|
5039
|
+
} else if (!sweepFlag && endAngle < startAngle) {
|
|
5040
|
+
endAngle += 2 * Math.PI;
|
|
5041
|
+
}
|
|
5042
|
+
if (!largeArcFlag && Math.abs(endAngle - startAngle) > Math.PI || largeArcFlag && Math.abs(endAngle - startAngle) < Math.PI) {
|
|
5043
|
+
if (endAngle > startAngle) {
|
|
5044
|
+
endAngle -= 2 * Math.PI;
|
|
5045
|
+
} else {
|
|
5046
|
+
endAngle += 2 * Math.PI;
|
|
5047
|
+
}
|
|
5048
|
+
}
|
|
5049
|
+
const numPoints = Math.max(
|
|
5050
|
+
2,
|
|
5051
|
+
Math.ceil(Math.abs(endAngle - startAngle) * radius)
|
|
5052
|
+
);
|
|
5053
|
+
const path2 = [];
|
|
5054
|
+
for (let i = 0; i <= numPoints; i++) {
|
|
5055
|
+
const t = i / numPoints;
|
|
5056
|
+
const angle2 = startAngle + t * (endAngle - startAngle);
|
|
5057
|
+
const x = centerX + radius * Math.cos(angle2);
|
|
5058
|
+
const y = centerY + radius * Math.sin(angle2);
|
|
5059
|
+
path2.push({ x, y });
|
|
5060
|
+
}
|
|
5061
|
+
return path2;
|
|
5062
|
+
}
|
|
5063
|
+
|
|
5061
5064
|
// lib/utils/easyeda-unit-to-mm.ts
|
|
5062
5065
|
var mil10ToMm = (value) => value * 10 * 0.0254;
|
|
5063
5066
|
|
|
@@ -5130,9 +5133,6 @@ var normalizePinLabels = (inputPinLabels) => {
|
|
|
5130
5133
|
return result;
|
|
5131
5134
|
};
|
|
5132
5135
|
|
|
5133
|
-
// lib/constants.ts
|
|
5134
|
-
var DEFAULT_PCB_THICKNESS_MM = 1.6;
|
|
5135
|
-
|
|
5136
5136
|
// lib/utils/normalize-symbol-name.ts
|
|
5137
5137
|
var normalizeSymbolName = (name) => {
|
|
5138
5138
|
const trimmedName = name.trim();
|
|
@@ -5142,6 +5142,9 @@ var normalizeSymbolName = (name) => {
|
|
|
5142
5142
|
};
|
|
5143
5143
|
|
|
5144
5144
|
// lib/convert-easyeda-json-to-tscircuit-soup-json.ts
|
|
5145
|
+
var EASYEDA_STEP_MODEL_URL = "https://modules.easyeda.com/qAxj6KHrDKw4blvCG8QJPs7Y";
|
|
5146
|
+
var EASYEDA_OBJ_MODEL_URL = "https://modules.easyeda.com/3dmodel";
|
|
5147
|
+
var TSCIRCUIT_MODEL_CDN_URL = "https://modelcdn.tscircuit.com/easyeda_models";
|
|
5145
5148
|
var mil2mm = (mil) => {
|
|
5146
5149
|
if (typeof mil === "number") return mm(`${mil}mil`);
|
|
5147
5150
|
if (mil.match(/^\d+$/)) return mm(`${mil}mil`);
|
|
@@ -5504,9 +5507,10 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, { useModelCdn, shouldRecente
|
|
|
5504
5507
|
const svgNode = easyEdaJson.packageDetail.dataStr.shape.find(
|
|
5505
5508
|
(a) => Boolean(a.type === "SVGNODE" && a.svgData.attrs?.uuid)
|
|
5506
5509
|
);
|
|
5507
|
-
const
|
|
5508
|
-
const objFileUrl =
|
|
5509
|
-
|
|
5510
|
+
const modelUuid = svgNode?.svgData?.attrs?.uuid;
|
|
5511
|
+
const objFileUrl = modelUuid ? useModelCdn ? `${TSCIRCUIT_MODEL_CDN_URL}/assets/${easyEdaJson.lcsc.number}.obj?uuid=${modelUuid}` : `${EASYEDA_OBJ_MODEL_URL}/${modelUuid}` : void 0;
|
|
5512
|
+
const stepFileUrl = modelUuid ? useModelCdn ? `${TSCIRCUIT_MODEL_CDN_URL}/assets/${easyEdaJson.lcsc.number}.step?uuid=${modelUuid}` : `${EASYEDA_STEP_MODEL_URL}/${modelUuid}` : void 0;
|
|
5513
|
+
if (objFileUrl !== void 0 || stepFileUrl !== void 0) {
|
|
5510
5514
|
const { position: position2, rotation: rotation2 } = parseCadOffsetsFromSvgNode(svgNode);
|
|
5511
5515
|
circuitElements.push(
|
|
5512
5516
|
cad_component.parse({
|
|
@@ -5523,7 +5527,8 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, { useModelCdn, shouldRecente
|
|
|
5523
5527
|
},
|
|
5524
5528
|
position: { x: 0, y: 0, z: 0 },
|
|
5525
5529
|
rotation: rotation2,
|
|
5526
|
-
model_obj_url: objFileUrl
|
|
5530
|
+
model_obj_url: objFileUrl,
|
|
5531
|
+
model_step_url: stepFileUrl
|
|
5527
5532
|
})
|
|
5528
5533
|
);
|
|
5529
5534
|
}
|
|
@@ -5660,9 +5665,11 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, { useModelCdn, shouldRecente
|
|
|
5660
5665
|
// lib/websafe/get-model-cdn-url.ts
|
|
5661
5666
|
var getModelCdnUrl = ({
|
|
5662
5667
|
easyedaModelUuid,
|
|
5663
|
-
easyedaPartNumber
|
|
5668
|
+
easyedaPartNumber,
|
|
5669
|
+
format = "obj"
|
|
5664
5670
|
}) => {
|
|
5665
|
-
|
|
5671
|
+
const extension = format === "step" ? "step" : "obj";
|
|
5672
|
+
return `https://modelcdn.tscircuit.com/easyeda_models/assets/${easyedaPartNumber}.${extension}?uuid=${easyedaModelUuid}`;
|
|
5666
5673
|
};
|
|
5667
5674
|
|
|
5668
5675
|
// lib/websafe/fetch-easyeda-json.ts
|
|
@@ -5679,7 +5686,6 @@ var getModelUuidFromRawPackageDetail = (result) => {
|
|
|
5679
5686
|
return modelUuid;
|
|
5680
5687
|
}
|
|
5681
5688
|
} catch {
|
|
5682
|
-
continue;
|
|
5683
5689
|
}
|
|
5684
5690
|
}
|
|
5685
5691
|
return null;
|
|
@@ -6540,6 +6546,120 @@ var EasyEdaJsonSchema = z163.object({
|
|
|
6540
6546
|
}).optional()
|
|
6541
6547
|
});
|
|
6542
6548
|
|
|
6549
|
+
// lib/utils/normalize-manufacturer-part-number.ts
|
|
6550
|
+
function normalizeManufacturerPartNumber(partNumber) {
|
|
6551
|
+
let normalized = partNumber.replace(/[-]/g, "_").replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
6552
|
+
if (/^\d/.test(normalized)) {
|
|
6553
|
+
normalized = "A_" + normalized;
|
|
6554
|
+
}
|
|
6555
|
+
return normalized;
|
|
6556
|
+
}
|
|
6557
|
+
|
|
6558
|
+
// lib/websafe/get-easyeda-cad-model-placement.ts
|
|
6559
|
+
var placementCache = /* @__PURE__ */ new Map();
|
|
6560
|
+
var parseObjBounds2 = (objText) => {
|
|
6561
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
6562
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
6563
|
+
let minZ = Number.POSITIVE_INFINITY;
|
|
6564
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
6565
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
6566
|
+
let maxZ = Number.NEGATIVE_INFINITY;
|
|
6567
|
+
let vertexCount = 0;
|
|
6568
|
+
for (const line of objText.split(/\r?\n/)) {
|
|
6569
|
+
const trimmed = line.trim();
|
|
6570
|
+
if (!trimmed.startsWith("v ")) continue;
|
|
6571
|
+
const [, xStr, yStr, zStr] = trimmed.split(/\s+/, 4);
|
|
6572
|
+
const x = Number(xStr);
|
|
6573
|
+
const y = Number(yStr);
|
|
6574
|
+
const z164 = Number(zStr);
|
|
6575
|
+
if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z164)) {
|
|
6576
|
+
continue;
|
|
6577
|
+
}
|
|
6578
|
+
vertexCount += 1;
|
|
6579
|
+
minX = Math.min(minX, x);
|
|
6580
|
+
minY = Math.min(minY, y);
|
|
6581
|
+
minZ = Math.min(minZ, z164);
|
|
6582
|
+
maxX = Math.max(maxX, x);
|
|
6583
|
+
maxY = Math.max(maxY, y);
|
|
6584
|
+
maxZ = Math.max(maxZ, z164);
|
|
6585
|
+
}
|
|
6586
|
+
if (vertexCount === 0) return null;
|
|
6587
|
+
return {
|
|
6588
|
+
min: { x: minX, y: minY, z: minZ },
|
|
6589
|
+
max: { x: maxX, y: maxY, z: maxZ }
|
|
6590
|
+
};
|
|
6591
|
+
};
|
|
6592
|
+
var getSvgNodeZOffsetMm = (easyEdaJson) => {
|
|
6593
|
+
const svgNode = easyEdaJson.packageDetail.dataStr.shape.find(
|
|
6594
|
+
(shape) => shape.type === "SVGNODE" && shape.svgData.attrs?.uuid
|
|
6595
|
+
);
|
|
6596
|
+
if (!svgNode || svgNode.type !== "SVGNODE") return null;
|
|
6597
|
+
const svgNodeZ = Number(svgNode.svgData.attrs?.z ?? 0);
|
|
6598
|
+
if (!Number.isFinite(svgNodeZ)) return null;
|
|
6599
|
+
return mil10ToMm(svgNodeZ);
|
|
6600
|
+
};
|
|
6601
|
+
var getPositionZMmFromBounds = (bounds, svgNodeZOffsetMm) => {
|
|
6602
|
+
const minZ = Math.abs(bounds.min.z) < 1e-6 ? 0 : bounds.min.z;
|
|
6603
|
+
return minZ - svgNodeZOffsetMm;
|
|
6604
|
+
};
|
|
6605
|
+
var getEasyEdaCadModelPlacement = async (easyEdaJson, { fetch: fetch2 = globalThis.fetch } = {}) => {
|
|
6606
|
+
const svgNode = easyEdaJson.packageDetail.dataStr.shape.find(
|
|
6607
|
+
(shape) => shape.type === "SVGNODE" && shape.svgData.attrs?.uuid
|
|
6608
|
+
);
|
|
6609
|
+
if (!svgNode || svgNode.type !== "SVGNODE") return null;
|
|
6610
|
+
const modelUuid = svgNode.svgData.attrs?.uuid;
|
|
6611
|
+
const partNumber = easyEdaJson.lcsc.number;
|
|
6612
|
+
const svgNodeZOffsetMm = getSvgNodeZOffsetMm(easyEdaJson);
|
|
6613
|
+
if (!modelUuid || !partNumber || svgNodeZOffsetMm == null || !fetch2) {
|
|
6614
|
+
return null;
|
|
6615
|
+
}
|
|
6616
|
+
const modelObjUrl = getModelCdnUrl({
|
|
6617
|
+
easyedaModelUuid: modelUuid,
|
|
6618
|
+
easyedaPartNumber: partNumber
|
|
6619
|
+
});
|
|
6620
|
+
const modelStepUrl = getModelCdnUrl({
|
|
6621
|
+
easyedaModelUuid: modelUuid,
|
|
6622
|
+
easyedaPartNumber: partNumber,
|
|
6623
|
+
format: "step"
|
|
6624
|
+
});
|
|
6625
|
+
const metadataBounds = easyEdaJson._objMetadata?.bounds;
|
|
6626
|
+
if (metadataBounds) {
|
|
6627
|
+
return {
|
|
6628
|
+
modelObjUrl,
|
|
6629
|
+
modelStepUrl,
|
|
6630
|
+
bounds: metadataBounds,
|
|
6631
|
+
positionZMm: getPositionZMmFromBounds(metadataBounds, svgNodeZOffsetMm)
|
|
6632
|
+
};
|
|
6633
|
+
}
|
|
6634
|
+
const cacheKey = `${modelObjUrl}::${svgNodeZOffsetMm}`;
|
|
6635
|
+
const cachedPlacement = placementCache.get(cacheKey);
|
|
6636
|
+
if (cachedPlacement) return cachedPlacement;
|
|
6637
|
+
const placementPromise = (async () => {
|
|
6638
|
+
try {
|
|
6639
|
+
const response = await fetch2(modelObjUrl);
|
|
6640
|
+
if (!response.ok) return null;
|
|
6641
|
+
const objText = await response.text();
|
|
6642
|
+
const bounds = parseObjBounds2(objText);
|
|
6643
|
+
if (!bounds) return null;
|
|
6644
|
+
return {
|
|
6645
|
+
modelObjUrl,
|
|
6646
|
+
modelStepUrl,
|
|
6647
|
+
bounds,
|
|
6648
|
+
// Align the EasyEDA SVG-node Z against the model's minimum Z.
|
|
6649
|
+
positionZMm: getPositionZMmFromBounds(bounds, svgNodeZOffsetMm)
|
|
6650
|
+
};
|
|
6651
|
+
} catch (error) {
|
|
6652
|
+
console.error(
|
|
6653
|
+
`Error resolving EasyEDA CAD placement for ${partNumber}:`,
|
|
6654
|
+
error
|
|
6655
|
+
);
|
|
6656
|
+
return null;
|
|
6657
|
+
}
|
|
6658
|
+
})();
|
|
6659
|
+
placementCache.set(cacheKey, placementPromise);
|
|
6660
|
+
return placementPromise;
|
|
6661
|
+
};
|
|
6662
|
+
|
|
6543
6663
|
// lib/websafe/generate-footprint-tsx.ts
|
|
6544
6664
|
var generateFootprintTsx = (circuitJson) => {
|
|
6545
6665
|
const holes = su(circuitJson).pcb_hole.list();
|
|
@@ -6623,6 +6743,7 @@ var generateTypescriptComponent = ({
|
|
|
6623
6743
|
pinLabels,
|
|
6624
6744
|
componentName,
|
|
6625
6745
|
objUrl,
|
|
6746
|
+
stepUrl,
|
|
6626
6747
|
circuitJson,
|
|
6627
6748
|
supplierPartNumbers,
|
|
6628
6749
|
manufacturerPartNumber
|
|
@@ -6639,6 +6760,12 @@ var generateTypescriptComponent = ({
|
|
|
6639
6760
|
})
|
|
6640
6761
|
);
|
|
6641
6762
|
const pinLabelsString = Object.entries(simplifiedPinLabels).map(([pin, labels]) => ` ${pin}: ${JSON.stringify(labels)}`).join(",\n");
|
|
6763
|
+
const cadModelLines = [
|
|
6764
|
+
objUrl ? `objUrl: "${objUrl}",` : "",
|
|
6765
|
+
stepUrl ? `stepUrl: "${stepUrl}",` : "",
|
|
6766
|
+
`pcbRotationOffset: ${cadComponent?.rotation?.z ?? 0},`,
|
|
6767
|
+
`modelOriginPosition: { x: ${cadComponent?.model_origin_position?.x ?? 0}, y: ${cadComponent?.model_origin_position?.y ?? 0}, z: ${cadComponent?.model_origin_position?.z ?? 0} },`
|
|
6768
|
+
].filter(Boolean).map((line) => ` ${line}`).join("\n");
|
|
6642
6769
|
return `
|
|
6643
6770
|
import type { ChipProps } from "@tscircuit/props"
|
|
6644
6771
|
|
|
@@ -6653,10 +6780,8 @@ export const ${componentName} = (props: ChipProps<typeof pinLabels>) => {
|
|
|
6653
6780
|
supplierPartNumbers={${JSON.stringify(supplierPartNumbers, null, " ")}}
|
|
6654
6781
|
manufacturerPartNumber="${manufacturerPartNumber}"
|
|
6655
6782
|
footprint={${footprintTsx}}
|
|
6656
|
-
${objUrl ? `cadModel={{
|
|
6657
|
-
|
|
6658
|
-
pcbRotationOffset: ${cadComponent?.rotation?.z ?? 0},
|
|
6659
|
-
modelOriginPosition: { x: ${cadComponent?.model_origin_position?.x ?? 0}, y: ${cadComponent?.model_origin_position?.y ?? 0}, z: ${cadComponent?.model_origin_position?.z ?? 0} },
|
|
6783
|
+
${objUrl || stepUrl ? `cadModel={{
|
|
6784
|
+
${cadModelLines}
|
|
6660
6785
|
}}` : ""}
|
|
6661
6786
|
{...props}
|
|
6662
6787
|
/>
|
|
@@ -6665,123 +6790,21 @@ export const ${componentName} = (props: ChipProps<typeof pinLabels>) => {
|
|
|
6665
6790
|
`.trim();
|
|
6666
6791
|
};
|
|
6667
6792
|
|
|
6668
|
-
// lib/utils/normalize-manufacturer-part-number.ts
|
|
6669
|
-
function normalizeManufacturerPartNumber(partNumber) {
|
|
6670
|
-
let normalized = partNumber.replace(/[-]/g, "_").replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
6671
|
-
if (/^\d/.test(normalized)) {
|
|
6672
|
-
normalized = "A_" + normalized;
|
|
6673
|
-
}
|
|
6674
|
-
return normalized;
|
|
6675
|
-
}
|
|
6676
|
-
|
|
6677
|
-
// lib/websafe/get-easyeda-cad-model-placement.ts
|
|
6678
|
-
var placementCache = /* @__PURE__ */ new Map();
|
|
6679
|
-
var parseObjBounds2 = (objText) => {
|
|
6680
|
-
let minX = Number.POSITIVE_INFINITY;
|
|
6681
|
-
let minY = Number.POSITIVE_INFINITY;
|
|
6682
|
-
let minZ = Number.POSITIVE_INFINITY;
|
|
6683
|
-
let maxX = Number.NEGATIVE_INFINITY;
|
|
6684
|
-
let maxY = Number.NEGATIVE_INFINITY;
|
|
6685
|
-
let maxZ = Number.NEGATIVE_INFINITY;
|
|
6686
|
-
let vertexCount = 0;
|
|
6687
|
-
for (const line of objText.split(/\r?\n/)) {
|
|
6688
|
-
const trimmed = line.trim();
|
|
6689
|
-
if (!trimmed.startsWith("v ")) continue;
|
|
6690
|
-
const [, xStr, yStr, zStr] = trimmed.split(/\s+/, 4);
|
|
6691
|
-
const x = Number(xStr);
|
|
6692
|
-
const y = Number(yStr);
|
|
6693
|
-
const z164 = Number(zStr);
|
|
6694
|
-
if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z164)) {
|
|
6695
|
-
continue;
|
|
6696
|
-
}
|
|
6697
|
-
vertexCount += 1;
|
|
6698
|
-
minX = Math.min(minX, x);
|
|
6699
|
-
minY = Math.min(minY, y);
|
|
6700
|
-
minZ = Math.min(minZ, z164);
|
|
6701
|
-
maxX = Math.max(maxX, x);
|
|
6702
|
-
maxY = Math.max(maxY, y);
|
|
6703
|
-
maxZ = Math.max(maxZ, z164);
|
|
6704
|
-
}
|
|
6705
|
-
if (vertexCount === 0) return null;
|
|
6706
|
-
return {
|
|
6707
|
-
min: { x: minX, y: minY, z: minZ },
|
|
6708
|
-
max: { x: maxX, y: maxY, z: maxZ }
|
|
6709
|
-
};
|
|
6710
|
-
};
|
|
6711
|
-
var getSvgNodeZOffsetMm = (easyEdaJson) => {
|
|
6712
|
-
const svgNode = easyEdaJson.packageDetail.dataStr.shape.find(
|
|
6713
|
-
(shape) => shape.type === "SVGNODE" && shape.svgData.attrs?.uuid
|
|
6714
|
-
);
|
|
6715
|
-
if (!svgNode || svgNode.type !== "SVGNODE") return null;
|
|
6716
|
-
const svgNodeZ = Number(svgNode.svgData.attrs?.z ?? 0);
|
|
6717
|
-
if (!Number.isFinite(svgNodeZ)) return null;
|
|
6718
|
-
return mil10ToMm(svgNodeZ);
|
|
6719
|
-
};
|
|
6720
|
-
var getPositionZMmFromBounds = (bounds, svgNodeZOffsetMm) => {
|
|
6721
|
-
const minZ = Math.abs(bounds.min.z) < 1e-6 ? 0 : bounds.min.z;
|
|
6722
|
-
return minZ - svgNodeZOffsetMm;
|
|
6723
|
-
};
|
|
6724
|
-
var getEasyEdaCadModelPlacement = async (easyEdaJson, { fetch: fetch2 = globalThis.fetch } = {}) => {
|
|
6725
|
-
const svgNode = easyEdaJson.packageDetail.dataStr.shape.find(
|
|
6726
|
-
(shape) => shape.type === "SVGNODE" && shape.svgData.attrs?.uuid
|
|
6727
|
-
);
|
|
6728
|
-
if (!svgNode || svgNode.type !== "SVGNODE") return null;
|
|
6729
|
-
const modelUuid = svgNode.svgData.attrs?.uuid;
|
|
6730
|
-
const partNumber = easyEdaJson.lcsc.number;
|
|
6731
|
-
const svgNodeZOffsetMm = getSvgNodeZOffsetMm(easyEdaJson);
|
|
6732
|
-
if (!modelUuid || !partNumber || svgNodeZOffsetMm == null || !fetch2) {
|
|
6733
|
-
return null;
|
|
6734
|
-
}
|
|
6735
|
-
const modelObjUrl = getModelCdnUrl({
|
|
6736
|
-
easyedaModelUuid: modelUuid,
|
|
6737
|
-
easyedaPartNumber: partNumber
|
|
6738
|
-
});
|
|
6739
|
-
const metadataBounds = easyEdaJson._objMetadata?.bounds;
|
|
6740
|
-
if (metadataBounds) {
|
|
6741
|
-
return {
|
|
6742
|
-
modelObjUrl,
|
|
6743
|
-
bounds: metadataBounds,
|
|
6744
|
-
positionZMm: getPositionZMmFromBounds(metadataBounds, svgNodeZOffsetMm)
|
|
6745
|
-
};
|
|
6746
|
-
}
|
|
6747
|
-
const cacheKey = `${modelObjUrl}::${svgNodeZOffsetMm}`;
|
|
6748
|
-
const cachedPlacement = placementCache.get(cacheKey);
|
|
6749
|
-
if (cachedPlacement) return cachedPlacement;
|
|
6750
|
-
const placementPromise = (async () => {
|
|
6751
|
-
try {
|
|
6752
|
-
const response = await fetch2(modelObjUrl);
|
|
6753
|
-
if (!response.ok) return null;
|
|
6754
|
-
const objText = await response.text();
|
|
6755
|
-
const bounds = parseObjBounds2(objText);
|
|
6756
|
-
if (!bounds) return null;
|
|
6757
|
-
return {
|
|
6758
|
-
modelObjUrl,
|
|
6759
|
-
bounds,
|
|
6760
|
-
// Align the EasyEDA SVG-node Z against the model's minimum Z.
|
|
6761
|
-
positionZMm: getPositionZMmFromBounds(bounds, svgNodeZOffsetMm)
|
|
6762
|
-
};
|
|
6763
|
-
} catch (error) {
|
|
6764
|
-
console.error(
|
|
6765
|
-
`Error resolving EasyEDA CAD placement for ${partNumber}:`,
|
|
6766
|
-
error
|
|
6767
|
-
);
|
|
6768
|
-
return null;
|
|
6769
|
-
}
|
|
6770
|
-
})();
|
|
6771
|
-
placementCache.set(cacheKey, placementPromise);
|
|
6772
|
-
return placementPromise;
|
|
6773
|
-
};
|
|
6774
|
-
|
|
6775
6793
|
// lib/websafe/convert-to-typescript-component/index.tsx
|
|
6776
|
-
var convertRawEasyToTsx = async (
|
|
6794
|
+
var convertRawEasyToTsx = async ({
|
|
6795
|
+
rawEasy,
|
|
6796
|
+
format = "obj"
|
|
6797
|
+
}) => {
|
|
6777
6798
|
const betterEasy = EasyEdaJsonSchema.parse(rawEasy);
|
|
6778
6799
|
const result = await convertBetterEasyToTsx({
|
|
6779
|
-
betterEasy
|
|
6800
|
+
betterEasy,
|
|
6801
|
+
format
|
|
6780
6802
|
});
|
|
6781
6803
|
return result;
|
|
6782
6804
|
};
|
|
6783
6805
|
var convertBetterEasyToTsx = async ({
|
|
6784
|
-
betterEasy
|
|
6806
|
+
betterEasy,
|
|
6807
|
+
format = "obj"
|
|
6785
6808
|
}) => {
|
|
6786
6809
|
const cadPlacement = await getEasyEdaCadModelPlacement(betterEasy);
|
|
6787
6810
|
const circuitJson = convertEasyEdaJsonToCircuitJson(betterEasy, {
|
|
@@ -6810,16 +6833,21 @@ var convertBetterEasyToTsx = async ({
|
|
|
6810
6833
|
];
|
|
6811
6834
|
}
|
|
6812
6835
|
let modelObjUrl;
|
|
6836
|
+
let modelStepUrl;
|
|
6813
6837
|
if (cadPlacement?.modelObjUrl) {
|
|
6814
6838
|
modelObjUrl = cadPlacement.modelObjUrl;
|
|
6839
|
+
modelStepUrl = cadPlacement.modelStepUrl;
|
|
6815
6840
|
} else if (cadComponent?.model_obj_url) {
|
|
6816
6841
|
const isValidUrl = await checkModelObjUrlValidity(
|
|
6817
6842
|
cadComponent.model_obj_url
|
|
6818
6843
|
);
|
|
6819
6844
|
if (isValidUrl) {
|
|
6820
6845
|
modelObjUrl = cadComponent.model_obj_url;
|
|
6846
|
+
modelStepUrl = cadComponent.model_step_url;
|
|
6821
6847
|
}
|
|
6822
6848
|
}
|
|
6849
|
+
const selectedObjUrl = format === "obj" ? modelObjUrl : void 0;
|
|
6850
|
+
const selectedStepUrl = format === "step" ? modelStepUrl : void 0;
|
|
6823
6851
|
const supplierPartNumbers = {
|
|
6824
6852
|
jlcpcb: [betterEasy.lcsc.number]
|
|
6825
6853
|
};
|
|
@@ -6827,7 +6855,8 @@ var convertBetterEasyToTsx = async ({
|
|
|
6827
6855
|
componentName: pn,
|
|
6828
6856
|
manufacturerPartNumber: pn,
|
|
6829
6857
|
pinLabels,
|
|
6830
|
-
objUrl:
|
|
6858
|
+
objUrl: selectedObjUrl,
|
|
6859
|
+
stepUrl: selectedStepUrl,
|
|
6831
6860
|
circuitJson,
|
|
6832
6861
|
supplierPartNumbers
|
|
6833
6862
|
});
|