jscad-electronics 0.0.232 → 0.0.234

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/vanilla.js CHANGED
@@ -24,7 +24,7 @@ function h(type, props, ...restChildren) {
24
24
  };
25
25
  }
26
26
 
27
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/external.js
27
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/external.js
28
28
  var external_exports = {};
29
29
  __export(external_exports, {
30
30
  BRAND: () => BRAND,
@@ -136,7 +136,7 @@ __export(external_exports, {
136
136
  void: () => voidType
137
137
  });
138
138
 
139
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/helpers/util.js
139
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/helpers/util.js
140
140
  var util;
141
141
  (function(util2) {
142
142
  util2.assertEqual = (_) => {
@@ -270,7 +270,7 @@ var getParsedType = (data) => {
270
270
  }
271
271
  };
272
272
 
273
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/ZodError.js
273
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/ZodError.js
274
274
  var ZodIssueCode = util.arrayToEnum([
275
275
  "invalid_type",
276
276
  "invalid_literal",
@@ -388,7 +388,7 @@ ZodError.create = (issues) => {
388
388
  return error;
389
389
  };
390
390
 
391
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/locales/en.js
391
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/locales/en.js
392
392
  var errorMap = (issue, _ctx) => {
393
393
  let message;
394
394
  switch (issue.code) {
@@ -491,7 +491,7 @@ var errorMap = (issue, _ctx) => {
491
491
  };
492
492
  var en_default = errorMap;
493
493
 
494
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/errors.js
494
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/errors.js
495
495
  var overrideErrorMap = en_default;
496
496
  function setErrorMap(map) {
497
497
  overrideErrorMap = map;
@@ -500,7 +500,7 @@ function getErrorMap() {
500
500
  return overrideErrorMap;
501
501
  }
502
502
 
503
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/helpers/parseUtil.js
503
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/helpers/parseUtil.js
504
504
  var makeIssue = (params) => {
505
505
  const { data, path, errorMaps, issueData } = params;
506
506
  const fullPath = [...path, ...issueData.path || []];
@@ -610,14 +610,14 @@ var isDirty = (x) => x.status === "dirty";
610
610
  var isValid = (x) => x.status === "valid";
611
611
  var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
612
612
 
613
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/helpers/errorUtil.js
613
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/helpers/errorUtil.js
614
614
  var errorUtil;
615
615
  (function(errorUtil2) {
616
616
  errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
617
617
  errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
618
618
  })(errorUtil || (errorUtil = {}));
619
619
 
620
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/types.js
620
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/types.js
621
621
  var ParseInputLazyPath = class {
622
622
  constructor(parent, value, path, key) {
623
623
  this._cachedPath = [];
@@ -4065,7 +4065,7 @@ var coerce = {
4065
4065
  };
4066
4066
  var NEVER = INVALID;
4067
4067
 
4068
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/@tscircuit/mm/dist/index.js
4068
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/@tscircuit/mm/dist/index.js
4069
4069
  var unitToMm = {
4070
4070
  in: 25.4,
4071
4071
  inch: 25.4,
@@ -4092,9 +4092,9 @@ var mm = (n) => {
4092
4092
  throw new Error(`Unsupported unit: ${unit}`);
4093
4093
  };
4094
4094
 
4095
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/index.js
4095
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/index.js
4096
4096
  function normalizeNemaMotorModelString(value) {
4097
- if (!/^nema(?:8|17|23)(?:_|$)/i.test(value)) return value;
4097
+ if (!/^nema(?:8|17|23|34)(?:_|$)/i.test(value)) return value;
4098
4098
  return value.replace(/(^|_)jst([0-9]+)_(ph|sh)(?=_|$)/gi, "$1jst$3$2").replace(/(^|_)jst[_-](ph|sh)[_-]([0-9]+)(?=_|$)/gi, "$1jst$2$3").replace(/(^|_)none(?=_|$)/gi, "$1nowires").replace(/(^|_)stubs(?=_|$)/gi, "$1wirestubs");
4099
4099
  }
4100
4100
  function splitModelStringTokens(value) {
@@ -4783,7 +4783,8 @@ var hexSocketBoltModelDefinitionSchema = external_exports.object({
4783
4783
  var nemaSizeSchema = external_exports.union([
4784
4784
  external_exports.literal(8),
4785
4785
  external_exports.literal(17),
4786
- external_exports.literal(23)
4786
+ external_exports.literal(23),
4787
+ external_exports.literal(34)
4787
4788
  ]);
4788
4789
  var nemaMotorDimensions = {
4789
4790
  8: {
@@ -4851,6 +4852,31 @@ var nemaMotorDimensions = {
4851
4852
  rearCapLength: 5,
4852
4853
  faceCornerChamfer: 2,
4853
4854
  bodyCornerChamfer: 15
4855
+ },
4856
+ 34: {
4857
+ // Illustrative rear details; independent of the mounting flange.
4858
+ backFaceHoleSpacing: 40,
4859
+ rearCornerChamfer: 24,
4860
+ backFaceScrewSize: "M5",
4861
+ backFaceHoleDepth: 6,
4862
+ bodyWidth: 86,
4863
+ bodyLength: 80,
4864
+ mountingHoleSpacing: 69.6,
4865
+ mountingHoleDiameter: 6.5,
4866
+ mountingHoleDepth: 10,
4867
+ mountingHoleThrough: true,
4868
+ pilotDiameter: 73,
4869
+ pilotLength: 1.6,
4870
+ shaftDiameter: 14,
4871
+ shaftLength: 32,
4872
+ shaftShape: "round",
4873
+ shaftFlatDepth: 0.5,
4874
+ shaftFlatLength: 15,
4875
+ shaftFlatAngle: 0,
4876
+ frontCapLength: 10,
4877
+ rearCapLength: 8,
4878
+ faceCornerChamfer: 2,
4879
+ bodyCornerChamfer: 24
4854
4880
  }
4855
4881
  };
4856
4882
  var shape3 = {
@@ -4889,7 +4915,10 @@ var shape3 = {
4889
4915
  frontCapLength: positiveModelLengthSchema.optional(),
4890
4916
  rearCapLength: positiveModelLengthSchema.optional(),
4891
4917
  faceCornerChamfer: nonnegativeModelLengthSchema.optional(),
4892
- bodyCornerChamfer: nonnegativeModelLengthSchema.optional()
4918
+ bodyCornerChamfer: nonnegativeModelLengthSchema.optional(),
4919
+ /** Rear outline is independent of the front mounting flange. */
4920
+ rearCornerChamfer: nonnegativeModelLengthSchema.optional(),
4921
+ cornerProfile: external_exports.enum(["chamfered", "stepped"]).optional()
4893
4922
  };
4894
4923
  var resolve = (p) => {
4895
4924
  const d = nemaMotorDimensions[p.nemaSize];
@@ -4898,12 +4927,12 @@ var resolve = (p) => {
4898
4927
  return {
4899
4928
  nemaSize: p.nemaSize,
4900
4929
  wireConnection: p.wireConnection ?? "stubs",
4901
- wireSideAngle: ((p.wireSideAngle ?? 0) % 360 + 360) % 360,
4902
- wireLength: p.wireLength ?? 6,
4903
- wireDiameter: p.wireDiameter ?? 1.2,
4930
+ wireSideAngle: ((p.wireSideAngle ?? (p.nemaSize === 34 ? 90 : 0)) % 360 + 360) % 360,
4931
+ wireLength: p.wireLength ?? (p.nemaSize === 34 ? 25 : 6),
4932
+ wireDiameter: p.wireDiameter ?? (p.nemaSize === 34 ? 2 : 1.2),
4904
4933
  wireCount: p.wireCount ?? 4,
4905
- backFace: p.backFace ?? "screws",
4906
- backFaceHoleSpacing: p.backFaceHoleSpacing ?? p.mountingHoleSpacing ?? d.mountingHoleSpacing,
4934
+ backFace: p.backFace ?? (p.nemaSize === 34 ? "plain" : "screws"),
4935
+ backFaceHoleSpacing: p.backFaceHoleSpacing ?? ("backFaceHoleSpacing" in d ? d.backFaceHoleSpacing : p.mountingHoleSpacing ?? d.mountingHoleSpacing),
4907
4936
  backFaceHoleDiameter: p.backFaceHoleDiameter ?? screw.diameter,
4908
4937
  backFaceHoleDepth: p.backFaceHoleDepth ?? d.backFaceHoleDepth,
4909
4938
  backFaceScrewSize,
@@ -4924,17 +4953,23 @@ var resolve = (p) => {
4924
4953
  frontCapLength: p.frontCapLength ?? d.frontCapLength,
4925
4954
  rearCapLength: p.rearCapLength ?? d.rearCapLength,
4926
4955
  faceCornerChamfer: p.faceCornerChamfer ?? d.faceCornerChamfer,
4927
- bodyCornerChamfer: p.bodyCornerChamfer ?? d.bodyCornerChamfer
4956
+ bodyCornerChamfer: p.bodyCornerChamfer ?? d.bodyCornerChamfer,
4957
+ ...p.nemaSize === 34 || p.cornerProfile !== void 0 ? { cornerProfile: p.cornerProfile ?? "stepped" } : {},
4958
+ ..."rearCornerChamfer" in d || p.rearCornerChamfer !== void 0 ? {
4959
+ rearCornerChamfer: p.rearCornerChamfer ?? ("rearCornerChamfer" in d ? d.rearCornerChamfer : p.faceCornerChamfer ?? d.faceCornerChamfer)
4960
+ } : {}
4928
4961
  };
4929
4962
  };
4930
4963
  var validate3 = (p, ctx) => {
4931
4964
  const issue = (message) => ctx.addIssue({ code: "custom", message });
4965
+ const rearChamfer = p.rearCornerChamfer ?? (p.backFace === "plain" && p.mountingHoleThrough ? p.bodyCornerChamfer : p.faceCornerChamfer);
4966
+ const rearEdge = p.cornerProfile === "stepped" ? rearChamfer / Math.SQRT2 : rearChamfer;
4932
4967
  if (p.backFace !== "plain") {
4933
4968
  const screw = hexSocketBoltDimensions[p.backFaceScrewSize];
4934
4969
  const radius = (p.backFace === "screws" ? Math.max(p.backFaceHoleDiameter, screw.headDiameter) : p.backFaceHoleDiameter) / 2;
4935
4970
  if (p.backFaceHoleSpacing <= 2 * radius)
4936
4971
  issue("Rear holes and screw heads must not overlap each other");
4937
- if (p.backFaceHoleSpacing + 2 * radius >= p.bodyWidth || p.bodyWidth - p.faceCornerChamfer - p.backFaceHoleSpacing <= radius * Math.SQRT2)
4972
+ if (p.backFaceHoleSpacing + 2 * radius >= p.bodyWidth || (p.cornerProfile === "stepped" ? p.backFaceHoleSpacing + 2 * radius >= p.bodyWidth - 2 * rearEdge : p.bodyWidth - rearChamfer - p.backFaceHoleSpacing <= radius * Math.SQRT2))
4938
4973
  issue("Rear holes and screw heads must fit entirely inside the rear face");
4939
4974
  if (p.backFaceHoleDepth >= p.rearCapLength)
4940
4975
  issue("Rear hole depth must be less than the rear cap length");
@@ -4942,18 +4977,18 @@ var validate3 = (p, ctx) => {
4942
4977
  issue("Rear holes must accommodate the screw diameter");
4943
4978
  }
4944
4979
  if (p.wireConnection === "stubs") {
4945
- if (p.wireDiameter * p.wireCount * 1.5 > p.bodyWidth - 2 * p.faceCornerChamfer)
4980
+ if (p.wireDiameter * p.wireCount * 1.5 > p.bodyWidth - 2 * rearEdge)
4946
4981
  issue("Wire bundle must fit on the cap side");
4947
4982
  if (p.wireDiameter >= p.rearCapLength)
4948
4983
  issue("Wire diameter must fit within the rear cap");
4949
4984
  }
4950
4985
  const connector = getJstMotorConnector(p.wireConnection);
4951
- if (connector && p.bodyWidth - 2 * p.faceCornerChamfer < connector.bodyWidth)
4986
+ if (connector && p.bodyWidth - 2 * rearEdge < connector.bodyWidth)
4952
4987
  issue("JST header must fit on the motor side");
4953
4988
  const r = p.mountingHoleDiameter / 2;
4954
4989
  if (p.frontCapLength + p.rearCapLength >= p.bodyLength)
4955
4990
  issue("End caps must leave a positive body length");
4956
- if (p.faceCornerChamfer >= p.bodyWidth / 2 || p.bodyCornerChamfer >= p.bodyWidth / 2)
4991
+ if (p.faceCornerChamfer >= p.bodyWidth / 2 || p.bodyCornerChamfer >= p.bodyWidth / 2 || rearChamfer >= p.bodyWidth / 2)
4957
4992
  issue("Chamfer must be smaller than half the body width");
4958
4993
  if (p.mountingHoleSpacing + 2 * r >= p.bodyWidth || p.bodyWidth - p.faceCornerChamfer - p.mountingHoleSpacing <= r * Math.SQRT2)
4959
4994
  issue("Mounting holes must fit entirely inside the front face");
@@ -4965,7 +5000,7 @@ var validate3 = (p, ctx) => {
4965
5000
  issue("Mounting holes must clear the pilot");
4966
5001
  if (!p.mountingHoleThrough && p.mountingHoleDepth >= p.frontCapLength)
4967
5002
  issue("Blind mounting hole depth must be less than the front cap length");
4968
- if (p.mountingHoleThrough && p.bodyWidth - p.bodyCornerChamfer - p.mountingHoleSpacing >= -r * Math.SQRT2)
5003
+ if (p.mountingHoleThrough && (p.cornerProfile === "stepped" ? p.bodyWidth / 2 - p.bodyCornerChamfer / Math.SQRT2 + Math.min(4, p.bodyCornerChamfer / Math.SQRT2 / 4) >= p.mountingHoleSpacing / 2 - r : p.bodyWidth - p.bodyCornerChamfer - p.mountingHoleSpacing >= -r * Math.SQRT2))
4969
5004
  issue("Body must clear through front mounting holes");
4970
5005
  if (p.shaftLength <= p.pilotLength)
4971
5006
  issue("Shaft tip must extend beyond the pilot");
@@ -4998,12 +5033,13 @@ var lengths2 = {
4998
5033
  frontcap: "frontCapLength",
4999
5034
  rearcap: "rearCapLength",
5000
5035
  facechamfer: "faceCornerChamfer",
5001
- bodychamfer: "bodyCornerChamfer"
5036
+ bodychamfer: "bodyCornerChamfer",
5037
+ rearchamfer: "rearCornerChamfer"
5002
5038
  };
5003
5039
  function parseNemaMotorModelParams(raw) {
5004
5040
  const tokens = normalizeNemaMotorModelString(raw.string).split("_");
5005
- const match = tokens[0]?.match(/^nema(8|17|23)$/i);
5006
- if (!match) throw new Error("Expected nema8, nema17 or nema23");
5041
+ const match = tokens[0]?.match(/^nema(8|17|23|34)$/i);
5042
+ if (!match) throw new Error("Expected nema8, nema17, nema23 or nema34");
5007
5043
  const props = {
5008
5044
  fn: "nema",
5009
5045
  nemaSize: Number(match[1])
@@ -5026,6 +5062,10 @@ function parseNemaMotorModelParams(raw) {
5026
5062
  throw new Error(`Invalid wire connection token "${token}"`);
5027
5063
  property = "wireConnection";
5028
5064
  parsed = isJst ? `jst-${name.slice(3)}-${value}` : name === "nowires" ? "none" : "stubs";
5065
+ } else if (name === "stepped" || name === "chamfered") {
5066
+ if (value) throw new Error(`NEMA flag "${name}" does not accept a value`);
5067
+ property = "cornerProfile";
5068
+ parsed = name;
5029
5069
  } else if (name === "wirecount") {
5030
5070
  property = "wireCount";
5031
5071
  if (!/^\d+$/.test(value)) throw new Error("wirecount requires an integer");
@@ -11636,10 +11676,32 @@ function getNemaMotorReferencePoints(input) {
11636
11676
  const p = nemaMotorModelPropsSchema.parse(input);
11637
11677
  const radians = p.wireSideAngle * Math.PI / 180;
11638
11678
  const x = Math.cos(radians), y = Math.sin(radians);
11639
- const radius = Math.min(
11679
+ let radius = Math.min(
11640
11680
  p.bodyWidth / 2 / Math.max(Math.abs(x), Math.abs(y)),
11641
11681
  (p.bodyWidth - p.faceCornerChamfer) / (Math.abs(x) + Math.abs(y))
11642
11682
  );
11683
+ if (p.nemaSize === 34 && p.cornerProfile === "stepped") {
11684
+ const h2 = p.bodyWidth / 2, c = p.bodyCornerChamfer / Math.SQRT2, r = Math.min(4, c / 4);
11685
+ const contains = (distance2) => {
11686
+ const a = Math.abs(distance2 * x), b = Math.abs(distance2 * y);
11687
+ if (a > h2 || b > h2) return false;
11688
+ if (c === 0) return true;
11689
+ if (a > h2 - c && b > h2 - c)
11690
+ return a <= h2 - c + r && b <= h2 - c + r && Math.hypot(a - (h2 - c + r), b - (h2 - c + r)) >= r;
11691
+ if (b > h2 - r && a > h2 - c - r)
11692
+ return Math.hypot(a - (h2 - c - r), b - (h2 - r)) <= r;
11693
+ if (a > h2 - r && b > h2 - c - r)
11694
+ return Math.hypot(a - (h2 - r), b - (h2 - c - r)) <= r;
11695
+ return true;
11696
+ };
11697
+ let low = 0, high = p.bodyWidth;
11698
+ for (let i = 0; i < 50; i++) {
11699
+ const mid = (low + high) / 2;
11700
+ if (contains(mid)) low = mid;
11701
+ else high = mid;
11702
+ }
11703
+ radius = low;
11704
+ }
11643
11705
  const flatRadians = p.shaftFlatAngle * Math.PI / 180;
11644
11706
  return {
11645
11707
  frontface: {
@@ -11658,7 +11720,7 @@ function getNemaMotorReferencePoints(input) {
11658
11720
  position: {
11659
11721
  x: radius * x,
11660
11722
  y: radius * y,
11661
- z: -p.bodyLength + p.rearCapLength / 2
11723
+ z: p.nemaSize === 34 ? -p.bodyLength + p.rearCapLength + 3 : -p.bodyLength + p.rearCapLength / 2
11662
11724
  },
11663
11725
  direction: { x, y, z: 0 }
11664
11726
  },
@@ -15707,11 +15769,66 @@ function register71(registry2) {
15707
15769
  registry2.register(model71);
15708
15770
  }
15709
15771
 
15772
+ // lib/utils/nemaMotorAssemblyGeometry.ts
15773
+ import jscad6 from "@jscad/modeling";
15774
+ function nema34AssemblyCenters(p) {
15775
+ const edge = p.bodyWidth / 2;
15776
+ return [-1, 1].flatMap(
15777
+ (side) => [-1, 1].map(
15778
+ (end) => [side * (edge - 3.5), end * p.bodyWidth * 0.26]
15779
+ )
15780
+ );
15781
+ }
15782
+ function cutNema34FrontRecesses(geometry, p) {
15783
+ return jscad6.booleans.subtract(
15784
+ geometry,
15785
+ ...nema34AssemblyCenters(p).flatMap(([x, y]) => [
15786
+ jscad6.primitives.cylinder({
15787
+ radius: 1.6,
15788
+ height: p.frontCapLength + 0.2,
15789
+ center: [x, y, -p.frontCapLength / 2],
15790
+ segments: 32
15791
+ }),
15792
+ jscad6.primitives.cylinder({
15793
+ radius: 5,
15794
+ height: Math.min(4, p.frontCapLength / 2) + 0.1,
15795
+ center: [
15796
+ Math.sign(x) * p.bodyWidth / 2,
15797
+ y,
15798
+ -Math.min(4, p.frontCapLength / 2) / 2 + 0.05
15799
+ ],
15800
+ segments: 48
15801
+ })
15802
+ ])
15803
+ );
15804
+ }
15805
+ function createNema34FrontScrews(p) {
15806
+ const head = jscad6.booleans.subtract(
15807
+ jscad6.primitives.ellipsoid({
15808
+ radius: [3.2, 3.2, 1.5],
15809
+ center: [0, 0, -1.8],
15810
+ segments: 32
15811
+ }),
15812
+ ...[
15813
+ [3.7, 0.8, 1.1],
15814
+ [0.8, 3.7, 1.1]
15815
+ ].map(
15816
+ (size) => jscad6.primitives.cuboid({
15817
+ size,
15818
+ center: [0, 0, -0.8]
15819
+ })
15820
+ )
15821
+ );
15822
+ return nema34AssemblyCenters(p).map(
15823
+ ([x, y]) => jscad6.transforms.translate([x, y, 0], head)
15824
+ );
15825
+ }
15826
+
15710
15827
  // lib/NemaMotor.tsx
15711
- import jscad7 from "@jscad/modeling";
15828
+ import jscad8 from "@jscad/modeling";
15712
15829
 
15713
15830
  // lib/utils/nemaMotorWireGeometry.ts
15714
- import jscad6 from "@jscad/modeling";
15831
+ import jscad7 from "@jscad/modeling";
15715
15832
 
15716
15833
  // lib/utils/nemaMotorParameters.ts
15717
15834
  var resolveNemaMotorProps = nemaMotorModelPropsSchema.parse.bind(nemaMotorModelPropsSchema);
@@ -15722,9 +15839,9 @@ function createNemaMotorWireGeometry(input) {
15722
15839
  if (p.wireConnection === "none") return [];
15723
15840
  const { position } = getNemaMotorReferencePoints(p).wireside;
15724
15841
  const angle = p.wireSideAngle * Math.PI / 180;
15725
- const place = (geometry) => jscad6.transforms.translate(
15842
+ const place = (geometry) => jscad7.transforms.translate(
15726
15843
  [position.x, position.y, position.z],
15727
- jscad6.transforms.rotateZ(angle, geometry)
15844
+ jscad7.transforms.rotateZ(angle, geometry)
15728
15845
  );
15729
15846
  if (p.wireConnection === "stubs") {
15730
15847
  const colors = [
@@ -15737,18 +15854,18 @@ function createNemaMotorWireGeometry(input) {
15737
15854
  "#ce7432",
15738
15855
  "#803e91"
15739
15856
  ];
15740
- return Array.from({ length: p.wireCount }, (_, i) => ({
15857
+ const wires = Array.from({ length: p.wireCount }, (_, i) => ({
15741
15858
  color: colors[i],
15742
15859
  geometry: place(
15743
- jscad6.transforms.translate(
15860
+ jscad7.transforms.translate(
15744
15861
  [
15745
15862
  (p.wireLength - 0.15) / 2,
15746
15863
  (i - (p.wireCount - 1) / 2) * p.wireDiameter * 1.5,
15747
15864
  0
15748
15865
  ],
15749
- jscad6.transforms.rotateY(
15866
+ jscad7.transforms.rotateY(
15750
15867
  Math.PI / 2,
15751
- jscad6.primitives.cylinder({
15868
+ jscad7.primitives.cylinder({
15752
15869
  height: p.wireLength + 0.15,
15753
15870
  radius: p.wireDiameter / 2,
15754
15871
  segments: 24
@@ -15757,18 +15874,31 @@ function createNemaMotorWireGeometry(input) {
15757
15874
  )
15758
15875
  )
15759
15876
  }));
15877
+ if (p.nemaSize === 34)
15878
+ wires.unshift({
15879
+ color: "#252830",
15880
+ geometry: place(
15881
+ jscad7.primitives.roundedCuboid({
15882
+ size: [3, p.wireCount * p.wireDiameter * 1.5 + 3, 6],
15883
+ center: [0.8, 0, 0],
15884
+ roundRadius: 1,
15885
+ segments: 24
15886
+ })
15887
+ )
15888
+ });
15889
+ return wires;
15760
15890
  }
15761
15891
  const connector = getJstMotorConnector(p.wireConnection);
15762
15892
  const { pinCount, pitch, bodyWidth, bodyHeight, matingDepth } = connector;
15763
15893
  const wall = pitch === 2 ? 0.6 : 0.3;
15764
15894
  const contactLength = pitch === 2 ? 3.4 : 2.4;
15765
15895
  const contactSize = pitch === 2 ? 0.5 : 0.3;
15766
- const shell = jscad6.booleans.subtract(
15767
- jscad6.primitives.cuboid({
15896
+ const shell = jscad7.booleans.subtract(
15897
+ jscad7.primitives.cuboid({
15768
15898
  size: [matingDepth + 0.1, bodyWidth, bodyHeight],
15769
15899
  center: [(matingDepth - 0.1) / 2, 0, 0]
15770
15900
  }),
15771
- jscad6.primitives.cuboid({
15901
+ jscad7.primitives.cuboid({
15772
15902
  size: [matingDepth - 0.5, bodyWidth - 2 * wall, bodyHeight - 2 * wall],
15773
15903
  center: [matingDepth / 2 + 0.55, 0, 0]
15774
15904
  })
@@ -15778,7 +15908,7 @@ function createNemaMotorWireGeometry(input) {
15778
15908
  ...Array.from({ length: pinCount }, (_, i) => ({
15779
15909
  color: "#b8bec6",
15780
15910
  geometry: place(
15781
- jscad6.primitives.cuboid({
15911
+ jscad7.primitives.cuboid({
15782
15912
  size: [contactLength, contactSize, contactSize],
15783
15913
  center: [contactLength / 2, (i - (pinCount - 1) / 2) * pitch, 0]
15784
15914
  })
@@ -15812,14 +15942,59 @@ var face = (width10, chamfer) => {
15812
15942
  [-h2, -h2 + c]
15813
15943
  ];
15814
15944
  };
15945
+ var roundedFace = (width10, radius) => {
15946
+ if (radius === 0) return face(width10, 0);
15947
+ const center = width10 / 2 - radius;
15948
+ return [0, 1, 2, 3].flatMap(
15949
+ (corner) => Array.from({ length: 13 }, (_, i) => {
15950
+ const angle = i * Math.PI / 24, rotation = corner * Math.PI / 2;
15951
+ const x = center + radius * Math.cos(angle), y = center + radius * Math.sin(angle);
15952
+ return [
15953
+ x * Math.cos(rotation) - y * Math.sin(rotation),
15954
+ x * Math.sin(rotation) + y * Math.cos(rotation)
15955
+ ];
15956
+ })
15957
+ );
15958
+ };
15959
+ var steppedFace = (width10, chamfer) => {
15960
+ if (chamfer === 0) return face(width10, 0);
15961
+ const h2 = width10 / 2, c = chamfer / Math.SQRT2, r = Math.min(4, c / 4);
15962
+ const corner = [];
15963
+ const arc = (x, y, from, to) => {
15964
+ for (let i = 0; i <= 12; i++) {
15965
+ const a = (from + (to - from) * i / 12) * Math.PI / 180;
15966
+ corner.push([x + r * Math.cos(a), y + r * Math.sin(a)]);
15967
+ }
15968
+ };
15969
+ arc(h2 - c - r, h2 - r, 90, 0);
15970
+ arc(h2 - c + r, h2 - c + r, 180, 270);
15971
+ arc(h2 - r, h2 - c - r, 90, 0);
15972
+ return [0, 1, 2, 3].flatMap(
15973
+ (i) => corner.map(([x, y]) => {
15974
+ const a = -i * Math.PI / 2;
15975
+ return [
15976
+ x * Math.cos(a) - y * Math.sin(a),
15977
+ x * Math.sin(a) + y * Math.cos(a)
15978
+ ];
15979
+ })
15980
+ ).reverse();
15981
+ };
15815
15982
  function createNemaMotorSections(input) {
15816
15983
  const p = resolveNemaMotorProps(input);
15817
15984
  const sections = [];
15818
15985
  const add = (name, outline, zMin, zMax, holes2 = []) => {
15819
15986
  if (zMax > zMin) sections.push({ name, outline, holes: holes2, zMin, zMax });
15820
15987
  };
15821
- const front = face(p.bodyWidth, p.faceCornerChamfer);
15822
- const core = face(p.bodyWidth, p.bodyCornerChamfer);
15988
+ const front = (p.nemaSize === 34 ? roundedFace : face)(
15989
+ p.bodyWidth,
15990
+ p.faceCornerChamfer
15991
+ );
15992
+ const profile6 = p.cornerProfile === "stepped" ? steppedFace : face;
15993
+ const core = profile6(p.bodyWidth, p.bodyCornerChamfer);
15994
+ const rear = profile6(
15995
+ p.bodyWidth,
15996
+ p.rearCornerChamfer ?? (p.backFace === "plain" && p.mountingHoleThrough ? p.bodyCornerChamfer : p.faceCornerChamfer)
15997
+ );
15823
15998
  const h2 = p.mountingHoleSpacing / 2;
15824
15999
  const centers = [
15825
16000
  [-h2, -h2],
@@ -15835,12 +16010,7 @@ function createNemaMotorSections(input) {
15835
16010
  add("frontCap", front, -p.frontCapLength, -holeDepth);
15836
16011
  add("body", core, -p.bodyLength + p.rearCapLength, -p.frontCapLength);
15837
16012
  if (p.backFace === "plain") {
15838
- add(
15839
- "rearCap",
15840
- p.mountingHoleThrough ? core : front,
15841
- -p.bodyLength,
15842
- -p.bodyLength + p.rearCapLength
15843
- );
16013
+ add("rearCap", rear, -p.bodyLength, -p.bodyLength + p.rearCapLength);
15844
16014
  } else {
15845
16015
  const halfPitch = p.backFaceHoleSpacing / 2;
15846
16016
  const rearHoles = [-halfPitch, halfPitch].flatMap(
@@ -15850,14 +16020,14 @@ function createNemaMotorSections(input) {
15850
16020
  );
15851
16021
  add(
15852
16022
  "rearCap",
15853
- front,
16023
+ rear,
15854
16024
  -p.bodyLength,
15855
16025
  -p.bodyLength + p.backFaceHoleDepth,
15856
16026
  rearHoles
15857
16027
  );
15858
16028
  add(
15859
16029
  "rearCap",
15860
- front,
16030
+ rear,
15861
16031
  -p.bodyLength + p.backFaceHoleDepth,
15862
16032
  -p.bodyLength + p.rearCapLength
15863
16033
  );
@@ -15870,12 +16040,12 @@ function createNemaMotorSections(input) {
15870
16040
  else {
15871
16041
  const cut = r - p.shaftFlatDepth;
15872
16042
  const angle = Math.acos(cut / r);
15873
- const profile6 = Array.from({ length: 97 }, (_, i) => {
16043
+ const profile7 = Array.from({ length: 97 }, (_, i) => {
15874
16044
  const a = angle + (2 * Math.PI - 2 * angle) * i / 96;
15875
16045
  return [r * Math.cos(a), r * Math.sin(a)];
15876
16046
  });
15877
16047
  const rotation = p.shaftFlatAngle * Math.PI / 180;
15878
- const d = profile6.map(([x, y]) => [
16048
+ const d = profile7.map(([x, y]) => [
15879
16049
  x * Math.cos(rotation) - y * Math.sin(rotation),
15880
16050
  x * Math.sin(rotation) + y * Math.cos(rotation)
15881
16051
  ]);
@@ -15886,7 +16056,7 @@ function createNemaMotorSections(input) {
15886
16056
  }
15887
16057
 
15888
16058
  // lib/NemaMotor.tsx
15889
- var generalize3 = jscad7.modifiers.generalize;
16059
+ var generalize3 = jscad8.modifiers.generalize;
15890
16060
  function NemaMotor({
15891
16061
  bodyColor = "#242830",
15892
16062
  capColor = "#aeb5bd",
@@ -15895,7 +16065,7 @@ function NemaMotor({
15895
16065
  ...props
15896
16066
  }) {
15897
16067
  const p = resolveNemaMotorProps(props);
15898
- const screw = p.backFace === "screws" ? jscad7.transforms.rotateX(
16068
+ const screw = p.backFace === "screws" ? jscad8.transforms.rotateX(
15899
16069
  Math.PI,
15900
16070
  createHexSocketBoltGeom({
15901
16071
  metricSize: p.backFaceScrewSize,
@@ -15906,18 +16076,20 @@ function NemaMotor({
15906
16076
  const halfPitch = p.backFaceHoleSpacing / 2;
15907
16077
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
15908
16078
  createNemaMotorSections(p).map((section, index) => {
15909
- const outline = jscad7.geometries.geom2.fromPoints(section.outline);
15910
- const profile6 = section.holes.length ? jscad7.booleans.subtract(
16079
+ const outline = jscad8.geometries.geom2.fromPoints(section.outline);
16080
+ const profile6 = section.holes.length ? jscad8.booleans.subtract(
15911
16081
  outline,
15912
- ...section.holes.map((h2) => jscad7.geometries.geom2.fromPoints(h2))
16082
+ ...section.holes.map((h2) => jscad8.geometries.geom2.fromPoints(h2))
15913
16083
  ) : outline;
15914
- const geometry = jscad7.transforms.translate(
16084
+ let geometry = jscad8.transforms.translate(
15915
16085
  [0, 0, section.zMin],
15916
- jscad7.extrusions.extrudeLinear(
16086
+ jscad8.extrusions.extrudeLinear(
15917
16087
  { height: section.zMax - section.zMin },
15918
16088
  profile6
15919
16089
  )
15920
16090
  );
16091
+ if (p.nemaSize === 34 && section.name === "frontCap")
16092
+ geometry = cutNema34FrontRecesses(geometry, p);
15921
16093
  return /* @__PURE__ */ jsx(
15922
16094
  Colorize,
15923
16095
  {
@@ -15937,6 +16109,15 @@ function NemaMotor({
15937
16109
  },
15938
16110
  `wire-${index}`
15939
16111
  )),
16112
+ p.nemaSize === 34 && createNema34FrontScrews(p).map((geometry, index) => /* @__PURE__ */ jsx(
16113
+ Colorize,
16114
+ {
16115
+ material: componentMaterials.steel,
16116
+ color: screwColor,
16117
+ children: /* @__PURE__ */ jsx(Custom, { geometry: generalize3({ simplify: true }, geometry) })
16118
+ },
16119
+ `front-screw-${index}`
16120
+ )),
15940
16121
  screw && [-halfPitch, halfPitch].flatMap(
15941
16122
  (x) => [-halfPitch, halfPitch].map((y) => /* @__PURE__ */ jsx(
15942
16123
  Colorize,
@@ -15946,7 +16127,7 @@ function NemaMotor({
15946
16127
  children: /* @__PURE__ */ jsx(
15947
16128
  Custom,
15948
16129
  {
15949
- geometry: jscad7.transforms.translate(
16130
+ geometry: jscad8.transforms.translate(
15950
16131
  [x, y, -p.bodyLength],
15951
16132
  generalize3({ simplify: true }, screw)
15952
16133
  )
@@ -15961,6 +16142,7 @@ function NemaMotor({
15961
16142
  var NEMA8 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 8 });
15962
16143
  var NEMA17 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 17 });
15963
16144
  var NEMA23 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 23 });
16145
+ var NEMA34 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 34 });
15964
16146
 
15965
16147
  // lib/models/nema/register.tsx
15966
16148
  var model72 = defineModelRenderer({
@@ -16330,7 +16512,7 @@ function register74(registry2) {
16330
16512
  }
16331
16513
 
16332
16514
  // lib/models/perforatedsheet/geometry.ts
16333
- import jscad8 from "@jscad/modeling";
16515
+ import jscad9 from "@jscad/modeling";
16334
16516
  var {
16335
16517
  booleans,
16336
16518
  primitives: primitives3,
@@ -16338,7 +16520,7 @@ var {
16338
16520
  geometries: geometries3,
16339
16521
  modifiers: modifiers3,
16340
16522
  measurements: measurements3
16341
- } = jscad8;
16523
+ } = jscad9;
16342
16524
  var generalize4 = modifiers3.generalize;
16343
16525
  var { subtract } = booleans;
16344
16526
  var { rectangle: rectangle3, roundedRectangle: roundedRectangle3, circle: circle2 } = primitives3;
@@ -16486,8 +16668,8 @@ function register76(registry2) {
16486
16668
  }
16487
16669
 
16488
16670
  // lib/models/pushfitplug/geometry.ts
16489
- import jscad9 from "@jscad/modeling";
16490
- var { primitives: primitives4, extrusions: extrusions4, geometries: geometries4, modifiers: modifiers4, measurements: measurements4 } = jscad9;
16671
+ import jscad10 from "@jscad/modeling";
16672
+ var { primitives: primitives4, extrusions: extrusions4, geometries: geometries4, modifiers: modifiers4, measurements: measurements4 } = jscad10;
16491
16673
  var generalize5 = modifiers4.generalize;
16492
16674
  var { rectangle: rectangle4, roundedRectangle: roundedRectangle4, polygon: polygon3 } = primitives4;
16493
16675
  function createPushFitPlugGeom(input) {
@@ -16558,8 +16740,8 @@ function register77(registry2) {
16558
16740
  }
16559
16741
 
16560
16742
  // lib/models/rectangularbar/geometry.ts
16561
- import jscad10 from "@jscad/modeling";
16562
- var { primitives: primitives5, extrusions: extrusions5, geometries: geometries5, modifiers: modifiers5, measurements: measurements5 } = jscad10;
16743
+ import jscad11 from "@jscad/modeling";
16744
+ var { primitives: primitives5, extrusions: extrusions5, geometries: geometries5, modifiers: modifiers5, measurements: measurements5 } = jscad11;
16563
16745
  var generalize6 = modifiers5.generalize;
16564
16746
  var { rectangle: rectangle5, roundedRectangle: roundedRectangle5 } = primitives5;
16565
16747
  var profile4 = (shape44, height10) => extrusions5.extrudeLinear({ height: height10 }, shape44);
@@ -16736,7 +16918,7 @@ function register79(registry2) {
16736
16918
  }
16737
16919
 
16738
16920
  // lib/models/rectangulartube/geometry.ts
16739
- import jscad11 from "@jscad/modeling";
16921
+ import jscad12 from "@jscad/modeling";
16740
16922
  var {
16741
16923
  booleans: booleans2,
16742
16924
  primitives: primitives6,
@@ -16744,7 +16926,7 @@ var {
16744
16926
  geometries: geometries6,
16745
16927
  modifiers: modifiers6,
16746
16928
  measurements: measurements6
16747
- } = jscad11;
16929
+ } = jscad12;
16748
16930
  var generalize7 = modifiers6.generalize;
16749
16931
  var { subtract: subtract2 } = booleans2;
16750
16932
  var { rectangle: rectangle6, roundedRectangle: roundedRectangle6 } = primitives6;
@@ -17729,7 +17911,7 @@ function register91(registry2) {
17729
17911
  }
17730
17912
 
17731
17913
  // lib/models/tslotcoverstrip/geometry.ts
17732
- import jscad14 from "@jscad/modeling";
17914
+ import jscad15 from "@jscad/modeling";
17733
17915
  var {
17734
17916
  primitives: primitives7,
17735
17917
  extrusions: extrusions7,
@@ -17737,7 +17919,7 @@ var {
17737
17919
  geometries: geometries7,
17738
17920
  modifiers: modifiers7,
17739
17921
  measurements: measurements7
17740
- } = jscad14;
17922
+ } = jscad15;
17741
17923
  var generalize8 = modifiers7.generalize;
17742
17924
  function createTSlotCoverStripGeom(input) {
17743
17925
  const p = tSlotCoverStripModelPropsSchema.parse(input);
@@ -26755,8 +26937,8 @@ function renderNode(node, colorCtx, renderCtx) {
26755
26937
  }
26756
26938
  return (children ?? []).flatMap((c) => renderNode(c, colorCtx, renderCtx));
26757
26939
  }
26758
- function render(root, jscad15) {
26759
- const geometries8 = renderNode(root, void 0, { jscad: jscad15 });
26940
+ function render(root, jscad16) {
26941
+ const geometries8 = renderNode(root, void 0, { jscad: jscad16 });
26760
26942
  return {
26761
26943
  geometries: geometries8.map(
26762
26944
  (entry) => entry.material ? { ...entry, geom: { ...entry.geom, material: entry.material } } : entry
@@ -26848,24 +27030,24 @@ function convertCSGToThreeGeom(csg) {
26848
27030
  }
26849
27031
 
26850
27032
  // lib/vanilla/index.ts
26851
- function getJscadModelForFootprint(footprint, jscad15) {
27033
+ function getJscadModelForFootprint(footprint, jscad16) {
26852
27034
  const vnode = h(Footprinter3d, { footprint });
26853
- return render(vnode, jscad15);
27035
+ return render(vnode, jscad16);
26854
27036
  }
26855
- function getJscadModelForFootprintWithPads(footprint, jscad15) {
27037
+ function getJscadModelForFootprintWithPads(footprint, jscad16) {
26856
27038
  const vnode = h(
26857
27039
  Fragment,
26858
27040
  {},
26859
27041
  h(Footprinter3d, { footprint }),
26860
27042
  h(ExtrudedPads, { footprint })
26861
27043
  );
26862
- return render(vnode, jscad15);
27044
+ return render(vnode, jscad16);
26863
27045
  }
26864
- function createJSCADRenderer(jscad15) {
27046
+ function createJSCADRenderer(jscad16) {
26865
27047
  function createJSCADRoot(container) {
26866
27048
  return {
26867
27049
  render(element) {
26868
- const { geometries: geometries8 } = render(element, jscad15);
27050
+ const { geometries: geometries8 } = render(element, jscad16);
26869
27051
  container.splice(0, container.length, ...geometries8);
26870
27052
  }
26871
27053
  };
@@ -26897,6 +27079,7 @@ export {
26897
27079
  MaleFemaleStandoff,
26898
27080
  NEMA17,
26899
27081
  NEMA23,
27082
+ NEMA34,
26900
27083
  NEMA8,
26901
27084
  NemaMotor,
26902
27085
  NylonLockNut,