jscad-electronics 0.0.223 → 0.0.228

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/a0c3adcab6538807c2f328e983467915c62ee778-v2/node_modules/zod/v3/external.js
27
+ // .model-contracts/generations/a2cdaa0ea42c20364c601d990971fef4f4e234fc-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/a0c3adcab6538807c2f328e983467915c62ee778-v2/node_modules/zod/v3/helpers/util.js
139
+ // .model-contracts/generations/a2cdaa0ea42c20364c601d990971fef4f4e234fc-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/a0c3adcab6538807c2f328e983467915c62ee778-v2/node_modules/zod/v3/ZodError.js
273
+ // .model-contracts/generations/a2cdaa0ea42c20364c601d990971fef4f4e234fc-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/a0c3adcab6538807c2f328e983467915c62ee778-v2/node_modules/zod/v3/locales/en.js
391
+ // .model-contracts/generations/a2cdaa0ea42c20364c601d990971fef4f4e234fc-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/a0c3adcab6538807c2f328e983467915c62ee778-v2/node_modules/zod/v3/errors.js
494
+ // .model-contracts/generations/a2cdaa0ea42c20364c601d990971fef4f4e234fc-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/a0c3adcab6538807c2f328e983467915c62ee778-v2/node_modules/zod/v3/helpers/parseUtil.js
503
+ // .model-contracts/generations/a2cdaa0ea42c20364c601d990971fef4f4e234fc-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/a0c3adcab6538807c2f328e983467915c62ee778-v2/node_modules/zod/v3/helpers/errorUtil.js
613
+ // .model-contracts/generations/a2cdaa0ea42c20364c601d990971fef4f4e234fc-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/a0c3adcab6538807c2f328e983467915c62ee778-v2/node_modules/zod/v3/types.js
620
+ // .model-contracts/generations/a2cdaa0ea42c20364c601d990971fef4f4e234fc-v2/node_modules/zod/v3/types.js
621
621
  var ParseInputLazyPath = class {
622
622
  constructor(parent, value, path, key) {
623
623
  this._cachedPath = [];
@@ -2402,9 +2402,9 @@ var ZodObject = class _ZodObject extends ZodType {
2402
2402
  _getCached() {
2403
2403
  if (this._cached !== null)
2404
2404
  return this._cached;
2405
- const shape33 = this._def.shape();
2406
- const keys = util.objectKeys(shape33);
2407
- this._cached = { shape: shape33, keys };
2405
+ const shape39 = this._def.shape();
2406
+ const keys = util.objectKeys(shape39);
2407
+ this._cached = { shape: shape39, keys };
2408
2408
  return this._cached;
2409
2409
  }
2410
2410
  _parse(input) {
@@ -2419,7 +2419,7 @@ var ZodObject = class _ZodObject extends ZodType {
2419
2419
  return INVALID;
2420
2420
  }
2421
2421
  const { status, ctx } = this._processInputParams(input);
2422
- const { shape: shape33, keys: shapeKeys } = this._getCached();
2422
+ const { shape: shape39, keys: shapeKeys } = this._getCached();
2423
2423
  const extraKeys = [];
2424
2424
  if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {
2425
2425
  for (const key in ctx.data) {
@@ -2430,7 +2430,7 @@ var ZodObject = class _ZodObject extends ZodType {
2430
2430
  }
2431
2431
  const pairs = [];
2432
2432
  for (const key of shapeKeys) {
2433
- const keyValidator = shape33[key];
2433
+ const keyValidator = shape39[key];
2434
2434
  const value = ctx.data[key];
2435
2435
  pairs.push({
2436
2436
  key: { status: "valid", value: key },
@@ -2636,27 +2636,27 @@ var ZodObject = class _ZodObject extends ZodType {
2636
2636
  });
2637
2637
  }
2638
2638
  pick(mask) {
2639
- const shape33 = {};
2639
+ const shape39 = {};
2640
2640
  for (const key of util.objectKeys(mask)) {
2641
2641
  if (mask[key] && this.shape[key]) {
2642
- shape33[key] = this.shape[key];
2642
+ shape39[key] = this.shape[key];
2643
2643
  }
2644
2644
  }
2645
2645
  return new _ZodObject({
2646
2646
  ...this._def,
2647
- shape: () => shape33
2647
+ shape: () => shape39
2648
2648
  });
2649
2649
  }
2650
2650
  omit(mask) {
2651
- const shape33 = {};
2651
+ const shape39 = {};
2652
2652
  for (const key of util.objectKeys(this.shape)) {
2653
2653
  if (!mask[key]) {
2654
- shape33[key] = this.shape[key];
2654
+ shape39[key] = this.shape[key];
2655
2655
  }
2656
2656
  }
2657
2657
  return new _ZodObject({
2658
2658
  ...this._def,
2659
- shape: () => shape33
2659
+ shape: () => shape39
2660
2660
  });
2661
2661
  }
2662
2662
  /**
@@ -2703,27 +2703,27 @@ var ZodObject = class _ZodObject extends ZodType {
2703
2703
  return createZodEnum(util.objectKeys(this.shape));
2704
2704
  }
2705
2705
  };
2706
- ZodObject.create = (shape33, params) => {
2706
+ ZodObject.create = (shape39, params) => {
2707
2707
  return new ZodObject({
2708
- shape: () => shape33,
2708
+ shape: () => shape39,
2709
2709
  unknownKeys: "strip",
2710
2710
  catchall: ZodNever.create(),
2711
2711
  typeName: ZodFirstPartyTypeKind.ZodObject,
2712
2712
  ...processCreateParams(params)
2713
2713
  });
2714
2714
  };
2715
- ZodObject.strictCreate = (shape33, params) => {
2715
+ ZodObject.strictCreate = (shape39, params) => {
2716
2716
  return new ZodObject({
2717
- shape: () => shape33,
2717
+ shape: () => shape39,
2718
2718
  unknownKeys: "strict",
2719
2719
  catchall: ZodNever.create(),
2720
2720
  typeName: ZodFirstPartyTypeKind.ZodObject,
2721
2721
  ...processCreateParams(params)
2722
2722
  });
2723
2723
  };
2724
- ZodObject.lazycreate = (shape33, params) => {
2724
+ ZodObject.lazycreate = (shape39, params) => {
2725
2725
  return new ZodObject({
2726
- shape: shape33,
2726
+ shape: shape39,
2727
2727
  unknownKeys: "strip",
2728
2728
  catchall: ZodNever.create(),
2729
2729
  typeName: ZodFirstPartyTypeKind.ZodObject,
@@ -4065,7 +4065,7 @@ var coerce = {
4065
4065
  };
4066
4066
  var NEVER = INVALID;
4067
4067
 
4068
- // .model-contracts/generations/a0c3adcab6538807c2f328e983467915c62ee778-v2/node_modules/@tscircuit/mm/dist/index.js
4068
+ // .model-contracts/generations/a2cdaa0ea42c20364c601d990971fef4f4e234fc-v2/node_modules/@tscircuit/mm/dist/index.js
4069
4069
  var unitToMm = {
4070
4070
  in: 25.4,
4071
4071
  inch: 25.4,
@@ -4092,7 +4092,7 @@ var mm = (n) => {
4092
4092
  throw new Error(`Unsupported unit: ${unit}`);
4093
4093
  };
4094
4094
 
4095
- // .model-contracts/generations/a0c3adcab6538807c2f328e983467915c62ee778-v2/index.js
4095
+ // .model-contracts/generations/a2cdaa0ea42c20364c601d990971fef4f4e234fc-v2/index.js
4096
4096
  function normalizeNemaMotorModelString(value) {
4097
4097
  if (!/^nema(?:8|17|23)(?:_|$)/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");
@@ -4178,55 +4178,55 @@ var stringFlags = {
4178
4178
  male: "threadgender(male)"
4179
4179
  };
4180
4180
  var omittedStringFlags = ["righthanded", "male"];
4181
- function defineModel(model392) {
4182
- return model392;
4181
+ function defineModel(model452) {
4182
+ return model452;
4183
4183
  }
4184
4184
  var ModelRegistry = class {
4185
4185
  models = /* @__PURE__ */ new Map();
4186
- register(model392) {
4187
- if (typeof model392.name !== "string" || !/^[a-z]+$/.test(model392.name)) {
4186
+ register(model452) {
4187
+ if (typeof model452.name !== "string" || !/^[a-z]+$/.test(model452.name)) {
4188
4188
  throw new Error("Model names must contain only lowercase letters");
4189
4189
  }
4190
- if (this.models.has(model392.name)) {
4190
+ if (this.models.has(model452.name)) {
4191
4191
  throw new Error(
4192
- `Modelprinter function "${model392.name}" is already registered`
4192
+ `Modelprinter function "${model452.name}" is already registered`
4193
4193
  );
4194
4194
  }
4195
- if (model392.normalizeString !== void 0 && typeof model392.normalizeString !== "function")
4195
+ if (model452.normalizeString !== void 0 && typeof model452.normalizeString !== "function")
4196
4196
  throw new Error("Model string normalizer must be a function");
4197
- this.models.set(model392.name, {
4198
- name: model392.name,
4199
- schema: model392.schema,
4200
- parse: model392.parse,
4201
- normalizeString: model392.normalizeString
4197
+ this.models.set(model452.name, {
4198
+ name: model452.name,
4199
+ schema: model452.schema,
4200
+ parse: model452.parse,
4201
+ normalizeString: model452.normalizeString
4202
4202
  });
4203
4203
  }
4204
4204
  getModelNames() {
4205
4205
  return [...this.models.keys()];
4206
4206
  }
4207
4207
  normalize(params) {
4208
- const model392 = this.models.get(params.fn);
4209
- if (!model392?.normalizeString) return params;
4210
- const value = model392.normalizeString(params.string);
4208
+ const model452 = this.models.get(params.fn);
4209
+ if (!model452?.normalizeString) return params;
4210
+ const value = model452.normalizeString(params.string);
4211
4211
  if (typeof value !== "string")
4212
- throw new Error(`Normalizer for "${model392.name}" must return a string`);
4212
+ throw new Error(`Normalizer for "${model452.name}" must return a string`);
4213
4213
  if (value === params.string) return params;
4214
4214
  const normalized = parseModelStringParams(value);
4215
- if (normalized.fn !== model392.name)
4215
+ if (normalized.fn !== model452.name)
4216
4216
  throw new Error(
4217
- `Normalizer for "${model392.name}" must preserve the model name`
4217
+ `Normalizer for "${model452.name}" must preserve the model name`
4218
4218
  );
4219
4219
  return normalized;
4220
4220
  }
4221
4221
  parse(params) {
4222
- const model392 = this.models.get(params.fn);
4223
- if (!model392) {
4222
+ const model452 = this.models.get(params.fn);
4223
+ if (!model452) {
4224
4224
  throw new Error(`Unsupported modelprinter function "${params.fn}"`);
4225
4225
  }
4226
- const definition = model392.parse(params);
4227
- if (definition === null || typeof definition !== "object" || Array.isArray(definition) || definition.fn !== model392.name) {
4226
+ const definition = model452.parse(params);
4227
+ if (definition === null || typeof definition !== "object" || Array.isArray(definition) || definition.fn !== model452.name) {
4228
4228
  throw new Error(
4229
- `Parser for "${model392.name}" must return a model with fn "${model392.name}"`
4229
+ `Parser for "${model452.name}" must return a model with fn "${model452.name}"`
4230
4230
  );
4231
4231
  }
4232
4232
  return definition;
@@ -5091,7 +5091,7 @@ var sheetMetalShape = {
5091
5091
  };
5092
5092
  var sheetMetalModelPropsSchema = external_exports.object(sheetMetalShape).strict();
5093
5093
  var sheetMetalModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("sheetmetal"), ...sheetMetalShape }).strict();
5094
- function parseSheetMetalFeature(feature, profile) {
5094
+ function parseSheetMetalFeature(feature, profile6) {
5095
5095
  const match = feature.match(/^(hole|slot)[1-9]\d*\(([^()]+)\)$/);
5096
5096
  if (!match) throw new Error(`Invalid sheet metal feature "${feature}"`);
5097
5097
  const kind = match[1];
@@ -5124,8 +5124,8 @@ function parseSheetMetalFeature(feature, profile) {
5124
5124
  if (faces.length !== 1)
5125
5125
  throw new Error(`Specify exactly one face in ${feature}`);
5126
5126
  const face2 = faces[0];
5127
- if (face2 === "angledface" && profile !== "angle" || ["leftface", "rightface"].includes(face2) && profile !== "channel")
5128
- throw new Error(`No ${face2} on ${profile}`);
5127
+ if (face2 === "angledface" && profile6 !== "angle" || ["leftface", "rightface"].includes(face2) && profile6 !== "channel")
5128
+ throw new Error(`No ${face2} on ${profile6}`);
5129
5129
  for (const [a, b] of [
5130
5130
  ["leftofcenter", "rightofcenter"],
5131
5131
  ["abovecenter", "belowcenter"],
@@ -5155,12 +5155,12 @@ function parseSheetMetalFeature(feature, profile) {
5155
5155
  }
5156
5156
  if (!("l" in values) || !("w" in values))
5157
5157
  throw new Error(`Slot requires l and w in ${feature}`);
5158
- const length20 = distance2("l"), width10 = distance2("w");
5159
- if (length20 < width10) throw new Error("Slot length must be at least its width");
5158
+ const length26 = distance2("l"), width10 = distance2("w");
5159
+ if (length26 < width10) throw new Error("Slot length must be at least its width");
5160
5160
  return sheetMetalHoleSchema.parse({
5161
5161
  ...position,
5162
5162
  shape: "slot",
5163
- length: length20,
5163
+ length: length26,
5164
5164
  width: width10,
5165
5165
  axis: panel === "base" === !("vertical" in values) ? "u" : "v"
5166
5166
  });
@@ -5363,9 +5363,9 @@ var flexScreenModelPropsSchema = external_exports.object(flexScreenModelPropsSha
5363
5363
  var flexScreenModelDefinitionSchema = external_exports.object({
5364
5364
  fn: external_exports.literal("flexscreen"),
5365
5365
  ...flexScreenModelPropsShape
5366
- }).strict().superRefine((model392, context) => {
5367
- validateTailLengths(model392, context);
5368
- addOrientationShortcutIssue(model392, (path) => {
5366
+ }).strict().superRefine((model452, context) => {
5367
+ validateTailLengths(model452, context);
5368
+ addOrientationShortcutIssue(model452, (path) => {
5369
5369
  context.addIssue({
5370
5370
  code: "custom",
5371
5371
  message: "Only one FlexScreen orientation shortcut can be true",
@@ -5868,6 +5868,90 @@ var model9 = defineModel({
5868
5868
  function register9(registry2) {
5869
5869
  registry2.register(model9);
5870
5870
  }
5871
+ var length2 = external_exports.union([
5872
+ external_exports.number(),
5873
+ external_exports.string().regex(/^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
5874
+ ]).pipe(modelLengthSchema);
5875
+ var positiveLength = length2.refine(
5876
+ (value) => value > 0,
5877
+ "Length must be positive"
5878
+ );
5879
+ var nonnegativeLength = length2.refine(
5880
+ (value) => value >= 0,
5881
+ "Length cannot be negative"
5882
+ );
5883
+ var shape6 = {
5884
+ width: positiveLength,
5885
+ height: positiveLength,
5886
+ thickness: positiveLength,
5887
+ length: positiveLength,
5888
+ innerRadius: nonnegativeLength.default(0),
5889
+ tipRadius: nonnegativeLength.default(0)
5890
+ };
5891
+ function validate6(p, context) {
5892
+ if (p.thickness >= Math.min(p.width, p.height))
5893
+ context.addIssue({
5894
+ code: "custom",
5895
+ message: "Invalid anglebar dimensions: constraint 1"
5896
+ });
5897
+ if (p.innerRadius >= Math.min(p.width, p.height) - p.thickness)
5898
+ context.addIssue({
5899
+ code: "custom",
5900
+ message: "Invalid anglebar dimensions: constraint 2"
5901
+ });
5902
+ if (2 * p.tipRadius >= p.thickness)
5903
+ context.addIssue({
5904
+ code: "custom",
5905
+ message: "Invalid anglebar dimensions: constraint 3"
5906
+ });
5907
+ if (p.innerRadius + p.tipRadius >= Math.min(p.width, p.height) - p.thickness)
5908
+ context.addIssue({
5909
+ code: "custom",
5910
+ message: "Invalid anglebar dimensions: constraint 4"
5911
+ });
5912
+ }
5913
+ var angleBarModelPropsSchema = external_exports.object(shape6).strict().superRefine(validate6);
5914
+ var angleBarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("anglebar"), ...shape6 }).strict().superRefine(validate6);
5915
+ var aliases2 = {
5916
+ w: "width",
5917
+ h: "height",
5918
+ t: "thickness",
5919
+ l: "length",
5920
+ innerr: "innerRadius",
5921
+ tipr: "tipRadius",
5922
+ width: "width",
5923
+ height: "height",
5924
+ thickness: "thickness",
5925
+ length: "length",
5926
+ innerradius: "innerRadius",
5927
+ tipradius: "tipRadius"
5928
+ };
5929
+ function parseAngleBarModelParams(raw) {
5930
+ const [name, ...tokens] = splitModelStringTokens(raw.string);
5931
+ if (raw.fn !== "anglebar" || name?.toLowerCase() !== "anglebar")
5932
+ throw new Error("Expected anglebar without inline values");
5933
+ const props = { fn: "anglebar" };
5934
+ for (const token of tokens) {
5935
+ const match = token.match(/^([a-z]+)(.*)$/i);
5936
+ const key = match?.[1]?.toLowerCase();
5937
+ const value = match?.[2];
5938
+ if (!key || !Object.hasOwn(aliases2, key) || !value)
5939
+ throw new Error(`Unknown or malformed anglebar token "${token}"`);
5940
+ const property = aliases2[key];
5941
+ if (Object.hasOwn(props, property))
5942
+ throw new Error(`Duplicate anglebar property "${property}"`);
5943
+ props[property] = value;
5944
+ }
5945
+ return angleBarModelDefinitionSchema.parse(props);
5946
+ }
5947
+ var model10 = defineModel({
5948
+ name: "anglebar",
5949
+ schema: angleBarModelDefinitionSchema,
5950
+ parse: parseAngleBarModelParams
5951
+ });
5952
+ function register10(registry2) {
5953
+ registry2.register(model10);
5954
+ }
5871
5955
  var ballBearingStandardSizes = {
5872
5956
  "608": { innerDiameter: 8, outerDiameter: 22, width: 7 },
5873
5957
  "625": { innerDiameter: 5, outerDiameter: 16, width: 5 },
@@ -5889,14 +5973,14 @@ var ballBearingCodeSchema = external_exports.enum([
5889
5973
  "6001",
5890
5974
  "6002"
5891
5975
  ]);
5892
- var positiveLength = external_exports.union([
5976
+ var positiveLength2 = external_exports.union([
5893
5977
  external_exports.number(),
5894
5978
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
5895
5979
  ]).pipe(modelLengthSchema).refine((value) => value > 0, "Length must be positive");
5896
- var shape6 = {
5897
- innerDiameter: positiveLength.optional(),
5898
- outerDiameter: positiveLength.optional(),
5899
- width: positiveLength.optional(),
5980
+ var shape7 = {
5981
+ innerDiameter: positiveLength2.optional(),
5982
+ outerDiameter: positiveLength2.optional(),
5983
+ width: positiveLength2.optional(),
5900
5984
  code: ballBearingCodeSchema.optional(),
5901
5985
  bothSidesOpen: external_exports.boolean().optional(),
5902
5986
  bothSidesShielded: external_exports.boolean().optional(),
@@ -5958,8 +6042,8 @@ function resolve2(input, context) {
5958
6042
  });
5959
6043
  return props;
5960
6044
  }
5961
- var ballBearingModelPropsSchema = external_exports.object(shape6).strict().transform(resolve2);
5962
- var ballBearingModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("ballbearing"), ...shape6 }).strict().transform((input, context) => ({ fn: input.fn, ...resolve2(input, context) }));
6045
+ var ballBearingModelPropsSchema = external_exports.object(shape7).strict().transform(resolve2);
6046
+ var ballBearingModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("ballbearing"), ...shape7 }).strict().transform((input, context) => ({ fn: input.fn, ...resolve2(input, context) }));
5963
6047
  function getBallBearingDimensions(input = {}) {
5964
6048
  const props = ballBearingModelPropsSchema.parse(input);
5965
6049
  const boreRadius = props.innerDiameter / 2;
@@ -6094,14 +6178,14 @@ function normalizeBallBearingModelString(value) {
6094
6178
  const faces = top === bottom ? `bothsides${top}` : `topside${top}_bottomside${bottom}`;
6095
6179
  return `ballbearing_id${decimal(props.innerDiameter)}mm_od${decimal(props.outerDiameter)}mm_w${decimal(props.width)}mm_${faces}`;
6096
6180
  }
6097
- var model10 = defineModel({
6181
+ var model11 = defineModel({
6098
6182
  name: "ballbearing",
6099
6183
  schema: ballBearingModelDefinitionSchema,
6100
6184
  parse: parseBallBearingModelParams,
6101
6185
  normalizeString: normalizeBallBearingModelString
6102
6186
  });
6103
- function register10(registry2) {
6104
- registry2.register(model10);
6187
+ function register11(registry2) {
6188
+ registry2.register(model11);
6105
6189
  }
6106
6190
  var ballTransferUnitDefaults = {
6107
6191
  ballDiameter: 25,
@@ -6115,19 +6199,19 @@ var ballTransferUnitDefaults = {
6115
6199
  socketClearance: 0.25,
6116
6200
  faceThreeHole: true
6117
6201
  };
6118
- var length2 = external_exports.union([
6202
+ var length3 = external_exports.union([
6119
6203
  external_exports.number().finite(),
6120
6204
  external_exports.string().regex(
6121
6205
  /^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i,
6122
6206
  "Expected a complete length with a supported unit"
6123
6207
  ).transform((value) => value.toLowerCase())
6124
6208
  ]).pipe(modelLengthSchema);
6125
- var positive2 = length2.refine((value) => value > 0, "Length must be positive");
6126
- var nonnegative = length2.refine(
6209
+ var positive2 = length3.refine((value) => value > 0, "Length must be positive");
6210
+ var nonnegative = length3.refine(
6127
6211
  (value) => value >= 0,
6128
6212
  "Length cannot be negative"
6129
6213
  );
6130
- var shape7 = {
6214
+ var shape8 = {
6131
6215
  ballDiameter: positive2.default(ballTransferUnitDefaults.ballDiameter),
6132
6216
  bodyDiameter: positive2.default(ballTransferUnitDefaults.bodyDiameter),
6133
6217
  /** Overall height from the flat body bottom to the load-ball top. */
@@ -6145,7 +6229,7 @@ var shape7 = {
6145
6229
  ),
6146
6230
  faceThreeHole: external_exports.literal(true).default(true)
6147
6231
  };
6148
- function validate6(props, context) {
6232
+ function validate7(props, context) {
6149
6233
  const issue = (path, message) => context.addIssue({ code: "custom", path: [path], message });
6150
6234
  const ballRadius = props.ballDiameter / 2;
6151
6235
  const socketRadius = ballRadius + props.socketClearance;
@@ -6174,8 +6258,8 @@ function validate6(props, context) {
6174
6258
  if (props.holeDiameter >= props.pitchCircleDiameter * Math.sqrt(3) / 2)
6175
6259
  issue("holeDiameter", "Mounting holes must not intersect one another");
6176
6260
  }
6177
- var ballTransferUnitModelPropsSchema = external_exports.object(shape7).strict().superRefine(validate6);
6178
- var ballTransferUnitModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("balltransferunit"), ...shape7 }).strict().superRefine(validate6);
6261
+ var ballTransferUnitModelPropsSchema = external_exports.object(shape8).strict().superRefine(validate7);
6262
+ var ballTransferUnitModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("balltransferunit"), ...shape8 }).strict().superRefine(validate7);
6179
6263
  function getBallTransferUnitDimensions(input = {}) {
6180
6264
  const props = ballTransferUnitModelPropsSchema.parse(input);
6181
6265
  const ballRadius = props.ballDiameter / 2;
@@ -6252,13 +6336,13 @@ function parseBallTransferUnitModelParams(raw) {
6252
6336
  }
6253
6337
  return ballTransferUnitModelDefinitionSchema.parse(props);
6254
6338
  }
6255
- var model11 = defineModel({
6339
+ var model12 = defineModel({
6256
6340
  name: "balltransferunit",
6257
6341
  schema: ballTransferUnitModelDefinitionSchema,
6258
6342
  parse: parseBallTransferUnitModelParams
6259
6343
  });
6260
- function register11(registry2) {
6261
- registry2.register(model11);
6344
+ function register12(registry2) {
6345
+ registry2.register(model12);
6262
6346
  }
6263
6347
  var stringFlags2 = {
6264
6348
  hexsocket: "drive(hexsocket)",
@@ -6316,24 +6400,24 @@ var buttonScrewDimensions = {
6316
6400
  referenceThreadLength: 24
6317
6401
  }
6318
6402
  };
6319
- var length3 = external_exports.union([
6403
+ var length4 = external_exports.union([
6320
6404
  external_exports.number(),
6321
6405
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
6322
6406
  ]).pipe(modelLengthSchema).refine((value) => value > 0, "Length must be positive");
6323
6407
  var buttonScrewMetricSizeSchema = external_exports.enum(["M3", "M4", "M5", "M6"]);
6324
- var shape8 = {
6408
+ var shape9 = {
6325
6409
  iso73801: external_exports.literal(true).default(true),
6326
6410
  metricSize: buttonScrewMetricSizeSchema,
6327
6411
  /** Under-head length; this family supports short fully threaded screws only. */
6328
- length: length3,
6412
+ length: length4,
6329
6413
  drive: external_exports.literal("hexsocket").default("hexsocket"),
6330
6414
  thread: external_exports.literal("full").default("full"),
6331
- threadPitch: length3.optional(),
6415
+ threadPitch: length4.optional(),
6332
6416
  threadHand: external_exports.literal("right").default("right"),
6333
6417
  threadClass: external_exports.literal("6g").default("6g"),
6334
6418
  showThreads: external_exports.boolean().default(true)
6335
6419
  };
6336
- function validate7(props, context) {
6420
+ function validate8(props, context) {
6337
6421
  const dimensions5 = buttonScrewDimensions[props.metricSize];
6338
6422
  if (props.threadPitch !== void 0 && Math.abs(props.threadPitch - dimensions5.threadPitch) > 1e-9)
6339
6423
  context.addIssue({
@@ -6360,8 +6444,8 @@ function normalize(props) {
6360
6444
  threadPitch: buttonScrewDimensions[props.metricSize].threadPitch
6361
6445
  };
6362
6446
  }
6363
- var buttonScrewModelPropsSchema = external_exports.object(shape8).strict().superRefine(validate7).transform(normalize);
6364
- var buttonScrewModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("buttonscrew"), ...shape8 }).strict().superRefine(validate7).transform(normalize);
6447
+ var buttonScrewModelPropsSchema = external_exports.object(shape9).strict().superRefine(validate8).transform(normalize);
6448
+ var buttonScrewModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("buttonscrew"), ...shape9 }).strict().superRefine(validate8).transform(normalize);
6365
6449
  function getButtonScrewDimensions(input) {
6366
6450
  const props = buttonScrewModelPropsSchema.parse(input);
6367
6451
  const dims = buttonScrewDimensions[props.metricSize];
@@ -6435,7 +6519,7 @@ function parseButtonScrewModelParams(raw) {
6435
6519
  }
6436
6520
  return buttonScrewModelDefinitionSchema.parse(props);
6437
6521
  }
6438
- var model12 = defineModel({
6522
+ var model13 = defineModel({
6439
6523
  name: "buttonscrew",
6440
6524
  schema: buttonScrewModelDefinitionSchema,
6441
6525
  parse: parseButtonScrewModelParams,
@@ -6446,31 +6530,31 @@ var model12 = defineModel({
6446
6530
  omittedStringFlags2
6447
6531
  )
6448
6532
  });
6449
- function register12(registry2) {
6450
- registry2.register(model12);
6533
+ function register13(registry2) {
6534
+ registry2.register(model13);
6451
6535
  }
6452
6536
  var stringFlags3 = {
6453
6537
  symmetricring: "shape(symmetricring)"
6454
6538
  };
6455
6539
  var omittedStringFlags3 = [];
6456
- var length4 = external_exports.union([
6540
+ var length5 = external_exports.union([
6457
6541
  external_exports.number(),
6458
6542
  external_exports.string().regex(
6459
6543
  /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i,
6460
6544
  "Expected a complete numeric length with an optional unit"
6461
6545
  )
6462
6546
  ]).pipe(positiveModelLengthSchema);
6463
- var shape9 = {
6464
- panelHoleDiameter: length4,
6465
- innerDiameter: length4,
6466
- outerDiameter: length4,
6467
- height: length4,
6468
- grooveWidth: length4,
6547
+ var shape10 = {
6548
+ panelHoleDiameter: length5,
6549
+ innerDiameter: length5,
6550
+ outerDiameter: length5,
6551
+ height: length5,
6552
+ grooveWidth: length5,
6469
6553
  /** Radial recess from the flange outside diameter. */
6470
- grooveDepth: length4,
6554
+ grooveDepth: length5,
6471
6555
  shape: external_exports.literal("symmetricring").default("symmetricring")
6472
6556
  };
6473
- function validate8(props, context) {
6557
+ function validate9(props, context) {
6474
6558
  if (props.innerDiameter >= props.panelHoleDiameter || props.panelHoleDiameter >= props.outerDiameter)
6475
6559
  context.addIssue({
6476
6560
  code: "custom",
@@ -6497,8 +6581,8 @@ function validate8(props, context) {
6497
6581
  message: "Derived root wall and flange thicknesses must be positive"
6498
6582
  });
6499
6583
  }
6500
- var cableGrommetModelPropsSchema = external_exports.object(shape9).strict().superRefine(validate8);
6501
- var cableGrommetModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("cablegrommet"), ...shape9 }).strict().superRefine(validate8);
6584
+ var cableGrommetModelPropsSchema = external_exports.object(shape10).strict().superRefine(validate9);
6585
+ var cableGrommetModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("cablegrommet"), ...shape10 }).strict().superRefine(validate9);
6502
6586
  function getCableGrommetDimensions(input) {
6503
6587
  const props = cableGrommetModelPropsSchema.parse(input);
6504
6588
  const grooveRootDiameter = props.outerDiameter - 2 * props.grooveDepth;
@@ -6551,7 +6635,7 @@ function parseCableGrommetModelParams(raw) {
6551
6635
  }
6552
6636
  return cableGrommetModelDefinitionSchema.parse(props);
6553
6637
  }
6554
- var model13 = defineModel({
6638
+ var model14 = defineModel({
6555
6639
  name: "cablegrommet",
6556
6640
  schema: cableGrommetModelDefinitionSchema,
6557
6641
  parse: parseCableGrommetModelParams,
@@ -6562,8 +6646,100 @@ var model13 = defineModel({
6562
6646
  omittedStringFlags3
6563
6647
  )
6564
6648
  });
6565
- function register13(registry2) {
6566
- registry2.register(model13);
6649
+ function register14(registry2) {
6650
+ registry2.register(model14);
6651
+ }
6652
+ var length6 = external_exports.union([
6653
+ external_exports.number(),
6654
+ external_exports.string().regex(/^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
6655
+ ]).pipe(modelLengthSchema);
6656
+ var positiveLength3 = length6.refine(
6657
+ (value) => value > 0,
6658
+ "Length must be positive"
6659
+ );
6660
+ var nonnegativeLength2 = length6.refine(
6661
+ (value) => value >= 0,
6662
+ "Length cannot be negative"
6663
+ );
6664
+ var shape11 = {
6665
+ width: positiveLength3,
6666
+ height: positiveLength3,
6667
+ webThickness: positiveLength3,
6668
+ flangeThickness: positiveLength3,
6669
+ length: positiveLength3,
6670
+ innerRadius: nonnegativeLength2.default(0),
6671
+ tipRadius: nonnegativeLength2.default(0)
6672
+ };
6673
+ function validate10(p, context) {
6674
+ if (2 * p.flangeThickness >= p.width)
6675
+ context.addIssue({
6676
+ code: "custom",
6677
+ message: "Invalid channelbar dimensions: constraint 1"
6678
+ });
6679
+ if (p.webThickness >= p.height)
6680
+ context.addIssue({
6681
+ code: "custom",
6682
+ message: "Invalid channelbar dimensions: constraint 2"
6683
+ });
6684
+ if (2 * p.innerRadius >= p.width - 2 * p.flangeThickness)
6685
+ context.addIssue({
6686
+ code: "custom",
6687
+ message: "Invalid channelbar dimensions: constraint 3"
6688
+ });
6689
+ if (p.innerRadius + p.tipRadius >= p.height - p.webThickness)
6690
+ context.addIssue({
6691
+ code: "custom",
6692
+ message: "Invalid channelbar dimensions: constraint 4"
6693
+ });
6694
+ if (2 * p.tipRadius >= p.flangeThickness)
6695
+ context.addIssue({
6696
+ code: "custom",
6697
+ message: "Invalid channelbar dimensions: constraint 5"
6698
+ });
6699
+ }
6700
+ var channelBarModelPropsSchema = external_exports.object(shape11).strict().superRefine(validate10);
6701
+ var channelBarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("channelbar"), ...shape11 }).strict().superRefine(validate10);
6702
+ var aliases3 = {
6703
+ w: "width",
6704
+ h: "height",
6705
+ web: "webThickness",
6706
+ flange: "flangeThickness",
6707
+ l: "length",
6708
+ innerr: "innerRadius",
6709
+ tipr: "tipRadius",
6710
+ width: "width",
6711
+ height: "height",
6712
+ webthickness: "webThickness",
6713
+ flangethickness: "flangeThickness",
6714
+ length: "length",
6715
+ innerradius: "innerRadius",
6716
+ tipradius: "tipRadius"
6717
+ };
6718
+ function parseChannelBarModelParams(raw) {
6719
+ const [name, ...tokens] = splitModelStringTokens(raw.string);
6720
+ if (raw.fn !== "channelbar" || name?.toLowerCase() !== "channelbar")
6721
+ throw new Error("Expected channelbar without inline values");
6722
+ const props = { fn: "channelbar" };
6723
+ for (const token of tokens) {
6724
+ const match = token.match(/^([a-z]+)(.*)$/i);
6725
+ const key = match?.[1]?.toLowerCase();
6726
+ const value = match?.[2];
6727
+ if (!key || !Object.hasOwn(aliases3, key) || !value)
6728
+ throw new Error(`Unknown or malformed channelbar token "${token}"`);
6729
+ const property = aliases3[key];
6730
+ if (Object.hasOwn(props, property))
6731
+ throw new Error(`Duplicate channelbar property "${property}"`);
6732
+ props[property] = value;
6733
+ }
6734
+ return channelBarModelDefinitionSchema.parse(props);
6735
+ }
6736
+ var model15 = defineModel({
6737
+ name: "channelbar",
6738
+ schema: channelBarModelDefinitionSchema,
6739
+ parse: parseChannelBarModelParams
6740
+ });
6741
+ function register15(registry2) {
6742
+ registry2.register(model15);
6567
6743
  }
6568
6744
  var stringFlags4 = {
6569
6745
  singleclamp: "mount(singleclamp)",
@@ -6571,19 +6747,19 @@ var stringFlags4 = {
6571
6747
  righthanded: "threadhand(right)"
6572
6748
  };
6573
6749
  var omittedStringFlags4 = ["righthanded"];
6574
- var length5 = external_exports.union([
6750
+ var length7 = external_exports.union([
6575
6751
  external_exports.number().finite(),
6576
6752
  external_exports.string().regex(
6577
6753
  /^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i,
6578
6754
  "Expected a complete length with a supported unit"
6579
6755
  ).transform((value) => value.toLowerCase())
6580
6756
  ]).pipe(modelLengthSchema);
6581
- var positive3 = length5.refine((value) => value > 0, "Length must be positive");
6582
- var nonnegative2 = length5.refine(
6757
+ var positive3 = length7.refine((value) => value > 0, "Length must be positive");
6758
+ var nonnegative2 = length7.refine(
6583
6759
  (value) => value >= 0,
6584
6760
  "Length cannot be negative"
6585
6761
  );
6586
- var shape10 = {
6762
+ var shape12 = {
6587
6763
  boreDiameter: positive3,
6588
6764
  outerDiameter: positive3,
6589
6765
  width: positive3,
@@ -6609,7 +6785,7 @@ function resolve3(props) {
6609
6785
  clearanceHoleDiameter: props.clearanceHoleDiameter ?? threadDiameter + 0.5
6610
6786
  };
6611
6787
  }
6612
- function validate9(props, context) {
6788
+ function validate11(props, context) {
6613
6789
  const p = resolve3(props);
6614
6790
  const issue = (message) => context.addIssue({ code: "custom", message });
6615
6791
  const diameter = hexSocketBoltDimensions[p.metricSize].diameter;
@@ -6636,8 +6812,8 @@ function validate9(props, context) {
6636
6812
  if (p.clampX + radius < outerRadius && p.splitWidth / 2 >= Math.sqrt(outerRadius ** 2 - (p.clampX + radius) ** 2))
6637
6813
  issue("Split must leave material around both sides of the clamping bore");
6638
6814
  }
6639
- var clampingShaftCollarModelPropsSchema = external_exports.object(shape10).strict().superRefine(validate9).transform(resolve3);
6640
- var clampingShaftCollarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("clampingshaftcollar"), ...shape10 }).strict().superRefine(validate9).transform((props) => ({ fn: props.fn, ...resolve3(props) }));
6815
+ var clampingShaftCollarModelPropsSchema = external_exports.object(shape12).strict().superRefine(validate11).transform(resolve3);
6816
+ var clampingShaftCollarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("clampingshaftcollar"), ...shape12 }).strict().superRefine(validate11).transform((props) => ({ fn: props.fn, ...resolve3(props) }));
6641
6817
  function getClampingShaftCollarDimensions(input) {
6642
6818
  const p = clampingShaftCollarModelPropsSchema.parse(input);
6643
6819
  const threadDiameter = hexSocketBoltDimensions[p.metricSize].diameter;
@@ -6727,7 +6903,7 @@ function parseClampingShaftCollarModelParams(raw) {
6727
6903
  ...props
6728
6904
  });
6729
6905
  }
6730
- var model14 = defineModel({
6906
+ var model16 = defineModel({
6731
6907
  name: "clampingshaftcollar",
6732
6908
  schema: clampingShaftCollarModelDefinitionSchema,
6733
6909
  parse: parseClampingShaftCollarModelParams,
@@ -6738,8 +6914,8 @@ var model14 = defineModel({
6738
6914
  omittedStringFlags4
6739
6915
  )
6740
6916
  });
6741
- function register14(registry2) {
6742
- registry2.register(model14);
6917
+ function register16(registry2) {
6918
+ registry2.register(model16);
6743
6919
  }
6744
6920
  var stringFlags5 = {
6745
6921
  closedground: "ends(closedground)",
@@ -6749,16 +6925,16 @@ var stringFlags5 = {
6749
6925
  free: "state(free)"
6750
6926
  };
6751
6927
  var omittedStringFlags5 = ["righthanded", "custom", "free"];
6752
- var length6 = external_exports.union([
6928
+ var length8 = external_exports.union([
6753
6929
  external_exports.number(),
6754
6930
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
6755
6931
  ]).pipe(modelLengthSchema).refine((value) => value > 0, "Length must be positive");
6756
6932
  var turnCount = external_exports.number().int().min(1).max(Number.MAX_SAFE_INTEGER);
6757
- var shape11 = {
6933
+ var shape13 = {
6758
6934
  spec: external_exports.literal("custom").default("custom"),
6759
- outerDiameter: length6,
6760
- wireDiameter: length6,
6761
- freeLength: length6,
6935
+ outerDiameter: length8,
6936
+ wireDiameter: length8,
6937
+ freeLength: length8,
6762
6938
  totalTurns: turnCount.min(3),
6763
6939
  /** Closed-ground ends have exactly one inactive turn at each end. */
6764
6940
  activeTurns: turnCount.optional(),
@@ -6766,7 +6942,7 @@ var shape11 = {
6766
6942
  hand: external_exports.enum(["right", "left"]).default("right"),
6767
6943
  state: external_exports.literal("free").default("free")
6768
6944
  };
6769
- function validate10(props, context) {
6945
+ function validate12(props, context) {
6770
6946
  if (props.outerDiameter <= 2 * props.wireDiameter)
6771
6947
  context.addIssue({
6772
6948
  code: "custom",
@@ -6790,8 +6966,8 @@ function validate10(props, context) {
6790
6966
  function normalize2(props) {
6791
6967
  return { ...props, activeTurns: props.activeTurns ?? props.totalTurns - 2 };
6792
6968
  }
6793
- var compressionSpringModelPropsSchema = external_exports.object(shape11).strict().superRefine(validate10).transform(normalize2);
6794
- var compressionSpringModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("compressionspring"), ...shape11 }).strict().superRefine(validate10).transform(normalize2);
6969
+ var compressionSpringModelPropsSchema = external_exports.object(shape13).strict().superRefine(validate12).transform(normalize2);
6970
+ var compressionSpringModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("compressionspring"), ...shape13 }).strict().superRefine(validate12).transform(normalize2);
6795
6971
  function getCompressionSpringDimensions(input) {
6796
6972
  const props = compressionSpringModelPropsSchema.parse(input);
6797
6973
  return {
@@ -6818,8 +6994,8 @@ function getCompressionSpringCenterlinePoint(input, turn) {
6818
6994
  const radius = (props.outerDiameter - props.wireDiameter) / 2;
6819
6995
  const pitch = (props.freeLength - 2 * props.wireDiameter) / props.activeTurns;
6820
6996
  const phase = (props.hand === "right" ? 1 : -1) * 2 * Math.PI * (turn % 1);
6821
- const z43 = turn <= 1 ? props.wireDiameter * turn : turn >= props.totalTurns - 1 ? props.freeLength - props.wireDiameter * (props.totalTurns - turn) : props.wireDiameter + pitch * (turn - 1);
6822
- return { x: radius * Math.cos(phase), y: radius * Math.sin(phase), z: z43 };
6997
+ const z49 = turn <= 1 ? props.wireDiameter * turn : turn >= props.totalTurns - 1 ? props.freeLength - props.wireDiameter * (props.totalTurns - turn) : props.wireDiameter + pitch * (turn - 1);
6998
+ return { x: radius * Math.cos(phase), y: radius * Math.sin(phase), z: z49 };
6823
6999
  }
6824
7000
  function parseCompressionSpringModelParams(raw) {
6825
7001
  const tokens = splitModelStringTokens(
@@ -6866,7 +7042,7 @@ function parseCompressionSpringModelParams(raw) {
6866
7042
  }
6867
7043
  return compressionSpringModelDefinitionSchema.parse(props);
6868
7044
  }
6869
- var model15 = defineModel({
7045
+ var model17 = defineModel({
6870
7046
  name: "compressionspring",
6871
7047
  schema: compressionSpringModelDefinitionSchema,
6872
7048
  parse: parseCompressionSpringModelParams,
@@ -6877,10 +7053,10 @@ var model15 = defineModel({
6877
7053
  omittedStringFlags5
6878
7054
  )
6879
7055
  });
6880
- function register15(registry2) {
6881
- registry2.register(model15);
7056
+ function register17(registry2) {
7057
+ registry2.register(model17);
6882
7058
  }
6883
- var length7 = external_exports.union([
7059
+ var length9 = external_exports.union([
6884
7060
  external_exports.number(),
6885
7061
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
6886
7062
  ]).pipe(modelLengthSchema).refine((value) => value > 0, "Length must be positive");
@@ -6936,16 +7112,16 @@ var near = (a, b) => Math.abs(a - b) <= 1e-9;
6936
7112
  function selectedDiameter(diameter) {
6937
7113
  return diameterValues.find((value) => near(value, diameter));
6938
7114
  }
6939
- var shape12 = {
7115
+ var shape14 = {
6940
7116
  /** The pinned ISO contract is the default and cannot be disabled. */
6941
7117
  iso8734: external_exports.literal(true).default(true),
6942
- diameter: length7,
7118
+ diameter: length9,
6943
7119
  /** Overall distance between the two flat end planes, including leads. */
6944
- length: length7,
6945
- endLeadLength: length7.optional(),
7120
+ length: length9,
7121
+ endLeadLength: length9.optional(),
6946
7122
  endLeadAngle: external_exports.number().finite().positive().optional()
6947
7123
  };
6948
- function validate11(props, context) {
7124
+ function validate13(props, context) {
6949
7125
  const issue = (path, message) => context.addIssue({ code: "custom", path: [path], message });
6950
7126
  const diameter = selectedDiameter(props.diameter);
6951
7127
  if (diameter === void 0) {
@@ -6981,8 +7157,8 @@ function resolve4(props) {
6981
7157
  endLeadAngle: 15
6982
7158
  };
6983
7159
  }
6984
- var dowelPinModelPropsSchema = external_exports.object(shape12).strict().superRefine(validate11).transform(resolve4);
6985
- var dowelPinModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("dowelpin"), ...shape12 }).strict().superRefine(validate11).transform(resolve4);
7160
+ var dowelPinModelPropsSchema = external_exports.object(shape14).strict().superRefine(validate13).transform(resolve4);
7161
+ var dowelPinModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("dowelpin"), ...shape14 }).strict().superRefine(validate13).transform(resolve4);
6986
7162
  function getDowelPinDimensions(input) {
6987
7163
  const props = dowelPinModelPropsSchema.parse(input);
6988
7164
  return {
@@ -7030,13 +7206,13 @@ function parseDowelPinModelParams(raw) {
7030
7206
  }
7031
7207
  return dowelPinModelDefinitionSchema.parse(props);
7032
7208
  }
7033
- var model16 = defineModel({
7209
+ var model18 = defineModel({
7034
7210
  name: "dowelpin",
7035
7211
  schema: dowelPinModelDefinitionSchema,
7036
7212
  parse: parseDowelPinModelParams
7037
7213
  });
7038
- function register16(registry2) {
7039
- registry2.register(model16);
7214
+ function register18(registry2) {
7215
+ registry2.register(model18);
7040
7216
  }
7041
7217
  var femaleStandoffMetricDimensions = {
7042
7218
  M2: { diameter: 2, threadPitch: 0.4, acrossFlats: 4 },
@@ -7049,26 +7225,26 @@ var femaleStandoffMetricDimensions = {
7049
7225
  M10: { diameter: 10, threadPitch: 1.5, acrossFlats: 17 },
7050
7226
  M12: { diameter: 12, threadPitch: 1.75, acrossFlats: 19 }
7051
7227
  };
7052
- var length8 = external_exports.union([
7228
+ var length10 = external_exports.union([
7053
7229
  external_exports.number(),
7054
7230
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
7055
7231
  ]).pipe(modelLengthSchema);
7056
- var positiveLength2 = length8.refine(
7232
+ var positiveLength4 = length10.refine(
7057
7233
  (value) => value > 0,
7058
7234
  "Length must be positive"
7059
7235
  );
7060
- var shape13 = {
7236
+ var shape15 = {
7061
7237
  metricSize: external_exports.enum(["M2", "M2.5", "M3", "M4", "M5", "M6", "M8", "M10", "M12"]).default("M3"),
7062
- acrossFlats: positiveLength2.optional(),
7238
+ acrossFlats: positiveLength4.optional(),
7063
7239
  /** End-plane distance of the body; lower mounting face is Z=0. */
7064
- length: positiveLength2.default(10),
7065
- threadPitch: positiveLength2.optional(),
7240
+ length: positiveLength4.default(10),
7241
+ threadPitch: positiveLength4.optional(),
7066
7242
  hex: external_exports.literal(true).default(true),
7067
7243
  threadedThrough: external_exports.literal(true).default(true),
7068
7244
  leftHand: external_exports.boolean().default(false),
7069
7245
  showThreads: external_exports.boolean().default(true),
7070
7246
  /** Axial/radial 45-degree setback of the outer hex edges at both ends. */
7071
- endChamfer: length8.refine((value) => value >= 0).optional()
7247
+ endChamfer: length10.refine((value) => value >= 0).optional()
7072
7248
  };
7073
7249
  function normalize3(props) {
7074
7250
  const defaults = femaleStandoffMetricDimensions[props.metricSize];
@@ -7081,7 +7257,7 @@ function normalize3(props) {
7081
7257
  );
7082
7258
  return { ...props, acrossFlats, threadPitch, endChamfer };
7083
7259
  }
7084
- function validate12(props, context) {
7260
+ function validate14(props, context) {
7085
7261
  const resolved = normalize3(props);
7086
7262
  const diameter = femaleStandoffMetricDimensions[props.metricSize].diameter;
7087
7263
  const minor = diameter - 5 * Math.sqrt(3) / 8 * resolved.threadPitch;
@@ -7101,8 +7277,8 @@ function validate12(props, context) {
7101
7277
  "Length must leave positive thread length between the bore chamfers"
7102
7278
  );
7103
7279
  }
7104
- var femaleStandoffModelPropsSchema = external_exports.object(shape13).strict().superRefine(validate12).transform(normalize3);
7105
- var femaleStandoffModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("femalestandoff"), ...shape13 }).strict().superRefine(validate12).transform(normalize3);
7280
+ var femaleStandoffModelPropsSchema = external_exports.object(shape15).strict().superRefine(validate14).transform(normalize3);
7281
+ var femaleStandoffModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("femalestandoff"), ...shape15 }).strict().superRefine(validate14).transform(normalize3);
7106
7282
  function getFemaleStandoffDimensions(input) {
7107
7283
  const props = femaleStandoffModelPropsSchema.parse(input);
7108
7284
  const diameter = femaleStandoffMetricDimensions[props.metricSize].diameter;
@@ -7179,15 +7355,15 @@ function parseFemaleStandoffModelParams(raw) {
7179
7355
  }
7180
7356
  return femaleStandoffModelDefinitionSchema.parse(props);
7181
7357
  }
7182
- var model17 = defineModel({
7358
+ var model19 = defineModel({
7183
7359
  name: "femalestandoff",
7184
7360
  schema: femaleStandoffModelDefinitionSchema,
7185
7361
  parse: parseFemaleStandoffModelParams
7186
7362
  });
7187
- function register17(registry2) {
7188
- registry2.register(model17);
7363
+ function register19(registry2) {
7364
+ registry2.register(model19);
7189
7365
  }
7190
- var positiveLength3 = external_exports.union([
7366
+ var positiveLength5 = external_exports.union([
7191
7367
  external_exports.number(),
7192
7368
  external_exports.string().regex(/^(?:\d+(?:\.\d+)?|\.\d+)(?:mm|cm|m|in|inch)?$/i).transform((value) => value.toLowerCase())
7193
7369
  ]).pipe(modelLengthSchema).refine((value) => value > 0, "Length must be positive");
@@ -7258,30 +7434,30 @@ var flangeboltDimensions = {
7258
7434
  }
7259
7435
  };
7260
7436
  var flangeboltMetricSizeSchema = external_exports.enum(["M5", "M6", "M8", "M10"]);
7261
- var shape14 = {
7437
+ var shape16 = {
7262
7438
  iso4162: external_exports.literal(true).default(true),
7263
7439
  metricSize: flangeboltMetricSizeSchema,
7264
- length: positiveLength3,
7440
+ length: positiveLength5,
7265
7441
  fullThread: external_exports.literal(true).default(true),
7266
7442
  plainFace: external_exports.literal(true).default(true),
7267
7443
  leftHand: external_exports.boolean().default(false),
7268
7444
  showThreads: external_exports.boolean().default(true),
7269
- diameter: positiveLength3.optional(),
7270
- threadPitch: positiveLength3.optional(),
7271
- headAcrossFlats: positiveLength3.optional(),
7272
- headHeight: positiveLength3.optional(),
7273
- flangeDiameter: positiveLength3.optional(),
7274
- flangeThickness: positiveLength3.optional(),
7275
- underHeadRadius: positiveLength3.optional(),
7276
- tipChamfer: positiveLength3.optional(),
7445
+ diameter: positiveLength5.optional(),
7446
+ threadPitch: positiveLength5.optional(),
7447
+ headAcrossFlats: positiveLength5.optional(),
7448
+ headHeight: positiveLength5.optional(),
7449
+ flangeDiameter: positiveLength5.optional(),
7450
+ flangeThickness: positiveLength5.optional(),
7451
+ underHeadRadius: positiveLength5.optional(),
7452
+ tipChamfer: positiveLength5.optional(),
7277
7453
  headChamferAngle: external_exports.number().finite().positive().optional(),
7278
- headChamferDiameter: positiveLength3.optional(),
7279
- headCornerDiameter: positiveLength3.optional(),
7454
+ headChamferDiameter: positiveLength5.optional(),
7455
+ headCornerDiameter: positiveLength5.optional(),
7280
7456
  flangeSlopeAngle: external_exports.number().finite().positive().optional(),
7281
- threadRootDiameter: positiveLength3.optional(),
7282
- threadPitchDiameter: positiveLength3.optional()
7457
+ threadRootDiameter: positiveLength5.optional(),
7458
+ threadPitchDiameter: positiveLength5.optional()
7283
7459
  };
7284
- var validate13 = (props, context) => {
7460
+ var validate15 = (props, context) => {
7285
7461
  const dimensions5 = flangeboltDimensions[props.metricSize];
7286
7462
  for (const key of Object.keys(dimensions5)) {
7287
7463
  if (props[key] !== void 0 && Math.abs(props[key] - dimensions5[key]) > 1e-9)
@@ -7298,15 +7474,15 @@ var validate13 = (props, context) => {
7298
7474
  message: "Length must leave material between fixed end features"
7299
7475
  });
7300
7476
  };
7301
- var flangeboltModelPropsSchema = external_exports.object(shape14).strict().superRefine(validate13).transform((props) => ({
7477
+ var flangeboltModelPropsSchema = external_exports.object(shape16).strict().superRefine(validate15).transform((props) => ({
7302
7478
  ...props,
7303
7479
  ...flangeboltDimensions[props.metricSize]
7304
7480
  }));
7305
- var flangeboltModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("flangebolt"), ...shape14 }).strict().superRefine(validate13).transform((props) => ({
7481
+ var flangeboltModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("flangebolt"), ...shape16 }).strict().superRefine(validate15).transform((props) => ({
7306
7482
  ...props,
7307
7483
  ...flangeboltDimensions[props.metricSize]
7308
7484
  }));
7309
- var aliases2 = {
7485
+ var aliases4 = {
7310
7486
  m: "metricSize",
7311
7487
  metricsize: "metricSize",
7312
7488
  l: "length",
@@ -7363,7 +7539,7 @@ function parseFlangeBoltModelParams(raw) {
7363
7539
  throw new Error(
7364
7540
  "ISO 4162 is the default head/flange envelope; use the bare iso4162 flag or omit it. Full threading is an extension of ISO 4162"
7365
7541
  );
7366
- property = aliases2[key] ?? "";
7542
+ property = aliases4[key] ?? "";
7367
7543
  if (!property || !value)
7368
7544
  throw new Error(`Unknown or missing flangebolt token ${token}`);
7369
7545
  if (property === "metricSize") {
@@ -7386,32 +7562,32 @@ function parseFlangeBoltModelParams(raw) {
7386
7562
  }
7387
7563
  return flangeboltModelDefinitionSchema.parse({ fn: "flangebolt", ...props });
7388
7564
  }
7389
- var model18 = defineModel({
7565
+ var model20 = defineModel({
7390
7566
  name: "flangebolt",
7391
7567
  schema: flangeboltModelDefinitionSchema,
7392
7568
  parse: parseFlangeBoltModelParams
7393
7569
  });
7394
- function register18(registry2) {
7395
- registry2.register(model18);
7570
+ function register20(registry2) {
7571
+ registry2.register(model20);
7396
7572
  }
7397
7573
  var stringFlags6 = {
7398
7574
  plainclosed: "style(plainclosed)"
7399
7575
  };
7400
7576
  var omittedStringFlags6 = ["plainclosed"];
7401
- var positiveLength4 = external_exports.union([
7577
+ var positiveLength6 = external_exports.union([
7402
7578
  external_exports.number(),
7403
7579
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
7404
7580
  ]).pipe(modelLengthSchema).refine((value) => value > 0);
7405
- var shape15 = {
7406
- innerDiameter: positiveLength4,
7407
- outerDiameter: positiveLength4,
7408
- flangeDiameter: positiveLength4,
7581
+ var shape17 = {
7582
+ innerDiameter: positiveLength6,
7583
+ outerDiameter: positiveLength6,
7584
+ flangeDiameter: positiveLength6,
7409
7585
  /** Overall end-plane distance including the integral flange. */
7410
- length: positiveLength4,
7411
- flangeThickness: positiveLength4,
7586
+ length: positiveLength6,
7587
+ flangeThickness: positiveLength6,
7412
7588
  style: external_exports.literal("plainclosed").default("plainclosed")
7413
7589
  };
7414
- function validate14(props, context) {
7590
+ function validate16(props, context) {
7415
7591
  if (props.outerDiameter <= props.innerDiameter)
7416
7592
  context.addIssue({
7417
7593
  code: "custom",
@@ -7431,8 +7607,8 @@ function validate14(props, context) {
7431
7607
  message: "Flange thickness must leave a positive projecting sleeve length"
7432
7608
  });
7433
7609
  }
7434
- var flangedBushingModelPropsSchema = external_exports.object(shape15).strict().superRefine(validate14);
7435
- var flangedBushingModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("flangedbushing"), ...shape15 }).strict().superRefine(validate14);
7610
+ var flangedBushingModelPropsSchema = external_exports.object(shape17).strict().superRefine(validate16);
7611
+ var flangedBushingModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("flangedbushing"), ...shape17 }).strict().superRefine(validate16);
7436
7612
  function getFlangedBushingDimensions(input) {
7437
7613
  const props = flangedBushingModelPropsSchema.parse(input);
7438
7614
  return {
@@ -7489,7 +7665,7 @@ function parseFlangedBushingModelParams(raw) {
7489
7665
  }
7490
7666
  return flangedBushingModelDefinitionSchema.parse(props);
7491
7667
  }
7492
- var model19 = defineModel({
7668
+ var model21 = defineModel({
7493
7669
  name: "flangedbushing",
7494
7670
  schema: flangedBushingModelDefinitionSchema,
7495
7671
  parse: parseFlangedBushingModelParams,
@@ -7500,8 +7676,8 @@ var model19 = defineModel({
7500
7676
  omittedStringFlags6
7501
7677
  )
7502
7678
  });
7503
- function register19(registry2) {
7504
- registry2.register(model19);
7679
+ function register21(registry2) {
7680
+ registry2.register(model21);
7505
7681
  }
7506
7682
  var flangeNutDimensions = {
7507
7683
  M5: {
@@ -7603,20 +7779,20 @@ var flangeNutMetricSizeSchema = external_exports.enum([
7603
7779
  "M16",
7604
7780
  "M20"
7605
7781
  ]);
7606
- var positiveLength5 = external_exports.union([
7782
+ var positiveLength7 = external_exports.union([
7607
7783
  external_exports.number().finite(),
7608
7784
  external_exports.string().regex(/^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
7609
7785
  ]).pipe(modelLengthSchema).refine((value) => value > 0, "Length must be positive");
7610
- var shape16 = {
7786
+ var shape18 = {
7611
7787
  iso4161: external_exports.literal(true).default(true),
7612
7788
  metricSize: flangeNutMetricSizeSchema,
7613
7789
  plainFace: external_exports.literal(true).default(true),
7614
- threadPitch: positiveLength5.optional(),
7790
+ threadPitch: positiveLength7.optional(),
7615
7791
  rightHanded: external_exports.literal(true).default(true),
7616
7792
  threadClass: external_exports.literal("6H").default("6H"),
7617
7793
  showThreads: external_exports.boolean().default(true)
7618
7794
  };
7619
- function validate15(props, context) {
7795
+ function validate17(props, context) {
7620
7796
  if (props.threadPitch !== void 0 && Math.abs(
7621
7797
  props.threadPitch - flangeNutDimensions[props.metricSize].threadPitch
7622
7798
  ) > 1e-9)
@@ -7632,8 +7808,8 @@ function normalize4(props) {
7632
7808
  threadPitch: flangeNutDimensions[props.metricSize].threadPitch
7633
7809
  };
7634
7810
  }
7635
- var flangeNutModelPropsSchema = external_exports.object(shape16).strict().superRefine(validate15).transform(normalize4);
7636
- var flangeNutModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("flangenut"), ...shape16 }).strict().superRefine(validate15).transform(normalize4);
7811
+ var flangeNutModelPropsSchema = external_exports.object(shape18).strict().superRefine(validate17).transform(normalize4);
7812
+ var flangeNutModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("flangenut"), ...shape18 }).strict().superRefine(validate17).transform(normalize4);
7637
7813
  function getFlangeNutDimensions(input) {
7638
7814
  const props = flangeNutModelPropsSchema.parse(input);
7639
7815
  const d = flangeNutDimensions[props.metricSize];
@@ -7693,13 +7869,13 @@ function parseFlangeNutModelParams(raw) {
7693
7869
  }
7694
7870
  return flangeNutModelDefinitionSchema.parse(props);
7695
7871
  }
7696
- var model20 = defineModel({
7872
+ var model22 = defineModel({
7697
7873
  name: "flangenut",
7698
7874
  schema: flangeNutModelDefinitionSchema,
7699
7875
  parse: parseFlangeNutModelParams
7700
7876
  });
7701
- function register20(registry2) {
7702
- registry2.register(model20);
7877
+ function register22(registry2) {
7878
+ registry2.register(model22);
7703
7879
  }
7704
7880
  var stringFlags7 = {
7705
7881
  hexsocket: "drive(hexsocket)",
@@ -7849,7 +8025,7 @@ var flatHeadScrewModelDefinitionSchema = external_exports.object({
7849
8025
  ...props,
7850
8026
  ...flatHeadScrewDimensions[props.metricSize]
7851
8027
  }));
7852
- var aliases3 = {
8028
+ var aliases5 = {
7853
8029
  m: "metricSize",
7854
8030
  metricsize: "metricSize",
7855
8031
  l: "length",
@@ -7915,7 +8091,7 @@ var parseFlatHeadScrewModelParams = (raw) => {
7915
8091
  property = "showThreads";
7916
8092
  parsed = key === "threads";
7917
8093
  } else {
7918
- property = key ? aliases3[key] ?? "" : "";
8094
+ property = key ? aliases5[key] ?? "" : "";
7919
8095
  if (!property || !value)
7920
8096
  throw new Error(`Unknown or missing flatheadscrew token "${token}"`);
7921
8097
  if (selectors2.has(property)) {
@@ -7945,7 +8121,7 @@ var parseFlatHeadScrewModelParams = (raw) => {
7945
8121
  ...props
7946
8122
  });
7947
8123
  };
7948
- var model21 = defineModel({
8124
+ var model23 = defineModel({
7949
8125
  name: "flatheadscrew",
7950
8126
  schema: flatHeadScrewModelDefinitionSchema,
7951
8127
  parse: parseFlatHeadScrewModelParams,
@@ -7956,10 +8132,10 @@ var model21 = defineModel({
7956
8132
  omittedStringFlags7
7957
8133
  )
7958
8134
  });
7959
- function register21(registry2) {
7960
- registry2.register(model21);
8135
+ function register23(registry2) {
8136
+ registry2.register(model23);
7961
8137
  }
7962
- var positiveLength6 = external_exports.union([
8138
+ var positiveLength8 = external_exports.union([
7963
8139
  external_exports.number(),
7964
8140
  external_exports.string().regex(/^(?:\d+(?:\.\d+)?|\.\d+)(?:mm|cm|m|in|inch)?$/i).transform((value) => value.toLowerCase())
7965
8141
  ]).pipe(modelLengthSchema).refine((value) => value > 0, "Length must be positive");
@@ -7970,21 +8146,21 @@ var heatSetInsertCoarsePitches = {
7970
8146
  M6: 1
7971
8147
  };
7972
8148
  var heatSetInsertMetricSizeSchema = external_exports.enum(["M3", "M4", "M5", "M6"]);
7973
- var shape17 = {
8149
+ var shape19 = {
7974
8150
  metricSize: heatSetInsertMetricSizeSchema,
7975
- outerDiameter: positiveLength6,
7976
- length: positiveLength6,
7977
- knurlDepth: positiveLength6,
7978
- knurlPitch: positiveLength6,
8151
+ outerDiameter: positiveLength8,
8152
+ length: positiveLength8,
8153
+ knurlDepth: positiveLength8,
8154
+ knurlPitch: positiveLength8,
7979
8155
  knurlTeeth: external_exports.number().int().min(3).max(96),
7980
8156
  diamondKnurl: external_exports.literal(true).default(true),
7981
8157
  leftHand: external_exports.boolean().default(false),
7982
8158
  showThreads: external_exports.boolean().default(true),
7983
- diameter: positiveLength6.optional(),
7984
- threadPitch: positiveLength6.optional(),
7985
- threadMinorDiameter: positiveLength6.optional(),
7986
- threadPitchDiameter: positiveLength6.optional(),
7987
- rootOuterDiameter: positiveLength6.optional()
8159
+ diameter: positiveLength8.optional(),
8160
+ threadPitch: positiveLength8.optional(),
8161
+ threadMinorDiameter: positiveLength8.optional(),
8162
+ threadPitchDiameter: positiveLength8.optional(),
8163
+ rootOuterDiameter: positiveLength8.optional()
7988
8164
  };
7989
8165
  function dimensions4(p) {
7990
8166
  const diameter = Number(p.metricSize.slice(1)), threadPitch = heatSetInsertCoarsePitches[p.metricSize];
@@ -7997,7 +8173,7 @@ function dimensions4(p) {
7997
8173
  rootOuterDiameter: p.outerDiameter - 2 * p.knurlDepth
7998
8174
  };
7999
8175
  }
8000
- function validate16(p, context) {
8176
+ function validate18(p, context) {
8001
8177
  const d = dimensions4(p);
8002
8178
  for (const key of Object.keys(d))
8003
8179
  if (p[key] !== void 0 && Math.abs(p[key] - d[key]) > 1e-9)
@@ -8019,9 +8195,9 @@ function validate16(p, context) {
8019
8195
  message: "Insert exceeds the 1000-repeat contract limit"
8020
8196
  });
8021
8197
  }
8022
- var heatSetInsertModelPropsSchema = external_exports.object(shape17).strict().superRefine(validate16).transform((p) => ({ ...p, ...dimensions4(p) }));
8023
- var heatSetInsertModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("heatsetinsert"), ...shape17 }).strict().superRefine(validate16).transform((p) => ({ ...p, ...dimensions4(p) }));
8024
- var aliases4 = {
8198
+ var heatSetInsertModelPropsSchema = external_exports.object(shape19).strict().superRefine(validate18).transform((p) => ({ ...p, ...dimensions4(p) }));
8199
+ var heatSetInsertModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("heatsetinsert"), ...shape19 }).strict().superRefine(validate18).transform((p) => ({ ...p, ...dimensions4(p) }));
8200
+ var aliases6 = {
8025
8201
  m: "metricSize",
8026
8202
  metricsize: "metricSize",
8027
8203
  od: "outerDiameter",
@@ -8060,7 +8236,7 @@ function parseHeatSetInsertModelParams(raw) {
8060
8236
  property = flags3[key];
8061
8237
  parsed = !["righthanded", "nothreads"].includes(key);
8062
8238
  } else {
8063
- property = aliases4[key] ?? "";
8239
+ property = aliases6[key] ?? "";
8064
8240
  if (!property || !value)
8065
8241
  throw new Error(`Unknown or missing heatsetinsert token ${token}`);
8066
8242
  if (property === "metricSize") {
@@ -8086,13 +8262,13 @@ function parseHeatSetInsertModelParams(raw) {
8086
8262
  ...props
8087
8263
  });
8088
8264
  }
8089
- var model22 = defineModel({
8265
+ var model24 = defineModel({
8090
8266
  name: "heatsetinsert",
8091
8267
  schema: heatSetInsertModelDefinitionSchema,
8092
8268
  parse: parseHeatSetInsertModelParams
8093
8269
  });
8094
- function register22(registry2) {
8095
- registry2.register(model22);
8270
+ function register24(registry2) {
8271
+ registry2.register(model24);
8096
8272
  }
8097
8273
  var stringFlags8 = {
8098
8274
  righthanded: "threadhand(right)"
@@ -8327,17 +8503,17 @@ var hexNutImperialSizeSchema = external_exports.enum([
8327
8503
  "7/8",
8328
8504
  "1"
8329
8505
  ]);
8330
- var length9 = external_exports.union([
8506
+ var length11 = external_exports.union([
8331
8507
  external_exports.number(),
8332
8508
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
8333
8509
  ]).pipe(modelLengthSchema).refine((value) => value > 0, "Length must be positive");
8334
- var shape18 = {
8510
+ var shape20 = {
8335
8511
  iso4032: external_exports.boolean().optional(),
8336
8512
  din934: external_exports.boolean().optional(),
8337
8513
  asmeb1822: external_exports.boolean().optional(),
8338
8514
  metricSize: hexNutMetricSizeSchema.optional(),
8339
8515
  imperialSize: hexNutImperialSizeSchema.optional(),
8340
- threadPitch: length9.optional(),
8516
+ threadPitch: length11.optional(),
8341
8517
  threadHand: external_exports.literal("right").default("right"),
8342
8518
  threadClass: external_exports.enum(["6H", "2B"]).optional(),
8343
8519
  showThreads: external_exports.boolean().default(true)
@@ -8360,7 +8536,7 @@ function selectedDimensions(props) {
8360
8536
  if (!props.metricSize) return void 0;
8361
8537
  return family.din934 ? hexNutDinDimensions[props.metricSize] : hexNutDimensions[props.metricSize];
8362
8538
  }
8363
- function validate17(props, context) {
8539
+ function validate19(props, context) {
8364
8540
  const issue = (path, message) => context.addIssue({ code: "custom", path: [path], message });
8365
8541
  if (!!props.metricSize === !!props.imperialSize)
8366
8542
  issue("metricSize", "Select exactly one metric or imperial size");
@@ -8394,8 +8570,8 @@ function normalize5(props) {
8394
8570
  threadClass: props.threadClass ?? (selectedFamily(props).asmeb1822 ? "2B" : "6H")
8395
8571
  };
8396
8572
  }
8397
- var hexNutModelPropsSchema = external_exports.object(shape18).strict().superRefine(validate17).transform(normalize5);
8398
- var hexNutModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("hexnut"), ...shape18 }).strict().superRefine(validate17).transform(normalize5);
8573
+ var hexNutModelPropsSchema = external_exports.object(shape20).strict().superRefine(validate19).transform(normalize5);
8574
+ var hexNutModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("hexnut"), ...shape20 }).strict().superRefine(validate19).transform(normalize5);
8399
8575
  function getHexNutDimensions(input) {
8400
8576
  const props = hexNutModelPropsSchema.parse(input);
8401
8577
  const dims = selectedDimensions(props);
@@ -8478,7 +8654,7 @@ function parseHexNutModelParams(raw) {
8478
8654
  }
8479
8655
  return hexNutModelDefinitionSchema.parse(props);
8480
8656
  }
8481
- var model23 = defineModel({
8657
+ var model25 = defineModel({
8482
8658
  name: "hexnut",
8483
8659
  schema: hexNutModelDefinitionSchema,
8484
8660
  parse: parseHexNutModelParams,
@@ -8489,19 +8665,19 @@ var model23 = defineModel({
8489
8665
  omittedStringFlags8
8490
8666
  )
8491
8667
  });
8492
- function register23(registry2) {
8493
- registry2.register(model23);
8668
+ function register25(registry2) {
8669
+ registry2.register(model25);
8494
8670
  }
8495
- var length10 = external_exports.union([
8671
+ var length12 = external_exports.union([
8496
8672
  external_exports.number(),
8497
8673
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
8498
8674
  ]).pipe(modelLengthSchema);
8499
- var positive4 = length10.refine((value) => value > 0, "Length must be positive");
8500
- var nonnegative3 = length10.refine(
8675
+ var positive4 = length12.refine((value) => value > 0, "Length must be positive");
8676
+ var nonnegative3 = length12.refine(
8501
8677
  (value) => value >= 0,
8502
8678
  "Length cannot be negative"
8503
8679
  );
8504
- var shape19 = {
8680
+ var shape21 = {
8505
8681
  /** Diameter at the rib crests. All lengths normalize to millimeters. */
8506
8682
  outerDiameter: positive4.default(6),
8507
8683
  innerDiameter: positive4.default(4),
@@ -8515,7 +8691,7 @@ var shape19 = {
8515
8691
  /** Radial distance from crest to root; zero produces a smooth tube. */
8516
8692
  ribDepth: nonnegative3.default(0.25)
8517
8693
  };
8518
- function validate18(props, context) {
8694
+ function validate20(props, context) {
8519
8695
  if (props.outerDiameter - 2 * props.ribDepth <= props.innerDiameter)
8520
8696
  context.addIssue({
8521
8697
  code: "custom",
@@ -8535,8 +8711,8 @@ function validate18(props, context) {
8535
8711
  message: "Centerline length must be finite and positive"
8536
8712
  });
8537
8713
  }
8538
- var hollowPositioningArmTubeModelPropsSchema = external_exports.object(shape19).strict().superRefine(validate18);
8539
- var hollowPositioningArmTubeModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("hollowpositioningarmtube"), ...shape19 }).strict().superRefine(validate18);
8714
+ var hollowPositioningArmTubeModelPropsSchema = external_exports.object(shape21).strict().superRefine(validate20);
8715
+ var hollowPositioningArmTubeModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("hollowpositioningarmtube"), ...shape21 }).strict().superRefine(validate20);
8540
8716
  function getHollowPositioningArmTubeDimensions(input) {
8541
8717
  const props = hollowPositioningArmTubeModelPropsSchema.parse(input);
8542
8718
  const bendLength = props.bendRadius * (props.bendAngle * Math.PI / 180);
@@ -8606,23 +8782,23 @@ function parseHollowPositioningArmTubeModelParams(raw) {
8606
8782
  }
8607
8783
  return hollowPositioningArmTubeModelDefinitionSchema.parse(props);
8608
8784
  }
8609
- var model24 = defineModel({
8785
+ var model26 = defineModel({
8610
8786
  name: "hollowpositioningarmtube",
8611
8787
  schema: hollowPositioningArmTubeModelDefinitionSchema,
8612
8788
  parse: parseHollowPositioningArmTubeModelParams
8613
8789
  });
8614
- function register24(registry2) {
8615
- registry2.register(model24);
8790
+ function register26(registry2) {
8791
+ registry2.register(model26);
8616
8792
  }
8617
- var length11 = external_exports.union([
8793
+ var length13 = external_exports.union([
8618
8794
  external_exports.number(),
8619
8795
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
8620
8796
  ]).pipe(modelLengthSchema);
8621
- var positiveLength7 = length11.refine(
8797
+ var positiveLength9 = length13.refine(
8622
8798
  (value) => value > 0,
8623
8799
  "Length must be positive"
8624
8800
  );
8625
- var nonnegativeLength = length11.refine(
8801
+ var nonnegativeLength3 = length13.refine(
8626
8802
  (value) => value >= 0,
8627
8803
  "Length cannot be negative"
8628
8804
  );
@@ -8648,21 +8824,21 @@ var maleFemaleStandoffMetricSizeSchema = external_exports.enum([
8648
8824
  "M10",
8649
8825
  "M12"
8650
8826
  ]);
8651
- var shape20 = {
8827
+ var shape22 = {
8652
8828
  metricSize: maleFemaleStandoffMetricSizeSchema,
8653
- acrossFlats: positiveLength7,
8829
+ acrossFlats: positiveLength9,
8654
8830
  /** Body height above its lower mounting plane Z=0, excluding the stud. */
8655
- length: positiveLength7,
8656
- studLength: positiveLength7,
8831
+ length: positiveLength9,
8832
+ studLength: positiveLength9,
8657
8833
  /** Blind female socket depth measured down from the upper mounting plane. */
8658
- femaleDepth: positiveLength7,
8834
+ femaleDepth: positiveLength9,
8659
8835
  hex: external_exports.literal(true).default(true),
8660
- threadPitch: positiveLength7.optional(),
8836
+ threadPitch: positiveLength9.optional(),
8661
8837
  leftHand: external_exports.boolean().default(false),
8662
8838
  showThreads: external_exports.boolean().default(true),
8663
- bodyChamfer: nonnegativeLength.optional(),
8664
- studChamfer: nonnegativeLength.optional(),
8665
- mouthChamfer: nonnegativeLength.optional()
8839
+ bodyChamfer: nonnegativeLength3.optional(),
8840
+ studChamfer: nonnegativeLength3.optional(),
8841
+ mouthChamfer: nonnegativeLength3.optional()
8666
8842
  };
8667
8843
  function resolve5(props) {
8668
8844
  const diameter = Number(props.metricSize.slice(1));
@@ -8682,7 +8858,7 @@ function resolve5(props) {
8682
8858
  mouthChamfer: props.mouthChamfer ?? chamfer
8683
8859
  };
8684
8860
  }
8685
- function validate19(props, context) {
8861
+ function validate21(props, context) {
8686
8862
  const p = resolve5(props);
8687
8863
  const diameter = Number(p.metricSize.slice(1));
8688
8864
  const externalMinorDiameter = diameter - 17 * Math.sqrt(3) / 24 * p.threadPitch;
@@ -8712,8 +8888,8 @@ function validate19(props, context) {
8712
8888
  "Hex body and chamfers must leave material around the socket and stud"
8713
8889
  );
8714
8890
  }
8715
- var maleFemaleStandoffModelPropsSchema = external_exports.object(shape20).strict().superRefine(validate19).transform(resolve5);
8716
- var maleFemaleStandoffModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("malefemalestandoff"), ...shape20 }).strict().superRefine(validate19).transform(resolve5);
8891
+ var maleFemaleStandoffModelPropsSchema = external_exports.object(shape22).strict().superRefine(validate21).transform(resolve5);
8892
+ var maleFemaleStandoffModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("malefemalestandoff"), ...shape22 }).strict().superRefine(validate21).transform(resolve5);
8717
8893
  function getMaleFemaleStandoffDimensions(input) {
8718
8894
  const props = maleFemaleStandoffModelPropsSchema.parse(input);
8719
8895
  const diameter = Number(props.metricSize.slice(1));
@@ -8792,13 +8968,13 @@ function parseMaleFemaleStandoffModelParams(raw) {
8792
8968
  }
8793
8969
  return maleFemaleStandoffModelDefinitionSchema.parse(props);
8794
8970
  }
8795
- var model25 = defineModel({
8971
+ var model27 = defineModel({
8796
8972
  name: "malefemalestandoff",
8797
8973
  schema: maleFemaleStandoffModelDefinitionSchema,
8798
8974
  parse: parseMaleFemaleStandoffModelParams
8799
8975
  });
8800
- function register25(registry2) {
8801
- registry2.register(model25);
8976
+ function register27(registry2) {
8977
+ registry2.register(model27);
8802
8978
  }
8803
8979
  var nylonLockNutDimensions = {
8804
8980
  M5: {
@@ -8849,22 +9025,22 @@ var nylonLockNutMetricSizeSchema = external_exports.enum([
8849
9025
  "M10",
8850
9026
  "M12"
8851
9027
  ]);
8852
- var length12 = external_exports.union([
9028
+ var length14 = external_exports.union([
8853
9029
  external_exports.number().finite(),
8854
9030
  external_exports.string().regex(/^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
8855
9031
  ]).pipe(modelLengthSchema).refine(
8856
9032
  (value) => Number.isFinite(value) && value > 0,
8857
9033
  "Length must be finite and positive"
8858
9034
  );
8859
- var shape21 = {
9035
+ var shape23 = {
8860
9036
  iso7040: external_exports.literal(true).default(true),
8861
9037
  metricSize: nylonLockNutMetricSizeSchema,
8862
- threadPitch: length12.optional(),
9038
+ threadPitch: length14.optional(),
8863
9039
  rightHanded: external_exports.literal(true).default(true),
8864
9040
  threadClass: external_exports.literal("6H").default("6H"),
8865
9041
  showThreads: external_exports.boolean().default(true)
8866
9042
  };
8867
- function validate20(props, context) {
9043
+ function validate22(props, context) {
8868
9044
  const expected = nylonLockNutDimensions[props.metricSize].threadPitch;
8869
9045
  if (props.threadPitch !== void 0 && Math.abs(props.threadPitch - expected) > 1e-9)
8870
9046
  context.addIssue({
@@ -8879,8 +9055,8 @@ function normalize6(props) {
8879
9055
  threadPitch: nylonLockNutDimensions[props.metricSize].threadPitch
8880
9056
  };
8881
9057
  }
8882
- var nylonLockNutModelPropsSchema = external_exports.object(shape21).strict().superRefine(validate20).transform(normalize6);
8883
- var nylonLockNutModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("nylonlocknut"), ...shape21 }).strict().superRefine(validate20).transform(normalize6);
9058
+ var nylonLockNutModelPropsSchema = external_exports.object(shape23).strict().superRefine(validate22).transform(normalize6);
9059
+ var nylonLockNutModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("nylonlocknut"), ...shape23 }).strict().superRefine(validate22).transform(normalize6);
8884
9060
  function getNylonLockNutDimensions(input) {
8885
9061
  const props = nylonLockNutModelPropsSchema.parse(input);
8886
9062
  const d = nylonLockNutDimensions[props.metricSize];
@@ -8943,13 +9119,13 @@ function parseNylonLockNutModelParams(raw) {
8943
9119
  }
8944
9120
  return nylonLockNutModelDefinitionSchema.parse(props);
8945
9121
  }
8946
- var model26 = defineModel({
9122
+ var model28 = defineModel({
8947
9123
  name: "nylonlocknut",
8948
9124
  schema: nylonLockNutModelDefinitionSchema,
8949
9125
  parse: parseNylonLockNutModelParams
8950
9126
  });
8951
- function register26(registry2) {
8952
- registry2.register(model26);
9127
+ function register28(registry2) {
9128
+ registry2.register(model28);
8953
9129
  }
8954
9130
  var stringFlags9 = {
8955
9131
  phillips: "drive(phillips)",
@@ -9148,7 +9324,7 @@ var panScrewModelDefinitionSchema = external_exports.object({
9148
9324
  fn: external_exports.literal("panscrew"),
9149
9325
  ...panScrewModelPropsShape
9150
9326
  }).strict().superRefine(validatePanScrew).transform((props) => ({ ...props, ...panScrewDimensions[props.metricSize] }));
9151
- var aliases5 = {
9327
+ var aliases7 = {
9152
9328
  m: "metricSize",
9153
9329
  metricsize: "metricSize",
9154
9330
  l: "length",
@@ -9223,7 +9399,7 @@ var parsePanScrewModelParams = (raw) => {
9223
9399
  property = "showThreads";
9224
9400
  parsed = key === "threads";
9225
9401
  } else {
9226
- property = key ? aliases5[key] ?? "" : "";
9402
+ property = key ? aliases7[key] ?? "" : "";
9227
9403
  if (!property || !value)
9228
9404
  throw new Error(`Unknown or missing panscrew token "${token}"`);
9229
9405
  if (selectors3.has(property)) {
@@ -9256,7 +9432,7 @@ var parsePanScrewModelParams = (raw) => {
9256
9432
  }
9257
9433
  return panScrewModelDefinitionSchema.parse({ fn: "panscrew", ...props });
9258
9434
  };
9259
- var model27 = defineModel({
9435
+ var model29 = defineModel({
9260
9436
  name: "panscrew",
9261
9437
  schema: panScrewModelDefinitionSchema,
9262
9438
  parse: parsePanScrewModelParams,
@@ -9267,28 +9443,121 @@ var model27 = defineModel({
9267
9443
  omittedStringFlags9
9268
9444
  )
9269
9445
  });
9270
- function register27(registry2) {
9271
- registry2.register(model27);
9446
+ function register29(registry2) {
9447
+ registry2.register(model29);
9448
+ }
9449
+ var length15 = external_exports.union([
9450
+ external_exports.number(),
9451
+ external_exports.string().regex(/^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
9452
+ ]).pipe(modelLengthSchema);
9453
+ var positiveLength10 = length15.refine(
9454
+ (value) => value > 0,
9455
+ "Length must be positive"
9456
+ );
9457
+ var nonnegativeLength4 = length15.refine(
9458
+ (value) => value >= 0,
9459
+ "Length cannot be negative"
9460
+ );
9461
+ var shape24 = {
9462
+ length: positiveLength10,
9463
+ width: positiveLength10,
9464
+ thickness: positiveLength10,
9465
+ holeDiameter: positiveLength10,
9466
+ pitchX: positiveLength10,
9467
+ pitchY: positiveLength10,
9468
+ edgeX: positiveLength10,
9469
+ edgeY: positiveLength10,
9470
+ stagger: nonnegativeLength4.default(0)
9471
+ };
9472
+ function validate23(p, context) {
9473
+ if (p.holeDiameter >= Math.min(p.pitchX, p.pitchY))
9474
+ context.addIssue({
9475
+ code: "custom",
9476
+ message: "Invalid perforatedsheet dimensions: constraint 1"
9477
+ });
9478
+ if (2 * p.edgeX > p.length || 2 * p.edgeY > p.width)
9479
+ context.addIssue({
9480
+ code: "custom",
9481
+ message: "Invalid perforatedsheet dimensions: constraint 2"
9482
+ });
9483
+ if (Math.min(p.edgeX, p.edgeY) <= p.holeDiameter / 2)
9484
+ context.addIssue({
9485
+ code: "custom",
9486
+ message: "Invalid perforatedsheet dimensions: constraint 3"
9487
+ });
9488
+ if (p.stagger >= p.pitchX)
9489
+ context.addIssue({
9490
+ code: "custom",
9491
+ message: "Invalid perforatedsheet dimensions: constraint 4"
9492
+ });
9493
+ if (Math.floor((p.length - 2 * p.edgeX) / p.pitchX + 1) * Math.floor((p.width - 2 * p.edgeY) / p.pitchY + 1) > 2500)
9494
+ context.addIssue({
9495
+ code: "custom",
9496
+ message: "Invalid perforatedsheet dimensions: constraint 5"
9497
+ });
9498
+ }
9499
+ var perforatedSheetModelPropsSchema = external_exports.object(shape24).strict().superRefine(validate23);
9500
+ var perforatedSheetModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("perforatedsheet"), ...shape24 }).strict().superRefine(validate23);
9501
+ var aliases8 = {
9502
+ l: "length",
9503
+ w: "width",
9504
+ t: "thickness",
9505
+ hole: "holeDiameter",
9506
+ pitchx: "pitchX",
9507
+ pitchy: "pitchY",
9508
+ edgex: "edgeX",
9509
+ edgey: "edgeY",
9510
+ stagger: "stagger",
9511
+ length: "length",
9512
+ width: "width",
9513
+ thickness: "thickness",
9514
+ holediameter: "holeDiameter"
9515
+ };
9516
+ function parsePerforatedSheetModelParams(raw) {
9517
+ const [name, ...tokens] = splitModelStringTokens(raw.string);
9518
+ if (raw.fn !== "perforatedsheet" || name?.toLowerCase() !== "perforatedsheet")
9519
+ throw new Error("Expected perforatedsheet without inline values");
9520
+ const props = { fn: "perforatedsheet" };
9521
+ for (const token of tokens) {
9522
+ const match = token.match(/^([a-z]+)(.*)$/i);
9523
+ const key = match?.[1]?.toLowerCase();
9524
+ const value = match?.[2];
9525
+ if (!key || !Object.hasOwn(aliases8, key) || !value)
9526
+ throw new Error(`Unknown or malformed perforatedsheet token "${token}"`);
9527
+ const property = aliases8[key];
9528
+ if (Object.hasOwn(props, property))
9529
+ throw new Error(`Duplicate perforatedsheet property "${property}"`);
9530
+ props[property] = value;
9531
+ }
9532
+ return perforatedSheetModelDefinitionSchema.parse(props);
9533
+ }
9534
+ var model30 = defineModel({
9535
+ name: "perforatedsheet",
9536
+ schema: perforatedSheetModelDefinitionSchema,
9537
+ parse: parsePerforatedSheetModelParams
9538
+ });
9539
+ function register30(registry2) {
9540
+ registry2.register(model30);
9272
9541
  }
9273
9542
  var stringFlags10 = {
9274
9543
  plainclosed: "style(plainclosed)"
9275
9544
  };
9276
9545
  var omittedStringFlags10 = ["plainclosed"];
9277
- var length13 = external_exports.union([
9546
+ var length16 = external_exports.union([
9278
9547
  external_exports.number(),
9279
9548
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
9280
9549
  ]).pipe(modelLengthSchema);
9281
- var positiveLength8 = length13.refine((value) => value > 0);
9282
- var shape22 = {
9283
- innerDiameter: positiveLength8,
9284
- outerDiameter: positiveLength8,
9550
+ var positiveLength11 = length16.refine((value) => value > 0);
9551
+ var shape25 = {
9552
+ innerDiameter: positiveLength11,
9553
+ outerDiameter: positiveLength11,
9285
9554
  /** Overall end-plane distance, including the chamfers. */
9286
- length: positiveLength8,
9555
+ length: positiveLength11,
9287
9556
  style: external_exports.literal("plainclosed").default("plainclosed"),
9288
9557
  /** Equal axial/radial setbacks of all four 45-degree bore/outside rim chamfers. */
9289
- edgeChamfer: length13.refine((value) => value >= 0).default(0)
9558
+ edgeChamfer: length16.refine((value) => value >= 0).default(0)
9290
9559
  };
9291
- function validate21(props, context) {
9560
+ function validate24(props, context) {
9292
9561
  if (props.outerDiameter <= props.innerDiameter)
9293
9562
  context.addIssue({
9294
9563
  code: "custom",
@@ -9308,8 +9577,8 @@ function validate21(props, context) {
9308
9577
  message: "The two end chamfers must leave positive straight bore length"
9309
9578
  });
9310
9579
  }
9311
- var plainBushingModelPropsSchema = external_exports.object(shape22).strict().superRefine(validate21);
9312
- var plainBushingModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("plainbushing"), ...shape22 }).strict().superRefine(validate21);
9580
+ var plainBushingModelPropsSchema = external_exports.object(shape25).strict().superRefine(validate24);
9581
+ var plainBushingModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("plainbushing"), ...shape25 }).strict().superRefine(validate24);
9313
9582
  function getPlainBushingDimensions(input) {
9314
9583
  const props = plainBushingModelPropsSchema.parse(input);
9315
9584
  return {
@@ -9355,26 +9624,237 @@ function parsePlainBushingModelParams(raw) {
9355
9624
  parsed = style[1].toLowerCase();
9356
9625
  } else throw new Error(`Unknown plain bushing token "${token}"`);
9357
9626
  if (Object.hasOwn(props, property))
9358
- throw new Error(
9359
- `Plain bushing property "${property}" is set more than once`
9360
- );
9361
- props[property] = parsed;
9627
+ throw new Error(
9628
+ `Plain bushing property "${property}" is set more than once`
9629
+ );
9630
+ props[property] = parsed;
9631
+ }
9632
+ return plainBushingModelDefinitionSchema.parse(props);
9633
+ }
9634
+ var model31 = defineModel({
9635
+ name: "plainbushing",
9636
+ schema: plainBushingModelDefinitionSchema,
9637
+ parse: parsePlainBushingModelParams,
9638
+ normalizeString: (value) => normalizeModelStringFlags(
9639
+ value,
9640
+ stringFlags10,
9641
+ parsePlainBushingModelParams,
9642
+ omittedStringFlags10
9643
+ )
9644
+ });
9645
+ function register31(registry2) {
9646
+ registry2.register(model31);
9647
+ }
9648
+ var length17 = external_exports.union([
9649
+ external_exports.number(),
9650
+ external_exports.string().regex(/^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
9651
+ ]).pipe(modelLengthSchema);
9652
+ var positiveLength12 = length17.refine(
9653
+ (value) => value > 0,
9654
+ "Length must be positive"
9655
+ );
9656
+ var shape26 = {
9657
+ tubeDiameter: positiveLength12,
9658
+ length: positiveLength12,
9659
+ headDiameter: positiveLength12,
9660
+ headThickness: positiveLength12
9661
+ };
9662
+ function validate25(p, context) {
9663
+ if (p.headDiameter <= p.tubeDiameter)
9664
+ context.addIssue({
9665
+ code: "custom",
9666
+ message: "Invalid pushfitplug dimensions: constraint 1"
9667
+ });
9668
+ if (p.headThickness >= p.length)
9669
+ context.addIssue({
9670
+ code: "custom",
9671
+ message: "Invalid pushfitplug dimensions: constraint 2"
9672
+ });
9673
+ }
9674
+ var pushFitPlugModelPropsSchema = external_exports.object(shape26).strict().superRefine(validate25);
9675
+ var pushFitPlugModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("pushfitplug"), ...shape26 }).strict().superRefine(validate25);
9676
+ var aliases9 = {
9677
+ tubeod: "tubeDiameter",
9678
+ l: "length",
9679
+ headod: "headDiameter",
9680
+ headt: "headThickness",
9681
+ tubediameter: "tubeDiameter",
9682
+ length: "length",
9683
+ headdiameter: "headDiameter",
9684
+ headthickness: "headThickness"
9685
+ };
9686
+ function parsePushFitPlugModelParams(raw) {
9687
+ const [name, ...tokens] = splitModelStringTokens(raw.string);
9688
+ if (raw.fn !== "pushfitplug" || name?.toLowerCase() !== "pushfitplug")
9689
+ throw new Error("Expected pushfitplug without inline values");
9690
+ const props = { fn: "pushfitplug" };
9691
+ for (const token of tokens) {
9692
+ const match = token.match(/^([a-z]+)(.*)$/i);
9693
+ const key = match?.[1]?.toLowerCase();
9694
+ const value = match?.[2];
9695
+ if (!key || !Object.hasOwn(aliases9, key) || !value)
9696
+ throw new Error(`Unknown or malformed pushfitplug token "${token}"`);
9697
+ const property = aliases9[key];
9698
+ if (Object.hasOwn(props, property))
9699
+ throw new Error(`Duplicate pushfitplug property "${property}"`);
9700
+ props[property] = value;
9701
+ }
9702
+ return pushFitPlugModelDefinitionSchema.parse(props);
9703
+ }
9704
+ var model32 = defineModel({
9705
+ name: "pushfitplug",
9706
+ schema: pushFitPlugModelDefinitionSchema,
9707
+ parse: parsePushFitPlugModelParams
9708
+ });
9709
+ function register32(registry2) {
9710
+ registry2.register(model32);
9711
+ }
9712
+ var length18 = external_exports.union([
9713
+ external_exports.number(),
9714
+ external_exports.string().regex(/^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
9715
+ ]).pipe(modelLengthSchema);
9716
+ var positiveLength13 = length18.refine(
9717
+ (value) => value > 0,
9718
+ "Length must be positive"
9719
+ );
9720
+ var nonnegativeLength5 = length18.refine(
9721
+ (value) => value >= 0,
9722
+ "Length cannot be negative"
9723
+ );
9724
+ var shape27 = {
9725
+ width: positiveLength13,
9726
+ height: positiveLength13,
9727
+ length: positiveLength13,
9728
+ cornerRadius: nonnegativeLength5.default(0)
9729
+ };
9730
+ function validate26(p, context) {
9731
+ if (p.cornerRadius * 2 >= Math.min(p.width, p.height))
9732
+ context.addIssue({
9733
+ code: "custom",
9734
+ message: "Invalid rectangularbar dimensions: constraint 1"
9735
+ });
9736
+ }
9737
+ var rectangularBarModelPropsSchema = external_exports.object(shape27).strict().superRefine(validate26);
9738
+ var rectangularBarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rectangularbar"), ...shape27 }).strict().superRefine(validate26);
9739
+ var aliases10 = {
9740
+ w: "width",
9741
+ h: "height",
9742
+ l: "length",
9743
+ cornerr: "cornerRadius",
9744
+ width: "width",
9745
+ height: "height",
9746
+ length: "length",
9747
+ cornerradius: "cornerRadius"
9748
+ };
9749
+ function parseRectangularBarModelParams(raw) {
9750
+ const [name, ...tokens] = splitModelStringTokens(raw.string);
9751
+ if (raw.fn !== "rectangularbar" || name?.toLowerCase() !== "rectangularbar")
9752
+ throw new Error("Expected rectangularbar without inline values");
9753
+ const props = { fn: "rectangularbar" };
9754
+ for (const token of tokens) {
9755
+ const match = token.match(/^([a-z]+)(.*)$/i);
9756
+ const key = match?.[1]?.toLowerCase();
9757
+ const value = match?.[2];
9758
+ if (!key || !Object.hasOwn(aliases10, key) || !value)
9759
+ throw new Error(`Unknown or malformed rectangularbar token "${token}"`);
9760
+ const property = aliases10[key];
9761
+ if (Object.hasOwn(props, property))
9762
+ throw new Error(`Duplicate rectangularbar property "${property}"`);
9763
+ props[property] = value;
9764
+ }
9765
+ return rectangularBarModelDefinitionSchema.parse(props);
9766
+ }
9767
+ var model33 = defineModel({
9768
+ name: "rectangularbar",
9769
+ schema: rectangularBarModelDefinitionSchema,
9770
+ parse: parseRectangularBarModelParams
9771
+ });
9772
+ function register33(registry2) {
9773
+ registry2.register(model33);
9774
+ }
9775
+ var length19 = external_exports.union([
9776
+ external_exports.number(),
9777
+ external_exports.string().regex(/^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
9778
+ ]).pipe(modelLengthSchema);
9779
+ var positiveLength14 = length19.refine(
9780
+ (value) => value > 0,
9781
+ "Length must be positive"
9782
+ );
9783
+ var nonnegativeLength6 = length19.refine(
9784
+ (value) => value >= 0,
9785
+ "Length cannot be negative"
9786
+ );
9787
+ var shape28 = {
9788
+ width: positiveLength14,
9789
+ height: positiveLength14,
9790
+ wallThickness: positiveLength14,
9791
+ length: positiveLength14,
9792
+ outerRadius: nonnegativeLength6.default(0),
9793
+ innerRadius: nonnegativeLength6.default(0)
9794
+ };
9795
+ function validate27(p, context) {
9796
+ if (2 * p.wallThickness >= Math.min(p.width, p.height))
9797
+ context.addIssue({
9798
+ code: "custom",
9799
+ message: "Invalid rectangulartube dimensions: constraint 1"
9800
+ });
9801
+ if (2 * p.outerRadius >= Math.min(p.width, p.height))
9802
+ context.addIssue({
9803
+ code: "custom",
9804
+ message: "Invalid rectangulartube dimensions: constraint 2"
9805
+ });
9806
+ if (2 * p.innerRadius >= Math.min(p.width, p.height) - 2 * p.wallThickness)
9807
+ context.addIssue({
9808
+ code: "custom",
9809
+ message: "Invalid rectangulartube dimensions: constraint 3"
9810
+ });
9811
+ if (p.wallThickness <= (1 - Math.SQRT1_2) * (p.outerRadius - p.innerRadius))
9812
+ context.addIssue({
9813
+ code: "custom",
9814
+ message: "Invalid rectangulartube dimensions: constraint 4"
9815
+ });
9816
+ }
9817
+ var rectangularTubeModelPropsSchema = external_exports.object(shape28).strict().superRefine(validate27);
9818
+ var rectangularTubeModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rectangulartube"), ...shape28 }).strict().superRefine(validate27);
9819
+ var aliases11 = {
9820
+ w: "width",
9821
+ h: "height",
9822
+ wall: "wallThickness",
9823
+ l: "length",
9824
+ outerr: "outerRadius",
9825
+ innerr: "innerRadius",
9826
+ width: "width",
9827
+ height: "height",
9828
+ wallthickness: "wallThickness",
9829
+ length: "length",
9830
+ outerradius: "outerRadius",
9831
+ innerradius: "innerRadius"
9832
+ };
9833
+ function parseRectangularTubeModelParams(raw) {
9834
+ const [name, ...tokens] = splitModelStringTokens(raw.string);
9835
+ if (raw.fn !== "rectangulartube" || name?.toLowerCase() !== "rectangulartube")
9836
+ throw new Error("Expected rectangulartube without inline values");
9837
+ const props = { fn: "rectangulartube" };
9838
+ for (const token of tokens) {
9839
+ const match = token.match(/^([a-z]+)(.*)$/i);
9840
+ const key = match?.[1]?.toLowerCase();
9841
+ const value = match?.[2];
9842
+ if (!key || !Object.hasOwn(aliases11, key) || !value)
9843
+ throw new Error(`Unknown or malformed rectangulartube token "${token}"`);
9844
+ const property = aliases11[key];
9845
+ if (Object.hasOwn(props, property))
9846
+ throw new Error(`Duplicate rectangulartube property "${property}"`);
9847
+ props[property] = value;
9362
9848
  }
9363
- return plainBushingModelDefinitionSchema.parse(props);
9849
+ return rectangularTubeModelDefinitionSchema.parse(props);
9364
9850
  }
9365
- var model28 = defineModel({
9366
- name: "plainbushing",
9367
- schema: plainBushingModelDefinitionSchema,
9368
- parse: parsePlainBushingModelParams,
9369
- normalizeString: (value) => normalizeModelStringFlags(
9370
- value,
9371
- stringFlags10,
9372
- parsePlainBushingModelParams,
9373
- omittedStringFlags10
9374
- )
9851
+ var model34 = defineModel({
9852
+ name: "rectangulartube",
9853
+ schema: rectangularTubeModelDefinitionSchema,
9854
+ parse: parseRectangularTubeModelParams
9375
9855
  });
9376
- function register28(registry2) {
9377
- registry2.register(model28);
9856
+ function register34(registry2) {
9857
+ registry2.register(model34);
9378
9858
  }
9379
9859
  var stringFlags11 = {
9380
9860
  setscrew: "mount(setscrew)",
@@ -9382,19 +9862,19 @@ var stringFlags11 = {
9382
9862
  righthanded: "threadhand(right)"
9383
9863
  };
9384
9864
  var omittedStringFlags11 = ["righthanded"];
9385
- var length14 = external_exports.union([
9865
+ var length20 = external_exports.union([
9386
9866
  external_exports.number().finite(),
9387
9867
  external_exports.string().regex(
9388
9868
  /^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i,
9389
9869
  "Expected a complete length with a supported unit"
9390
9870
  ).transform((value) => value.toLowerCase())
9391
9871
  ]).pipe(modelLengthSchema);
9392
- var positive5 = length14.refine((value) => value > 0, "Length must be positive");
9393
- var nonnegative4 = length14.refine(
9872
+ var positive5 = length20.refine((value) => value > 0, "Length must be positive");
9873
+ var nonnegative4 = length20.refine(
9394
9874
  (value) => value >= 0,
9395
9875
  "Length cannot be negative"
9396
9876
  );
9397
- var shape23 = {
9877
+ var shape29 = {
9398
9878
  boreDiameter: positive5,
9399
9879
  outerDiameter: positive5,
9400
9880
  boreBDiameter: positive5.optional(),
@@ -9419,7 +9899,7 @@ function resolve6(props) {
9419
9899
  screwAngle: (props.screwAngle % 360 + 360) % 360
9420
9900
  };
9421
9901
  }
9422
- function validate22(props, context) {
9902
+ function validate28(props, context) {
9423
9903
  const p = resolve6(props);
9424
9904
  const issue = (message) => context.addIssue({ code: "custom", message });
9425
9905
  const diameter = hexSocketBoltDimensions[p.metricSize].diameter;
@@ -9443,8 +9923,8 @@ function validate22(props, context) {
9443
9923
  if (p.length - 2 * p.screwEndOffset <= diameter)
9444
9924
  issue("Each end must have a separate, nonintersecting screw-hole plane");
9445
9925
  }
9446
- var rigidCouplerModelPropsSchema = external_exports.object(shape23).strict().superRefine(validate22).transform(resolve6);
9447
- var rigidCouplerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rigidcoupler"), ...shape23 }).strict().superRefine(validate22).transform((props) => ({ fn: props.fn, ...resolve6(props) }));
9926
+ var rigidCouplerModelPropsSchema = external_exports.object(shape29).strict().superRefine(validate28).transform(resolve6);
9927
+ var rigidCouplerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rigidcoupler"), ...shape29 }).strict().superRefine(validate28).transform((props) => ({ fn: props.fn, ...resolve6(props) }));
9448
9928
  function getRigidCouplerDimensions(input) {
9449
9929
  const p = rigidCouplerModelPropsSchema.parse(input);
9450
9930
  const threadDiameter = hexSocketBoltDimensions[p.metricSize].diameter;
@@ -9544,7 +10024,7 @@ function parseRigidCouplerModelParams(raw) {
9544
10024
  ...props
9545
10025
  });
9546
10026
  }
9547
- var model29 = defineModel({
10027
+ var model35 = defineModel({
9548
10028
  name: "rigidcoupler",
9549
10029
  schema: rigidCouplerModelDefinitionSchema,
9550
10030
  parse: parseRigidCouplerModelParams,
@@ -9555,10 +10035,10 @@ var model29 = defineModel({
9555
10035
  omittedStringFlags11
9556
10036
  )
9557
10037
  });
9558
- function register29(registry2) {
9559
- registry2.register(model29);
10038
+ function register35(registry2) {
10039
+ registry2.register(model35);
9560
10040
  }
9561
- var positiveLength9 = external_exports.union([
10041
+ var positiveLength15 = external_exports.union([
9562
10042
  external_exports.number(),
9563
10043
  external_exports.string().regex(/^(?:\d+(?:\.\d+)?|\.\d+)(?:mm|cm|m|in|inch)?$/i).transform((value) => value.toLowerCase())
9564
10044
  ]).pipe(modelLengthSchema).refine((value) => value > 0, "Length must be positive");
@@ -9613,26 +10093,26 @@ var setscrewDimensions = {
9613
10093
  }
9614
10094
  };
9615
10095
  var setscrewMetricSizeSchema = external_exports.enum(["M3", "M4", "M5", "M6"]);
9616
- var shape24 = {
10096
+ var shape30 = {
9617
10097
  iso4029: external_exports.literal(true).default(true),
9618
10098
  metricSize: setscrewMetricSizeSchema,
9619
- length: positiveLength9,
10099
+ length: positiveLength15,
9620
10100
  hexSocket: external_exports.literal(true).default(true),
9621
10101
  cupPoint: external_exports.literal(true).default(true),
9622
10102
  leftHand: external_exports.boolean().default(false),
9623
10103
  showThreads: external_exports.boolean().default(true),
9624
- diameter: positiveLength9.optional(),
9625
- threadPitch: positiveLength9.optional(),
9626
- socketAcrossFlats: positiveLength9.optional(),
9627
- socketDepth: positiveLength9.optional(),
9628
- cupDiameter: positiveLength9.optional(),
9629
- cupDepth: positiveLength9.optional(),
9630
- pointTaperLength: positiveLength9.optional(),
9631
- mouthChamfer: positiveLength9.optional(),
9632
- threadRootDiameter: positiveLength9.optional(),
9633
- threadPitchDiameter: positiveLength9.optional()
9634
- };
9635
- var validate23 = (props, context) => {
10104
+ diameter: positiveLength15.optional(),
10105
+ threadPitch: positiveLength15.optional(),
10106
+ socketAcrossFlats: positiveLength15.optional(),
10107
+ socketDepth: positiveLength15.optional(),
10108
+ cupDiameter: positiveLength15.optional(),
10109
+ cupDepth: positiveLength15.optional(),
10110
+ pointTaperLength: positiveLength15.optional(),
10111
+ mouthChamfer: positiveLength15.optional(),
10112
+ threadRootDiameter: positiveLength15.optional(),
10113
+ threadPitchDiameter: positiveLength15.optional()
10114
+ };
10115
+ var validate29 = (props, context) => {
9636
10116
  const dimensions5 = setscrewDimensions[props.metricSize];
9637
10117
  for (const key of Object.keys(dimensions5)) {
9638
10118
  if (props[key] !== void 0 && Math.abs(props[key] - dimensions5[key]) > 1e-9)
@@ -9649,9 +10129,9 @@ var validate23 = (props, context) => {
9649
10129
  message: "Length must leave material between fixed end features"
9650
10130
  });
9651
10131
  };
9652
- var setscrewModelPropsSchema = external_exports.object(shape24).strict().superRefine(validate23).transform((props) => ({ ...props, ...setscrewDimensions[props.metricSize] }));
9653
- var setscrewModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("setscrew"), ...shape24 }).strict().superRefine(validate23).transform((props) => ({ ...props, ...setscrewDimensions[props.metricSize] }));
9654
- var aliases6 = {
10132
+ var setscrewModelPropsSchema = external_exports.object(shape30).strict().superRefine(validate29).transform((props) => ({ ...props, ...setscrewDimensions[props.metricSize] }));
10133
+ var setscrewModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("setscrew"), ...shape30 }).strict().superRefine(validate29).transform((props) => ({ ...props, ...setscrewDimensions[props.metricSize] }));
10134
+ var aliases12 = {
9655
10135
  m: "metricSize",
9656
10136
  metricsize: "metricSize",
9657
10137
  l: "length",
@@ -9700,7 +10180,7 @@ function parseSetScrewModelParams(raw) {
9700
10180
  property = flags5[key];
9701
10181
  parsed = !["righthanded", "nothreads"].includes(key);
9702
10182
  } else {
9703
- property = aliases6[key] ?? "";
10183
+ property = aliases12[key] ?? "";
9704
10184
  if (!property || !value)
9705
10185
  throw new Error(`Unknown or missing setscrew token ${token}`);
9706
10186
  if (property === "metricSize") {
@@ -9723,13 +10203,13 @@ function parseSetScrewModelParams(raw) {
9723
10203
  }
9724
10204
  return setscrewModelDefinitionSchema.parse({ fn: "setscrew", ...props });
9725
10205
  }
9726
- var model30 = defineModel({
10206
+ var model36 = defineModel({
9727
10207
  name: "setscrew",
9728
10208
  schema: setscrewModelDefinitionSchema,
9729
10209
  parse: parseSetScrewModelParams
9730
10210
  });
9731
- function register30(registry2) {
9732
- registry2.register(model30);
10211
+ function register36(registry2) {
10212
+ registry2.register(model36);
9733
10213
  }
9734
10214
  var stringFlags12 = {
9735
10215
  setscrew: "mount(setscrew)",
@@ -9737,19 +10217,19 @@ var stringFlags12 = {
9737
10217
  righthanded: "threadhand(right)"
9738
10218
  };
9739
10219
  var omittedStringFlags12 = ["righthanded"];
9740
- var length15 = external_exports.union([
10220
+ var length21 = external_exports.union([
9741
10221
  external_exports.number().finite(),
9742
10222
  external_exports.string().regex(
9743
10223
  /^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i,
9744
10224
  "Expected a complete length with a supported unit"
9745
10225
  ).transform((value) => value.toLowerCase())
9746
10226
  ]).pipe(modelLengthSchema);
9747
- var positive6 = length15.refine((value) => value > 0, "Length must be positive");
9748
- var nonnegative5 = length15.refine(
10227
+ var positive6 = length21.refine((value) => value > 0, "Length must be positive");
10228
+ var nonnegative5 = length21.refine(
9749
10229
  (value) => value >= 0,
9750
10230
  "Length cannot be negative"
9751
10231
  );
9752
- var shape25 = {
10232
+ var shape31 = {
9753
10233
  boreDiameter: positive6,
9754
10234
  outerDiameter: positive6,
9755
10235
  width: positive6,
@@ -9771,7 +10251,7 @@ function resolve7(props) {
9771
10251
  screwAngle: (props.screwAngle % 360 + 360) % 360
9772
10252
  };
9773
10253
  }
9774
- function validate24(props, context) {
10254
+ function validate30(props, context) {
9775
10255
  const p = resolve7(props);
9776
10256
  const issue = (message) => context.addIssue({ code: "custom", message });
9777
10257
  const diameter = hexSocketBoltDimensions[p.metricSize].diameter;
@@ -9788,8 +10268,8 @@ function validate24(props, context) {
9788
10268
  if (p.screwZ - diameter / 2 <= p.chamfer || p.screwZ + diameter / 2 >= p.width - p.chamfer)
9789
10269
  issue("Screw hole must clear both end faces and chamfers");
9790
10270
  }
9791
- var shaftCollarModelPropsSchema = external_exports.object(shape25).strict().superRefine(validate24).transform(resolve7);
9792
- var shaftCollarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("shaftcollar"), ...shape25 }).strict().superRefine(validate24).transform((props) => ({ fn: props.fn, ...resolve7(props) }));
10271
+ var shaftCollarModelPropsSchema = external_exports.object(shape31).strict().superRefine(validate30).transform(resolve7);
10272
+ var shaftCollarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("shaftcollar"), ...shape31 }).strict().superRefine(validate30).transform((props) => ({ fn: props.fn, ...resolve7(props) }));
9793
10273
  function getShaftCollarDimensions(input) {
9794
10274
  const p = shaftCollarModelPropsSchema.parse(input);
9795
10275
  const threadDiameter = hexSocketBoltDimensions[p.metricSize].diameter;
@@ -9863,7 +10343,7 @@ function parseShaftCollarModelParams(raw) {
9863
10343
  }
9864
10344
  return shaftCollarModelDefinitionSchema.parse({ fn: "shaftcollar", ...props });
9865
10345
  }
9866
- var model31 = defineModel({
10346
+ var model37 = defineModel({
9867
10347
  name: "shaftcollar",
9868
10348
  schema: shaftCollarModelDefinitionSchema,
9869
10349
  parse: parseShaftCollarModelParams,
@@ -9874,27 +10354,27 @@ var model31 = defineModel({
9874
10354
  omittedStringFlags12
9875
10355
  )
9876
10356
  });
9877
- function register31(registry2) {
9878
- registry2.register(model31);
10357
+ function register37(registry2) {
10358
+ registry2.register(model37);
9879
10359
  }
9880
- var length16 = external_exports.union([
10360
+ var length22 = external_exports.union([
9881
10361
  external_exports.number(),
9882
10362
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
9883
10363
  ]).pipe(modelLengthSchema);
9884
- var positiveLength10 = length16.refine(
10364
+ var positiveLength16 = length22.refine(
9885
10365
  (value) => value > 0,
9886
10366
  "Length must be positive"
9887
10367
  );
9888
- var shape26 = {
9889
- innerDiameter: positiveLength10,
9890
- outerDiameter: positiveLength10,
10368
+ var shape32 = {
10369
+ innerDiameter: positiveLength16,
10370
+ outerDiameter: positiveLength16,
9891
10371
  /** End-plane distance, including the rim chamfers. */
9892
- length: positiveLength10,
10372
+ length: positiveLength16,
9893
10373
  round: external_exports.literal(true).default(true),
9894
10374
  /** Equal axial/radial setbacks at all four 45-degree rims. */
9895
- chamfer: length16.refine((value) => value >= 0, "Chamfer cannot be negative").default(0)
10375
+ chamfer: length22.refine((value) => value >= 0, "Chamfer cannot be negative").default(0)
9896
10376
  };
9897
- function validate25(props, context) {
10377
+ function validate31(props, context) {
9898
10378
  if (props.outerDiameter <= props.innerDiameter)
9899
10379
  context.addIssue({
9900
10380
  code: "custom",
@@ -9914,9 +10394,9 @@ function validate25(props, context) {
9914
10394
  message: "Chamfers must leave positive straight bore length"
9915
10395
  });
9916
10396
  }
9917
- var spacerModelPropsSchema = external_exports.object(shape26).strict().superRefine(validate25);
9918
- var spacerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("spacer"), ...shape26 }).strict().superRefine(validate25);
9919
- var aliases7 = {
10397
+ var spacerModelPropsSchema = external_exports.object(shape32).strict().superRefine(validate31);
10398
+ var spacerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("spacer"), ...shape32 }).strict().superRefine(validate31);
10399
+ var aliases13 = {
9920
10400
  id: "innerDiameter",
9921
10401
  innerdiameter: "innerDiameter",
9922
10402
  od: "outerDiameter",
@@ -9940,8 +10420,8 @@ function parseSpacerModelParams(raw) {
9940
10420
  if (key === "round" && value === "") {
9941
10421
  property = "round";
9942
10422
  parsed = true;
9943
- } else if (key && Object.hasOwn(aliases7, key) && value) {
9944
- property = aliases7[key];
10423
+ } else if (key && Object.hasOwn(aliases13, key) && value) {
10424
+ property = aliases13[key];
9945
10425
  parsed = value;
9946
10426
  } else throw new Error(`Unknown or malformed spacer token "${token}"`);
9947
10427
  if (Object.hasOwn(props, property))
@@ -9950,34 +10430,34 @@ function parseSpacerModelParams(raw) {
9950
10430
  }
9951
10431
  return spacerModelDefinitionSchema.parse(props);
9952
10432
  }
9953
- var model32 = defineModel({
10433
+ var model38 = defineModel({
9954
10434
  name: "spacer",
9955
10435
  schema: spacerModelDefinitionSchema,
9956
10436
  parse: parseSpacerModelParams
9957
10437
  });
9958
- function register32(registry2) {
9959
- registry2.register(model32);
10438
+ function register38(registry2) {
10439
+ registry2.register(model38);
9960
10440
  }
9961
- var length17 = external_exports.union([
10441
+ var length23 = external_exports.union([
9962
10442
  external_exports.number(),
9963
10443
  external_exports.string().regex(/^(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i)
9964
10444
  ]).pipe(modelLengthSchema);
9965
- var positiveLength11 = length17.refine(
10445
+ var positiveLength17 = length23.refine(
9966
10446
  (value) => value > 0,
9967
10447
  "Length must be positive"
9968
10448
  );
9969
- var shape27 = {
9970
- innerDiameter: positiveLength11,
9971
- outerDiameter: positiveLength11,
10449
+ var shape33 = {
10450
+ innerDiameter: positiveLength17,
10451
+ outerDiameter: positiveLength17,
9972
10452
  /** Axial thickness of the rectangular radial/vertical section. */
9973
- thickness: positiveLength11,
10453
+ thickness: positiveLength17,
9974
10454
  /** End-to-end axial displacement, independent of section thickness. */
9975
- rise: length17.refine((value) => value >= 0, "Rise cannot be negative"),
10455
+ rise: length23.refine((value) => value >= 0, "Rise cannot be negative"),
9976
10456
  gapAngle: external_exports.number().finite().gt(0).lt(360),
9977
10457
  rectangular: external_exports.literal(true).default(true),
9978
10458
  leftHanded: external_exports.boolean().default(false)
9979
10459
  };
9980
- function validate26(p, context) {
10460
+ function validate32(p, context) {
9981
10461
  if (p.innerDiameter >= p.outerDiameter)
9982
10462
  context.addIssue({
9983
10463
  code: "custom",
@@ -9990,8 +10470,8 @@ function validate26(p, context) {
9990
10470
  message: "The washer envelope and volume must remain finite"
9991
10471
  });
9992
10472
  }
9993
- var splitWasherModelPropsSchema = external_exports.object(shape27).strict().superRefine(validate26);
9994
- var splitWasherModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("splitwasher"), ...shape27 }).strict().superRefine(validate26);
10473
+ var splitWasherModelPropsSchema = external_exports.object(shape33).strict().superRefine(validate32);
10474
+ var splitWasherModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("splitwasher"), ...shape33 }).strict().superRefine(validate32);
9995
10475
  var lengths16 = {
9996
10476
  id: "innerDiameter",
9997
10477
  innerdiameter: "innerDiameter",
@@ -10036,20 +10516,20 @@ function parseSplitWasherModelParams(raw) {
10036
10516
  }
10037
10517
  return splitWasherModelDefinitionSchema.parse(props);
10038
10518
  }
10039
- var model33 = defineModel({
10519
+ var model39 = defineModel({
10040
10520
  name: "splitwasher",
10041
10521
  schema: splitWasherModelDefinitionSchema,
10042
10522
  parse: parseSplitWasherModelParams
10043
10523
  });
10044
- function register33(registry2) {
10045
- registry2.register(model33);
10524
+ function register39(registry2) {
10525
+ registry2.register(model39);
10046
10526
  }
10047
- var length18 = external_exports.union([
10527
+ var length24 = external_exports.union([
10048
10528
  external_exports.number(),
10049
10529
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
10050
10530
  ]).pipe(modelLengthSchema);
10051
- var positiveLength12 = length18.refine((value) => value > 0);
10052
- var nonnegativeLength2 = length18.refine((value) => value >= 0);
10531
+ var positiveLength18 = length24.refine((value) => value > 0);
10532
+ var nonnegativeLength7 = length24.refine((value) => value >= 0);
10053
10533
  var threadedRodCoarsePitches = {
10054
10534
  M2: 0.4,
10055
10535
  "M2.5": 0.45,
@@ -10076,13 +10556,13 @@ var threadedRodMetricSizeSchema = external_exports.enum([
10076
10556
  "M16",
10077
10557
  "M20"
10078
10558
  ]);
10079
- var shape28 = {
10559
+ var shape34 = {
10080
10560
  metricSize: threadedRodMetricSizeSchema,
10081
10561
  /** Overall end-plane distance, including terminal chamfers. */
10082
- length: positiveLength12,
10562
+ length: positiveLength18,
10083
10563
  /** Equal axial and radial setbacks of the two 45-degree outer chamfers. */
10084
- chamfer: nonnegativeLength2.default(0),
10085
- threadPitch: positiveLength12.optional(),
10564
+ chamfer: nonnegativeLength7.default(0),
10565
+ threadPitch: positiveLength18.optional(),
10086
10566
  leftHand: external_exports.boolean().default(false)
10087
10567
  };
10088
10568
  function resolve8(props) {
@@ -10091,7 +10571,7 @@ function resolve8(props) {
10091
10571
  threadPitch: props.threadPitch ?? threadedRodCoarsePitches[props.metricSize]
10092
10572
  };
10093
10573
  }
10094
- function validate27(props, context) {
10574
+ function validate33(props, context) {
10095
10575
  const diameter = Number(props.metricSize.slice(1));
10096
10576
  const pitch = resolve8(props).threadPitch;
10097
10577
  if (diameter - 1.226869 * pitch <= 0)
@@ -10107,8 +10587,8 @@ function validate27(props, context) {
10107
10587
  message: "Chamfer must leave flat end faces and separate end chamfers"
10108
10588
  });
10109
10589
  }
10110
- var threadedRodModelPropsSchema = external_exports.object(shape28).strict().superRefine(validate27).transform(resolve8);
10111
- var threadedRodModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("threadedrod"), ...shape28 }).strict().superRefine(validate27).transform((model392) => ({ fn: model392.fn, ...resolve8(model392) }));
10590
+ var threadedRodModelPropsSchema = external_exports.object(shape34).strict().superRefine(validate33).transform(resolve8);
10591
+ var threadedRodModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("threadedrod"), ...shape34 }).strict().superRefine(validate33).transform((model452) => ({ fn: model452.fn, ...resolve8(model452) }));
10112
10592
  function getThreadedRodDimensions(input) {
10113
10593
  const props = threadedRodModelPropsSchema.parse(input);
10114
10594
  const diameter = Number(props.metricSize.slice(1));
@@ -10176,21 +10656,21 @@ function normalizeThreadedRodModelString(value) {
10176
10656
  return [lower === "lefthanded" ? lower : token];
10177
10657
  }).join("_");
10178
10658
  }
10179
- var model34 = defineModel({
10659
+ var model40 = defineModel({
10180
10660
  name: "threadedrod",
10181
10661
  schema: threadedRodModelDefinitionSchema,
10182
10662
  parse: parseThreadedRodModelParams,
10183
10663
  normalizeString: normalizeThreadedRodModelString
10184
10664
  });
10185
- function register34(registry2) {
10186
- registry2.register(model34);
10665
+ function register40(registry2) {
10666
+ registry2.register(model40);
10187
10667
  }
10188
- var length19 = external_exports.union([
10668
+ var length25 = external_exports.union([
10189
10669
  external_exports.number(),
10190
10670
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
10191
10671
  ]).pipe(modelLengthSchema);
10192
- var positive7 = length19.refine((value) => value > 0, "Length must be positive");
10193
- var shape29 = {
10672
+ var positive7 = length25.refine((value) => value > 0, "Length must be positive");
10673
+ var shape35 = {
10194
10674
  outerDiameter: positive7.default(8),
10195
10675
  wireDiameter: positive7.default(0.8),
10196
10676
  /** Fractional turns set the relative leg direction. */
@@ -10204,7 +10684,7 @@ var shape29 = {
10204
10684
  function normalize7(p) {
10205
10685
  return { ...p, pitch: p.pitch ?? p.wireDiameter * 1.25 };
10206
10686
  }
10207
- function validate28(p, context) {
10687
+ function validate34(p, context) {
10208
10688
  if (p.outerDiameter < 3 * p.wireDiameter)
10209
10689
  context.addIssue({
10210
10690
  code: "custom",
@@ -10226,8 +10706,8 @@ function validate28(p, context) {
10226
10706
  message: "Spring dimensions must remain finite"
10227
10707
  });
10228
10708
  }
10229
- var torsionSpringModelPropsSchema = external_exports.object(shape29).strict().superRefine(validate28).transform(normalize7);
10230
- var torsionSpringModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("torsionspring"), ...shape29 }).strict().superRefine(validate28).transform((p) => ({ ...normalize7(p), fn: p.fn }));
10709
+ var torsionSpringModelPropsSchema = external_exports.object(shape35).strict().superRefine(validate34).transform(normalize7);
10710
+ var torsionSpringModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("torsionspring"), ...shape35 }).strict().superRefine(validate34).transform((p) => ({ ...normalize7(p), fn: p.fn }));
10231
10711
  function getTorsionSpringDimensions(input) {
10232
10712
  const p = torsionSpringModelPropsSchema.parse(input);
10233
10713
  const meanRadius = (p.outerDiameter - p.wireDiameter) / 2;
@@ -10312,19 +10792,19 @@ function parseTorsionSpringModelParams(raw) {
10312
10792
  }
10313
10793
  return torsionSpringModelDefinitionSchema.parse(props);
10314
10794
  }
10315
- var model35 = defineModel({
10795
+ var model41 = defineModel({
10316
10796
  name: "torsionspring",
10317
10797
  schema: torsionSpringModelDefinitionSchema,
10318
10798
  parse: parseTorsionSpringModelParams
10319
10799
  });
10320
- function register35(registry2) {
10321
- registry2.register(model35);
10800
+ function register41(registry2) {
10801
+ registry2.register(model41);
10322
10802
  }
10323
10803
  var stringFlags13 = {
10324
10804
  fourtsolid: "profile(fourtsolid)"
10325
10805
  };
10326
10806
  var omittedStringFlags13 = [];
10327
- var shape30 = {
10807
+ var shape36 = {
10328
10808
  width: positiveGearLengthSchema.default(20),
10329
10809
  height: positiveGearLengthSchema.default(20),
10330
10810
  length: positiveGearLengthSchema.default(100),
@@ -10337,7 +10817,7 @@ var shape30 = {
10337
10817
  boreDiameter: nonnegativeGearLengthSchema.default(0),
10338
10818
  cornerRadius: nonnegativeGearLengthSchema.default(0)
10339
10819
  };
10340
- function validate29(props, context) {
10820
+ function validate35(props, context) {
10341
10821
  const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
10342
10822
  const halfSize = Math.min(props.width, props.height) / 2;
10343
10823
  const depth = props.lipThickness + props.pocketDepth;
@@ -10365,8 +10845,8 @@ function validate29(props, context) {
10365
10845
  "boreDiameter"
10366
10846
  );
10367
10847
  }
10368
- var tSlotExtrusionModelPropsSchema = external_exports.object(shape30).strict().superRefine(validate29);
10369
- var tSlotExtrusionModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotextrusion"), ...shape30 }).strict().superRefine(validate29);
10848
+ var tSlotExtrusionModelPropsSchema = external_exports.object(shape36).strict().superRefine(validate35);
10849
+ var tSlotExtrusionModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotextrusion"), ...shape36 }).strict().superRefine(validate35);
10370
10850
  var lengths19 = {
10371
10851
  w: "width",
10372
10852
  width: "width",
@@ -10411,7 +10891,7 @@ function parseTSlotExtrusionModelParams(raw) {
10411
10891
  }
10412
10892
  return tSlotExtrusionModelDefinitionSchema.parse(props);
10413
10893
  }
10414
- var model36 = defineModel({
10894
+ var model42 = defineModel({
10415
10895
  name: "tslotextrusion",
10416
10896
  schema: tSlotExtrusionModelDefinitionSchema,
10417
10897
  parse: parseTSlotExtrusionModelParams,
@@ -10422,14 +10902,14 @@ var model36 = defineModel({
10422
10902
  omittedStringFlags13
10423
10903
  )
10424
10904
  });
10425
- function register36(registry2) {
10426
- registry2.register(model36);
10905
+ function register42(registry2) {
10906
+ registry2.register(model42);
10427
10907
  }
10428
10908
  var stringFlags14 = {
10429
10909
  righttriangle: "shape(righttriangle)"
10430
10910
  };
10431
10911
  var omittedStringFlags14 = [];
10432
- var shape31 = {
10912
+ var shape37 = {
10433
10913
  width: positiveGearLengthSchema.default(40),
10434
10914
  height: positiveGearLengthSchema.default(40),
10435
10915
  thickness: positiveGearLengthSchema.default(4),
@@ -10442,22 +10922,22 @@ var shape31 = {
10442
10922
  /** Ligament between each slot and its parallel outer plate edge. */
10443
10923
  edgeMargin: positiveGearLengthSchema.default(1)
10444
10924
  };
10445
- function validate30(props, context) {
10925
+ function validate36(props, context) {
10446
10926
  const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
10447
- const [width10, length20] = props.slot;
10448
- if (length20 < width10) {
10927
+ const [width10, length26] = props.slot;
10928
+ if (length26 < width10) {
10449
10929
  issue("Slot length must be at least its width", "slot");
10450
10930
  return;
10451
10931
  }
10452
10932
  const radius = width10 / 2;
10453
- const halfStraight = (length20 - width10) / 2;
10933
+ const halfStraight = (length26 - width10) / 2;
10454
10934
  const inset = props.edgeMargin + radius;
10455
10935
  const [x, y] = props.centers;
10456
10936
  if (!Number.isFinite(inset)) {
10457
10937
  issue("Derived slot centers must be finite", "edgeMargin");
10458
10938
  return;
10459
10939
  }
10460
- if (x <= length20 / 2 || y <= length20 / 2)
10940
+ if (x <= length26 / 2 || y <= length26 / 2)
10461
10941
  issue("Slots must leave material at the right-angle corner", "centers");
10462
10942
  const normalRatio = Math.min(props.width, props.height) / Math.max(props.width, props.height);
10463
10943
  const capSupport = radius / Math.min(props.width, props.height) * Math.hypot(1, normalRatio);
@@ -10473,18 +10953,18 @@ function validate30(props, context) {
10473
10953
  if (Math.hypot(dx, dy) <= width10)
10474
10954
  issue("The two slots must retain a positive separating ligament", "centers");
10475
10955
  }
10476
- var tSlotGussetModelPropsSchema = external_exports.object(shape31).strict().superRefine(validate30);
10477
- var tSlotGussetModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotgusset"), ...shape31 }).strict().superRefine(validate30);
10956
+ var tSlotGussetModelPropsSchema = external_exports.object(shape37).strict().superRefine(validate36);
10957
+ var tSlotGussetModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotgusset"), ...shape37 }).strict().superRefine(validate36);
10478
10958
  function getTSlotGussetMountingSlots(input = {}) {
10479
10959
  const props = tSlotGussetModelPropsSchema.parse(input);
10480
- const [width10, length20] = props.slot;
10960
+ const [width10, length26] = props.slot;
10481
10961
  const inset = props.edgeMargin + width10 / 2;
10482
10962
  return [
10483
10963
  {
10484
10964
  center: { x: props.centers[0], y: inset, z: 0 },
10485
10965
  orientation: 0,
10486
10966
  width: width10,
10487
- length: length20,
10967
+ length: length26,
10488
10968
  depth: props.thickness,
10489
10969
  direction: { x: 0, y: 0, z: 1 }
10490
10970
  },
@@ -10492,7 +10972,7 @@ function getTSlotGussetMountingSlots(input = {}) {
10492
10972
  center: { x: inset, y: props.centers[1], z: 0 },
10493
10973
  orientation: 90,
10494
10974
  width: width10,
10495
- length: length20,
10975
+ length: length26,
10496
10976
  depth: props.thickness,
10497
10977
  direction: { x: 0, y: 0, z: 1 }
10498
10978
  }
@@ -10539,7 +11019,7 @@ function parseTSlotGussetModelParams(raw) {
10539
11019
  }
10540
11020
  return tSlotGussetModelDefinitionSchema.parse(props);
10541
11021
  }
10542
- var model37 = defineModel({
11022
+ var model43 = defineModel({
10543
11023
  name: "tslotgusset",
10544
11024
  schema: tSlotGussetModelDefinitionSchema,
10545
11025
  parse: parseTSlotGussetModelParams,
@@ -10550,10 +11030,10 @@ var model37 = defineModel({
10550
11030
  omittedStringFlags14
10551
11031
  )
10552
11032
  });
10553
- function register37(registry2) {
10554
- registry2.register(model37);
11033
+ function register43(registry2) {
11034
+ registry2.register(model43);
10555
11035
  }
10556
- var shape32 = {
11036
+ var shape38 = {
10557
11037
  width: positiveGearLengthSchema.default(20),
10558
11038
  /** Equal leg extents from the virtual intersection of the inside flats. */
10559
11039
  legLength: positiveGearLengthSchema.default(40),
@@ -10565,7 +11045,7 @@ var shape32 = {
10565
11045
  holeOffset: positiveGearLengthSchema.default(20),
10566
11046
  bendRadius: nonnegativeGearLengthSchema.default(0)
10567
11047
  };
10568
- function validate31(props, context) {
11048
+ function validate37(props, context) {
10569
11049
  const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
10570
11050
  if (!Number.isFinite(props.bendRadius + props.thickness)) {
10571
11051
  issue("Outside bend radius must be finite", "bendRadius");
@@ -10583,8 +11063,8 @@ function validate31(props, context) {
10583
11063
  if (props.holeOffset + radius >= props.legLength)
10584
11064
  issue("Holes must leave material at the free leg ends", "holeOffset");
10585
11065
  }
10586
- var tSlotInsideCornerModelPropsSchema = external_exports.object(shape32).strict().superRefine(validate31);
10587
- var tSlotInsideCornerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotinsidecorner"), ...shape32 }).strict().superRefine(validate31);
11066
+ var tSlotInsideCornerModelPropsSchema = external_exports.object(shape38).strict().superRefine(validate37);
11067
+ var tSlotInsideCornerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotinsidecorner"), ...shape38 }).strict().superRefine(validate37);
10588
11068
  var lengths21 = {
10589
11069
  w: "width",
10590
11070
  width: "width",
@@ -10622,13 +11102,13 @@ function parseTSlotInsideCornerModelParams(raw) {
10622
11102
  }
10623
11103
  return tSlotInsideCornerModelDefinitionSchema.parse(props);
10624
11104
  }
10625
- var model38 = defineModel({
11105
+ var model44 = defineModel({
10626
11106
  name: "tslotinsidecorner",
10627
11107
  schema: tSlotInsideCornerModelDefinitionSchema,
10628
11108
  parse: parseTSlotInsideCornerModelParams
10629
11109
  });
10630
- function register38(registry2) {
10631
- registry2.register(model38);
11110
+ function register44(registry2) {
11111
+ registry2.register(model44);
10632
11112
  }
10633
11113
  function getNemaMotorReferencePoints(input) {
10634
11114
  const p = nemaMotorModelPropsSchema.parse(input);
@@ -10712,7 +11192,13 @@ var modelDefinitionSchema = external_exports.union([
10712
11192
  model35.schema,
10713
11193
  model36.schema,
10714
11194
  model37.schema,
10715
- model38.schema
11195
+ model38.schema,
11196
+ model39.schema,
11197
+ model40.schema,
11198
+ model41.schema,
11199
+ model42.schema,
11200
+ model43.schema,
11201
+ model44.schema
10716
11202
  ]);
10717
11203
  function registerAllModels(registry2) {
10718
11204
  register(registry2);
@@ -10753,6 +11239,12 @@ function registerAllModels(registry2) {
10753
11239
  register36(registry2);
10754
11240
  register37(registry2);
10755
11241
  register38(registry2);
11242
+ register39(registry2);
11243
+ register40(registry2);
11244
+ register41(registry2);
11245
+ register42(registry2);
11246
+ register43(registry2);
11247
+ register44(registry2);
10756
11248
  }
10757
11249
  var registry = new ModelRegistry();
10758
11250
  registerAllModels(registry);
@@ -10935,24 +11427,24 @@ var FootprintPlatedHole = ({
10935
11427
  };
10936
11428
 
10937
11429
  // lib/model-registry.ts
10938
- function defineModelRenderer(model76) {
10939
- return model76;
11430
+ function defineModelRenderer(model88) {
11431
+ return model88;
10940
11432
  }
10941
11433
  var ModelRendererRegistry = class {
10942
11434
  models = /* @__PURE__ */ new Map();
10943
- register(model76) {
10944
- if (typeof model76.name !== "string" || !/^[a-z]+$/.test(model76.name)) {
11435
+ register(model88) {
11436
+ if (typeof model88.name !== "string" || !/^[a-z]+$/.test(model88.name)) {
10945
11437
  throw new Error(
10946
11438
  "Model renderer names must contain only lowercase letters"
10947
11439
  );
10948
11440
  }
10949
- if (this.models.has(model76.name)) {
10950
- throw new Error(`Model renderer "${model76.name}" is already registered`);
11441
+ if (this.models.has(model88.name)) {
11442
+ throw new Error(`Model renderer "${model88.name}" is already registered`);
10951
11443
  }
10952
- if (model76.pads !== "none" && model76.pads !== "footprinter") {
11444
+ if (model88.pads !== "none" && model88.pads !== "footprinter") {
10953
11445
  throw new Error('Model renderer pads must be "none" or "footprinter"');
10954
11446
  }
10955
- const { name, schema, render: render2, pads } = model76;
11447
+ const { name, schema, render: render2, pads } = model88;
10956
11448
  this.models.set(name, {
10957
11449
  name,
10958
11450
  schema,
@@ -10978,8 +11470,118 @@ var ModelRendererRegistry = class {
10978
11470
  }
10979
11471
  };
10980
11472
 
10981
- // lib/mechanical/indexedMeshToGeom3.ts
11473
+ // lib/models/anglebar/geometry.ts
10982
11474
  import jscad from "@jscad/modeling";
11475
+ var { primitives, extrusions, geometries, modifiers, measurements } = jscad;
11476
+ var generalize = modifiers.generalize;
11477
+ var { rectangle, roundedRectangle, polygon } = primitives;
11478
+ var profile = (shape39, height10) => extrusions.extrudeLinear({ height: height10 }, shape39);
11479
+ function filletProfile(points, radii, width10, height10) {
11480
+ const outline = [];
11481
+ for (let i = 0; i < points.length; i++) {
11482
+ const a = points[(i + points.length - 1) % points.length];
11483
+ const b = points[i];
11484
+ const c = points[(i + 1) % points.length];
11485
+ const radius = radii[i];
11486
+ if (!radius) {
11487
+ outline.push([b[0] - width10 / 2, b[1] - height10 / 2]);
11488
+ continue;
11489
+ }
11490
+ const al = Math.hypot(a[0] - b[0], a[1] - b[1]);
11491
+ const cl = Math.hypot(c[0] - b[0], c[1] - b[1]);
11492
+ const u = [(a[0] - b[0]) / al, (a[1] - b[1]) / al];
11493
+ const v = [(c[0] - b[0]) / cl, (c[1] - b[1]) / cl];
11494
+ const center = [
11495
+ b[0] + radius * (u[0] + v[0]),
11496
+ b[1] + radius * (u[1] + v[1])
11497
+ ];
11498
+ const start = Math.atan2(
11499
+ b[1] + radius * u[1] - center[1],
11500
+ b[0] + radius * u[0] - center[0]
11501
+ );
11502
+ const turn = u[1] * v[0] - u[0] * v[1] > 0 ? 1 : -1;
11503
+ for (let j = 0; j <= 16; j++) {
11504
+ const angle = start + turn * j * Math.PI / 32;
11505
+ outline.push([
11506
+ center[0] + radius * Math.cos(angle) - width10 / 2,
11507
+ center[1] + radius * Math.sin(angle) - height10 / 2
11508
+ ]);
11509
+ }
11510
+ }
11511
+ return polygon({ points: outline });
11512
+ }
11513
+ function createAngleBarGeom(input) {
11514
+ const p = angleBarModelPropsSchema.parse(input);
11515
+ return profile(
11516
+ filletProfile(
11517
+ [
11518
+ [0, 0],
11519
+ [p.width, 0],
11520
+ [p.width, p.thickness],
11521
+ [p.thickness, p.thickness],
11522
+ [p.thickness, p.height],
11523
+ [0, p.height]
11524
+ ],
11525
+ [0, p.tipRadius, p.tipRadius, p.innerRadius, p.tipRadius, p.tipRadius],
11526
+ p.width,
11527
+ p.height
11528
+ ),
11529
+ p.length
11530
+ );
11531
+ }
11532
+ function createAngleBarMesh(input) {
11533
+ const geom = generalize(
11534
+ { snap: true, triangulate: true },
11535
+ createAngleBarGeom(input)
11536
+ );
11537
+ const epsilon = Math.max(...measurements.measureDimensions(geom)) * 1e-10;
11538
+ const positions = [];
11539
+ const indices = [];
11540
+ const lookup = /* @__PURE__ */ new Map();
11541
+ const vertex = (v) => {
11542
+ const key = v.map((x) => Math.round(x / epsilon)).join(",");
11543
+ let index = lookup.get(key);
11544
+ if (index === void 0) {
11545
+ index = positions.length / 3;
11546
+ positions.push(...v);
11547
+ lookup.set(key, index);
11548
+ }
11549
+ return index;
11550
+ };
11551
+ for (const poly of geometries.geom3.toPolygons(geom)) {
11552
+ for (let i = 1; i < poly.vertices.length - 1; i++) {
11553
+ const a = poly.vertices[0], b = poly.vertices[i], c = poly.vertices[i + 1];
11554
+ const u = b.map((x, j) => x - a[j]), v = c.map((x, j) => x - a[j]);
11555
+ const area = Math.hypot(
11556
+ u[1] * v[2] - u[2] * v[1],
11557
+ u[2] * v[0] - u[0] * v[2],
11558
+ u[0] * v[1] - u[1] * v[0]
11559
+ );
11560
+ if (area > epsilon * epsilon)
11561
+ indices.push(vertex(a), vertex(b), vertex(c));
11562
+ }
11563
+ }
11564
+ return { positions, indices };
11565
+ }
11566
+
11567
+ // lib/models/anglebar/AngleBar.tsx
11568
+ function AngleBar({ color = "#929da9", ...props }) {
11569
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createAngleBarGeom(props) }) });
11570
+ }
11571
+
11572
+ // lib/models/anglebar/register.tsx
11573
+ var model45 = defineModelRenderer({
11574
+ name: "anglebar",
11575
+ schema: angleBarModelDefinitionSchema,
11576
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(AngleBar, { ...props }),
11577
+ pads: "none"
11578
+ });
11579
+ function register45(registry2) {
11580
+ registry2.register(model45);
11581
+ }
11582
+
11583
+ // lib/mechanical/indexedMeshToGeom3.ts
11584
+ import jscad2 from "@jscad/modeling";
10983
11585
  function indexedMeshToGeom3(mesh) {
10984
11586
  const polygons = [];
10985
11587
  for (let i = 0; i < mesh.indices.length; i += 3)
@@ -10990,7 +11592,7 @@ function indexedMeshToGeom3(mesh) {
10990
11592
  mesh.positions[index * 3 + 2]
10991
11593
  ])
10992
11594
  );
10993
- return jscad.geometries.geom3.fromPoints(polygons);
11595
+ return jscad2.geometries.geom3.fromPoints(polygons);
10994
11596
  }
10995
11597
 
10996
11598
  // lib/models/ballbearing/mesh.ts
@@ -11106,7 +11708,7 @@ function createBallBearingMesh(input = {}, options = {}) {
11106
11708
  if (face2 === "open") continue;
11107
11709
  const t = d.closureThickness;
11108
11710
  const ri = d.innerRaceOuterRadius, ro = d.outerRaceInnerRadius;
11109
- const shape33 = face2 === "shielded" ? [
11711
+ const shape39 = face2 === "shielded" ? [
11110
11712
  [ro, 0],
11111
11713
  [ro, t * 0.45],
11112
11714
  [ri, t * 0.45],
@@ -11119,11 +11721,11 @@ function createBallBearingMesh(input = {}, options = {}) {
11119
11721
  [ri + 0.15 * (ro - ri), 0.5 * t],
11120
11722
  [ro - 0.15 * (ro - ri), 0.5 * t]
11121
11723
  ];
11122
- const profile = sign === -1 ? shape33 : shape33.map(([r, z]) => [r, d.width - z]).reverse();
11724
+ const profile6 = sign === -1 ? shape39 : shape39.map(([r, z]) => [r, d.width - z]).reverse();
11123
11725
  parts.push({
11124
11726
  name: `${face2} ${sign < 0 ? "lower" : "upper"}`,
11125
11727
  color: face2 === "sealed" ? "#252a30" : "#b5bbc3",
11126
- mesh: revolve(profile, segments)
11728
+ mesh: revolve(profile6, segments)
11127
11729
  });
11128
11730
  }
11129
11731
  return { ...combine(parts), parts };
@@ -11140,21 +11742,21 @@ function checkPrecision(lengths22) {
11140
11742
  "Bearing dimensions exceed the renderer's numerical resolution"
11141
11743
  );
11142
11744
  }
11143
- function revolve(profile, segments) {
11745
+ function revolve(profile6, segments) {
11144
11746
  const positions = [];
11145
11747
  const indices = [];
11146
- for (const [radius, z] of profile)
11748
+ for (const [radius, z] of profile6)
11147
11749
  for (let i = 0; i < segments; i++) {
11148
11750
  const angle = i * Math.PI * 2 / segments;
11149
11751
  const r = typeof radius === "number" ? radius : radius(angle);
11150
11752
  positions.push(r * Math.cos(angle), r * Math.sin(angle), z);
11151
11753
  }
11152
- for (let j = 0; j < profile.length; j++)
11754
+ for (let j = 0; j < profile6.length; j++)
11153
11755
  for (let i = 0; i < segments; i++) {
11154
11756
  const a = j * segments + i;
11155
11757
  const b = j * segments + (i + 1) % segments;
11156
- const c = (j + 1) % profile.length * segments + (i + 1) % segments;
11157
- const e = (j + 1) % profile.length * segments + i;
11758
+ const c = (j + 1) % profile6.length * segments + (i + 1) % segments;
11759
+ const e = (j + 1) % profile6.length * segments + i;
11158
11760
  indices.push(a, b, c, a, c, e);
11159
11761
  }
11160
11762
  return { positions, indices };
@@ -11165,7 +11767,7 @@ function annularSector(inner, outer, z0, z1, start, end, segments) {
11165
11767
  Math.ceil((end - start) / (2 * Math.PI) * segments)
11166
11768
  );
11167
11769
  const count = steps + 1;
11168
- const profile = [
11770
+ const profile6 = [
11169
11771
  [outer, z0],
11170
11772
  [outer, z1],
11171
11773
  [inner, z1],
@@ -11173,7 +11775,7 @@ function annularSector(inner, outer, z0, z1, start, end, segments) {
11173
11775
  ];
11174
11776
  const positions = [];
11175
11777
  const indices = [];
11176
- for (const [r, z] of profile)
11778
+ for (const [r, z] of profile6)
11177
11779
  for (let i = 0; i <= steps; i++) {
11178
11780
  const angle = start + (end - start) * i / steps;
11179
11781
  positions.push(r * Math.cos(angle), r * Math.sin(angle), z);
@@ -11243,14 +11845,14 @@ function BallBearing({ color, ...props }) {
11243
11845
  }
11244
11846
 
11245
11847
  // lib/models/ballbearing/register.tsx
11246
- var model39 = defineModelRenderer({
11848
+ var model46 = defineModelRenderer({
11247
11849
  name: "ballbearing",
11248
11850
  schema: ballBearingModelDefinitionSchema,
11249
11851
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(BallBearing, { ...props }),
11250
11852
  pads: "none"
11251
11853
  });
11252
- function register39(registry2) {
11253
- registry2.register(model39);
11854
+ function register46(registry2) {
11855
+ registry2.register(model46);
11254
11856
  }
11255
11857
 
11256
11858
  // lib/models/balltransferunit/mesh.ts
@@ -11364,7 +11966,7 @@ function createBallTransferUnitMesh(input = {}) {
11364
11966
  );
11365
11967
  const segments = 96;
11366
11968
  const latitude = 48;
11367
- const profile = [
11969
+ const profile6 = [
11368
11970
  [d.bodyRadius, 0],
11369
11971
  [d.bodyRadius, d.flangeBottomZ],
11370
11972
  [d.flangeRadius, d.flangeBottomZ],
@@ -11377,12 +11979,12 @@ function createBallTransferUnitMesh(input = {}) {
11377
11979
  for (let j = 1; j < latitude; j++) {
11378
11980
  const angle = j * Math.PI / latitude;
11379
11981
  if ((angle - openingAngle) * d.socketRadius > resolution7)
11380
- profile.push([
11982
+ profile6.push([
11381
11983
  d.socketRadius * Math.sin(angle),
11382
11984
  d.ballCenterZ + d.socketRadius * Math.cos(angle)
11383
11985
  ]);
11384
11986
  }
11385
- profile.push([0, d.socketBottomZ], [0, 0]);
11987
+ profile6.push([0, d.socketBottomZ], [0, 0]);
11386
11988
  const holes = d.mountingHoles.map(
11387
11989
  ({ x, y, diameter }) => circularProfile(x, y, diameter / 2, segments)
11388
11990
  );
@@ -11390,7 +11992,7 @@ function createBallTransferUnitMesh(input = {}) {
11390
11992
  const housing = joinProfileMeshes([
11391
11993
  // Cap faces are triangulated with all openings, rather than covered by
11392
11994
  // annular triangles and repaired afterward with Boolean subtraction.
11393
- revolve2(profile, segments, /* @__PURE__ */ new Set([1, 3])),
11995
+ revolve2(profile6, segments, /* @__PURE__ */ new Set([1, 3])),
11394
11996
  cap(
11395
11997
  flangeOutline,
11396
11998
  [circularProfile(0, 0, d.bodyRadius, segments), ...holes],
@@ -11427,10 +12029,10 @@ function createBallTransferUnitMesh(input = {}) {
11427
12029
  ];
11428
12030
  return { positions, indices, parts };
11429
12031
  }
11430
- function revolve2(profile, segments, omittedEdges = /* @__PURE__ */ new Set()) {
12032
+ function revolve2(profile6, segments, omittedEdges = /* @__PURE__ */ new Set()) {
11431
12033
  const positions = [];
11432
12034
  const indices = [];
11433
- const rings = profile.map(([radius, z]) => {
12035
+ const rings = profile6.map(([radius, z]) => {
11434
12036
  const start = positions.length / 3;
11435
12037
  const count = radius === 0 ? 1 : segments;
11436
12038
  for (let i = 0; i < count; i++) {
@@ -11499,14 +12101,14 @@ function BallTransferUnit({ color, ...props }) {
11499
12101
  }
11500
12102
 
11501
12103
  // lib/models/balltransferunit/register.tsx
11502
- var model40 = defineModelRenderer({
12104
+ var model47 = defineModelRenderer({
11503
12105
  name: "balltransferunit",
11504
12106
  schema: ballTransferUnitModelDefinitionSchema,
11505
12107
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(BallTransferUnit, { ...props }),
11506
12108
  pads: "none"
11507
12109
  });
11508
- function register40(registry2) {
11509
- registry2.register(model40);
12110
+ function register47(registry2) {
12111
+ registry2.register(model47);
11510
12112
  }
11511
12113
 
11512
12114
  // lib/models/buttonscrew/mesh.ts
@@ -11626,14 +12228,14 @@ function ButtonScrew({ color = "#737e8f", ...props }) {
11626
12228
  }
11627
12229
 
11628
12230
  // lib/models/buttonscrew/register.tsx
11629
- var model41 = defineModelRenderer({
12231
+ var model48 = defineModelRenderer({
11630
12232
  name: "buttonscrew",
11631
12233
  schema: buttonScrewModelDefinitionSchema,
11632
12234
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ButtonScrew, { ...props }),
11633
12235
  pads: "none"
11634
12236
  });
11635
- function register41(registry2) {
11636
- registry2.register(model41);
12237
+ function register48(registry2) {
12238
+ registry2.register(model48);
11637
12239
  }
11638
12240
 
11639
12241
  // lib/models/cablegrommet/mesh.ts
@@ -11701,21 +12303,142 @@ function CableGrommet({
11701
12303
  }
11702
12304
 
11703
12305
  // lib/models/cablegrommet/register.tsx
11704
- var model42 = defineModelRenderer({
12306
+ var model49 = defineModelRenderer({
11705
12307
  name: "cablegrommet",
11706
12308
  schema: cableGrommetModelDefinitionSchema,
11707
12309
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(CableGrommet, { ...props }),
11708
12310
  pads: "none"
11709
12311
  });
11710
- function register42(registry2) {
11711
- registry2.register(model42);
12312
+ function register49(registry2) {
12313
+ registry2.register(model49);
11712
12314
  }
11713
12315
 
11714
- // lib/models/clampingshaftcollar/mesh.ts
12316
+ // lib/models/channelbar/geometry.ts
11715
12317
  import jscad3 from "@jscad/modeling";
12318
+ var { primitives: primitives2, extrusions: extrusions2, geometries: geometries2, modifiers: modifiers2, measurements: measurements2 } = jscad3;
12319
+ var generalize2 = modifiers2.generalize;
12320
+ var { rectangle: rectangle2, roundedRectangle: roundedRectangle2, polygon: polygon2 } = primitives2;
12321
+ var profile2 = (shape39, height10) => extrusions2.extrudeLinear({ height: height10 }, shape39);
12322
+ function filletProfile2(points, radii, width10, height10) {
12323
+ const outline = [];
12324
+ for (let i = 0; i < points.length; i++) {
12325
+ const a = points[(i + points.length - 1) % points.length];
12326
+ const b = points[i];
12327
+ const c = points[(i + 1) % points.length];
12328
+ const radius = radii[i];
12329
+ if (!radius) {
12330
+ outline.push([b[0] - width10 / 2, b[1] - height10 / 2]);
12331
+ continue;
12332
+ }
12333
+ const al = Math.hypot(a[0] - b[0], a[1] - b[1]);
12334
+ const cl = Math.hypot(c[0] - b[0], c[1] - b[1]);
12335
+ const u = [(a[0] - b[0]) / al, (a[1] - b[1]) / al];
12336
+ const v = [(c[0] - b[0]) / cl, (c[1] - b[1]) / cl];
12337
+ const center = [
12338
+ b[0] + radius * (u[0] + v[0]),
12339
+ b[1] + radius * (u[1] + v[1])
12340
+ ];
12341
+ const start = Math.atan2(
12342
+ b[1] + radius * u[1] - center[1],
12343
+ b[0] + radius * u[0] - center[0]
12344
+ );
12345
+ const turn = u[1] * v[0] - u[0] * v[1] > 0 ? 1 : -1;
12346
+ for (let j = 0; j <= 16; j++) {
12347
+ const angle = start + turn * j * Math.PI / 32;
12348
+ outline.push([
12349
+ center[0] + radius * Math.cos(angle) - width10 / 2,
12350
+ center[1] + radius * Math.sin(angle) - height10 / 2
12351
+ ]);
12352
+ }
12353
+ }
12354
+ return polygon2({ points: outline });
12355
+ }
12356
+ function createChannelBarGeom(input) {
12357
+ const p = channelBarModelPropsSchema.parse(input);
12358
+ return profile2(
12359
+ filletProfile2(
12360
+ [
12361
+ [0, 0],
12362
+ [p.width, 0],
12363
+ [p.width, p.height],
12364
+ [p.width - p.flangeThickness, p.height],
12365
+ [p.width - p.flangeThickness, p.webThickness],
12366
+ [p.flangeThickness, p.webThickness],
12367
+ [p.flangeThickness, p.height],
12368
+ [0, p.height]
12369
+ ],
12370
+ [
12371
+ 0,
12372
+ 0,
12373
+ p.tipRadius,
12374
+ p.tipRadius,
12375
+ p.innerRadius,
12376
+ p.innerRadius,
12377
+ p.tipRadius,
12378
+ p.tipRadius
12379
+ ],
12380
+ p.width,
12381
+ p.height
12382
+ ),
12383
+ p.length
12384
+ );
12385
+ }
12386
+ function createChannelBarMesh(input) {
12387
+ const geom = generalize2(
12388
+ { snap: true, triangulate: true },
12389
+ createChannelBarGeom(input)
12390
+ );
12391
+ const epsilon = Math.max(...measurements2.measureDimensions(geom)) * 1e-10;
12392
+ const positions = [];
12393
+ const indices = [];
12394
+ const lookup = /* @__PURE__ */ new Map();
12395
+ const vertex = (v) => {
12396
+ const key = v.map((x) => Math.round(x / epsilon)).join(",");
12397
+ let index = lookup.get(key);
12398
+ if (index === void 0) {
12399
+ index = positions.length / 3;
12400
+ positions.push(...v);
12401
+ lookup.set(key, index);
12402
+ }
12403
+ return index;
12404
+ };
12405
+ for (const poly of geometries2.geom3.toPolygons(geom)) {
12406
+ for (let i = 1; i < poly.vertices.length - 1; i++) {
12407
+ const a = poly.vertices[0], b = poly.vertices[i], c = poly.vertices[i + 1];
12408
+ const u = b.map((x, j) => x - a[j]), v = c.map((x, j) => x - a[j]);
12409
+ const area = Math.hypot(
12410
+ u[1] * v[2] - u[2] * v[1],
12411
+ u[2] * v[0] - u[0] * v[2],
12412
+ u[0] * v[1] - u[1] * v[0]
12413
+ );
12414
+ if (area > epsilon * epsilon)
12415
+ indices.push(vertex(a), vertex(b), vertex(c));
12416
+ }
12417
+ }
12418
+ return { positions, indices };
12419
+ }
12420
+
12421
+ // lib/models/channelbar/ChannelBar.tsx
12422
+ function ChannelBar({ color = "#929da9", ...props }) {
12423
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createChannelBarGeom(props) }) });
12424
+ }
12425
+
12426
+ // lib/models/channelbar/register.tsx
12427
+ var model50 = defineModelRenderer({
12428
+ name: "channelbar",
12429
+ schema: channelBarModelDefinitionSchema,
12430
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ChannelBar, { ...props }),
12431
+ pads: "none"
12432
+ });
12433
+ function register50(registry2) {
12434
+ registry2.register(model50);
12435
+ }
12436
+
12437
+ // lib/models/clampingshaftcollar/mesh.ts
12438
+ import jscad5 from "@jscad/modeling";
11716
12439
 
11717
12440
  // lib/mechanical/shaft-mount-geometry.ts
11718
- import jscad2 from "@jscad/modeling";
12441
+ import jscad4 from "@jscad/modeling";
11719
12442
  var bodySegments = 64;
11720
12443
  var threadSegments = 24;
11721
12444
  var samplesPerTurn = 12;
@@ -11736,9 +12459,9 @@ function createAnnularSleeve({
11736
12459
  outerRadius,
11737
12460
  boreARadius,
11738
12461
  boreBRadius = boreARadius,
11739
- length: length20,
12462
+ length: length26,
11740
12463
  chamfer,
11741
- stepZ = length20 / 2
12464
+ stepZ = length26 / 2
11742
12465
  }) {
11743
12466
  const halfAngle = Math.PI / bodySegments;
11744
12467
  const cosine = Math.cos(halfAngle);
@@ -11749,31 +12472,31 @@ function createAnnularSleeve({
11749
12472
  const raw = [
11750
12473
  [0, outerRadius - chamfer, false],
11751
12474
  [chamfer, outerRadius, false],
11752
- [length20 - chamfer, outerRadius, false],
11753
- [length20, outerRadius - chamfer, false],
11754
- [length20, boreBRadius + chamfer, true],
11755
- [length20 - chamfer, boreBRadius, true],
12475
+ [length26 - chamfer, outerRadius, false],
12476
+ [length26, outerRadius - chamfer, false],
12477
+ [length26, boreBRadius + chamfer, true],
12478
+ [length26 - chamfer, boreBRadius, true],
11756
12479
  [stepZ, boreBRadius, true],
11757
12480
  [stepZ, boreARadius, true],
11758
12481
  [chamfer, boreARadius, true],
11759
12482
  [0, boreARadius + chamfer, true]
11760
12483
  ];
11761
- const profile = raw.filter(
12484
+ const profile6 = raw.filter(
11762
12485
  ([z, r], i) => i === 0 || z !== raw[i - 1][0] || r !== raw[i - 1][1]
11763
12486
  );
11764
12487
  const positions = [];
11765
12488
  const indices = [];
11766
- for (const [z, r, isBore] of profile)
12489
+ for (const [z, r, isBore] of profile6)
11767
12490
  for (let i = 0; i < bodySegments; i++) {
11768
12491
  const angle = (i + (isBore ? 0.5 : 0)) * Math.PI * 2 / bodySegments;
11769
12492
  const radius = isBore ? r / cosine : r;
11770
12493
  positions.push(radius * Math.cos(angle), radius * Math.sin(angle), z);
11771
12494
  }
11772
- for (let row = 0; row < profile.length; row++)
12495
+ for (let row = 0; row < profile6.length; row++)
11773
12496
  for (let i = 0; i < bodySegments; i++) {
11774
12497
  const next = (i + 1) % bodySegments;
11775
12498
  const a = row * bodySegments + i, b = row * bodySegments + next;
11776
- const c = (row + 1) % profile.length * bodySegments + next, d = (row + 1) % profile.length * bodySegments + i;
12499
+ const c = (row + 1) % profile6.length * bodySegments + next, d = (row + 1) % profile6.length * bodySegments + i;
11777
12500
  indices.push(a, b, c, a, c, d);
11778
12501
  }
11779
12502
  return indexedMeshToGeom3({ positions, indices });
@@ -11831,10 +12554,10 @@ function createMountingHoleCutter(hole) {
11831
12554
  function subtractShaftMountParts(body, ...cutters) {
11832
12555
  const factor = 100;
11833
12556
  const scaled = [body, ...cutters].map(
11834
- (geometry) => jscad2.transforms.scale([factor, factor, factor], geometry)
12557
+ (geometry) => jscad4.transforms.scale([factor, factor, factor], geometry)
11835
12558
  );
11836
- const result = jscad2.booleans.subtract(scaled[0], ...scaled.slice(1));
11837
- return jscad2.transforms.scale([1 / factor, 1 / factor, 1 / factor], result);
12559
+ const result = jscad4.booleans.subtract(scaled[0], ...scaled.slice(1));
12560
+ return jscad4.transforms.scale([1 / factor, 1 / factor, 1 / factor], result);
11838
12561
  }
11839
12562
  function finishShaftMountMesh(geometry) {
11840
12563
  const positions = [];
@@ -11860,8 +12583,8 @@ function finishShaftMountMesh(geometry) {
11860
12583
  vertices.set(key, [...vertices.get(key) ?? [], index]);
11861
12584
  return index;
11862
12585
  };
11863
- const polygons = jscad2.geometries.geom3.toPolygons(geometry).map(
11864
- (polygon) => polygon.vertices.map(weld).filter((id, i, ids) => id !== ids[(i + ids.length - 1) % ids.length])
12586
+ const polygons = jscad4.geometries.geom3.toPolygons(geometry).map(
12587
+ (polygon4) => polygon4.vertices.map(weld).filter((id, i, ids) => id !== ids[(i + ids.length - 1) % ids.length])
11865
12588
  ).map((ids) => [...new Set(ids)]).filter((ids) => ids.length >= 3).filter((ids) => {
11866
12589
  let longest = 0;
11867
12590
  let origin = [];
@@ -11885,9 +12608,9 @@ function finishShaftMountMesh(geometry) {
11885
12608
  });
11886
12609
  const edgeKey = (a, b) => `${Math.min(a, b)},${Math.max(a, b)}`;
11887
12610
  const edges = /* @__PURE__ */ new Map();
11888
- for (const polygon of polygons)
11889
- for (let i = 0; i < polygon.length; i++) {
11890
- const a = polygon[i], b = polygon[(i + 1) % polygon.length], key = edgeKey(a, b);
12611
+ for (const polygon4 of polygons)
12612
+ for (let i = 0; i < polygon4.length; i++) {
12613
+ const a = polygon4[i], b = polygon4[(i + 1) % polygon4.length], key = edgeKey(a, b);
11891
12614
  const edge = edges.get(key) ?? { a, b, count: 0 };
11892
12615
  edge.count++;
11893
12616
  edges.set(key, edge);
@@ -11918,10 +12641,10 @@ function finishShaftMountMesh(geometry) {
11918
12641
  splits.set(`${b},${a}`, points.map((p) => p.id).reverse());
11919
12642
  }
11920
12643
  const indices = [];
11921
- for (const polygon of polygons) {
11922
- const perimeter = polygon.flatMap((a, i) => [
12644
+ for (const polygon4 of polygons) {
12645
+ const perimeter = polygon4.flatMap((a, i) => [
11923
12646
  a,
11924
- ...(splits.get(`${a},${polygon[(i + 1) % polygon.length]}`) ?? []).filter((id) => !polygon.includes(id))
12647
+ ...(splits.get(`${a},${polygon4[(i + 1) % polygon4.length]}`) ?? []).filter((id) => !polygon4.includes(id))
11925
12648
  ]);
11926
12649
  const unique = perimeter.filter(
11927
12650
  (id, i) => id !== perimeter[(i + perimeter.length - 1) % perimeter.length]
@@ -11968,7 +12691,7 @@ function createClampingShaftCollarMesh(input) {
11968
12691
  });
11969
12692
  const s = dimensions5.split;
11970
12693
  const epsilon = 1e-4;
11971
- const slit = jscad3.primitives.cuboid({
12694
+ const slit = jscad5.primitives.cuboid({
11972
12695
  size: [
11973
12696
  s.xMax - s.xMin + epsilon,
11974
12697
  s.yMax - s.yMin,
@@ -12002,14 +12725,14 @@ function ClampingShaftCollar({
12002
12725
  }
12003
12726
 
12004
12727
  // lib/models/clampingshaftcollar/register.tsx
12005
- var model43 = defineModelRenderer({
12728
+ var model51 = defineModelRenderer({
12006
12729
  name: "clampingshaftcollar",
12007
12730
  schema: clampingShaftCollarModelDefinitionSchema,
12008
12731
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ClampingShaftCollar, { ...props }),
12009
12732
  pads: "none"
12010
12733
  });
12011
- function register43(registry2) {
12012
- registry2.register(model43);
12734
+ function register51(registry2) {
12735
+ registry2.register(model51);
12013
12736
  }
12014
12737
 
12015
12738
  // lib/mechanical/clip-mesh-to-z-range.ts
@@ -12047,12 +12770,12 @@ function clipMeshToZRange(mesh, lower, upper) {
12047
12770
  }
12048
12771
  return point;
12049
12772
  };
12050
- const clip = (polygon, plane, keepAbove) => {
12773
+ const clip = (polygon4, plane, keepAbove) => {
12051
12774
  const result = [];
12052
12775
  const inside = (point) => keepAbove ? point.coordinates[2] >= plane : point.coordinates[2] <= plane;
12053
- for (let index = 0; index < polygon.length; index++) {
12054
- const a = polygon[index];
12055
- const b = polygon[(index + 1) % polygon.length];
12776
+ for (let index = 0; index < polygon4.length; index++) {
12777
+ const a = polygon4[index];
12778
+ const b = polygon4[(index + 1) % polygon4.length];
12056
12779
  if (inside(a)) result.push(a);
12057
12780
  if (inside(a) !== inside(b)) result.push(crossing(a, b, plane));
12058
12781
  }
@@ -12074,9 +12797,9 @@ function clipMeshToZRange(mesh, lower, upper) {
12074
12797
  };
12075
12798
  for (let index = 0; index < mesh.indices.length; index += 3) {
12076
12799
  const triangle = mesh.indices.slice(index, index + 3).map((i) => originals[i]);
12077
- const polygon = clip(clip(triangle, lower, true), upper, false);
12078
- for (let corner = 1; corner + 1 < polygon.length; corner++) {
12079
- const points = [polygon[0], polygon[corner], polygon[corner + 1]];
12800
+ const polygon4 = clip(clip(triangle, lower, true), upper, false);
12801
+ for (let corner = 1; corner + 1 < polygon4.length; corner++) {
12802
+ const points = [polygon4[0], polygon4[corner], polygon4[corner + 1]];
12080
12803
  if (new Set(points.map((point) => point.key)).size === 3)
12081
12804
  indices.push(...points.map(vertex));
12082
12805
  }
@@ -12205,14 +12928,14 @@ function CompressionSpring({
12205
12928
  }
12206
12929
 
12207
12930
  // lib/models/compressionspring/register.tsx
12208
- var model44 = defineModelRenderer({
12931
+ var model52 = defineModelRenderer({
12209
12932
  name: "compressionspring",
12210
12933
  schema: compressionSpringModelDefinitionSchema,
12211
12934
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(CompressionSpring, { ...props }),
12212
12935
  pads: "none"
12213
12936
  });
12214
- function register44(registry2) {
12215
- registry2.register(model44);
12937
+ function register52(registry2) {
12938
+ registry2.register(model52);
12216
12939
  }
12217
12940
 
12218
12941
  // lib/models/dowelpin/mesh.ts
@@ -12263,14 +12986,14 @@ function DowelPin({ color = "#929da9", ...props }) {
12263
12986
  }
12264
12987
 
12265
12988
  // lib/models/dowelpin/register.tsx
12266
- var model45 = defineModelRenderer({
12989
+ var model53 = defineModelRenderer({
12267
12990
  name: "dowelpin",
12268
12991
  schema: dowelPinModelDefinitionSchema,
12269
12992
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(DowelPin, { ...props }),
12270
12993
  pads: "none"
12271
12994
  });
12272
- function register45(registry2) {
12273
- registry2.register(model45);
12995
+ function register53(registry2) {
12996
+ registry2.register(model53);
12274
12997
  }
12275
12998
 
12276
12999
  // lib/models/femalestandoff/mesh.ts
@@ -12372,14 +13095,14 @@ function FemaleStandoff({
12372
13095
  }
12373
13096
 
12374
13097
  // lib/models/femalestandoff/register.tsx
12375
- var model46 = defineModelRenderer({
13098
+ var model54 = defineModelRenderer({
12376
13099
  name: "femalestandoff",
12377
13100
  schema: femaleStandoffModelDefinitionSchema,
12378
13101
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FemaleStandoff, { ...props }),
12379
13102
  pads: "none"
12380
13103
  });
12381
- function register46(registry2) {
12382
- registry2.register(model46);
13104
+ function register54(registry2) {
13105
+ registry2.register(model54);
12383
13106
  }
12384
13107
 
12385
13108
  // lib/models/flangebolt/mesh.ts
@@ -12526,14 +13249,14 @@ function FlangeBolt({ color = "#737e8f", ...props }) {
12526
13249
  }
12527
13250
 
12528
13251
  // lib/models/flangebolt/register.tsx
12529
- var model47 = defineModelRenderer({
13252
+ var model55 = defineModelRenderer({
12530
13253
  name: "flangebolt",
12531
13254
  schema: flangeboltModelDefinitionSchema,
12532
13255
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlangeBolt, { ...props }),
12533
13256
  pads: "none"
12534
- });
12535
- function register47(registry2) {
12536
- registry2.register(model47);
13257
+ });
13258
+ function register55(registry2) {
13259
+ registry2.register(model55);
12537
13260
  }
12538
13261
 
12539
13262
  // lib/models/flangedbushing/mesh.ts
@@ -12543,7 +13266,7 @@ function createFlangedBushingMesh(input) {
12543
13266
  const ri = d.innerDiameter / 2;
12544
13267
  const ro = d.outerDiameter / 2;
12545
13268
  const rf = d.flangeDiameter / 2;
12546
- const profile = [
13269
+ const profile6 = [
12547
13270
  [rf, 0],
12548
13271
  [rf, d.shoulderZ],
12549
13272
  [ro, d.shoulderZ],
@@ -12554,14 +13277,14 @@ function createFlangedBushingMesh(input) {
12554
13277
  const segments = 96;
12555
13278
  const positions = [];
12556
13279
  const indices = [];
12557
- for (const [radius, z] of profile)
13280
+ for (const [radius, z] of profile6)
12558
13281
  for (let i = 0; i < segments; i++) {
12559
13282
  const angle = i * Math.PI * 2 / segments;
12560
13283
  positions.push(radius * Math.cos(angle), radius * Math.sin(angle), z);
12561
13284
  }
12562
- for (let ring = 0; ring < profile.length; ring++) {
13285
+ for (let ring = 0; ring < profile6.length; ring++) {
12563
13286
  const a = ring * segments;
12564
- const b = (ring + 1) % profile.length * segments;
13287
+ const b = (ring + 1) % profile6.length * segments;
12565
13288
  for (let i = 0; i < segments; i++) {
12566
13289
  const next = (i + 1) % segments;
12567
13290
  indices.push(a + i, a + next, b + next, a + i, b + next, b + i);
@@ -12582,14 +13305,14 @@ function FlangedBushing({
12582
13305
  }
12583
13306
 
12584
13307
  // lib/models/flangedbushing/register.tsx
12585
- var model48 = defineModelRenderer({
13308
+ var model56 = defineModelRenderer({
12586
13309
  name: "flangedbushing",
12587
13310
  schema: flangedBushingModelDefinitionSchema,
12588
13311
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlangedBushing, { ...props }),
12589
13312
  pads: "none"
12590
13313
  });
12591
- function register48(registry2) {
12592
- registry2.register(model48);
13314
+ function register56(registry2) {
13315
+ registry2.register(model56);
12593
13316
  }
12594
13317
 
12595
13318
  // lib/models/flangenut/mesh.ts
@@ -12695,14 +13418,14 @@ function FlangeNut({ color = "#737e8f", ...props }) {
12695
13418
  }
12696
13419
 
12697
13420
  // lib/models/flangenut/register.tsx
12698
- var model49 = defineModelRenderer({
13421
+ var model57 = defineModelRenderer({
12699
13422
  name: "flangenut",
12700
13423
  schema: flangeNutModelDefinitionSchema,
12701
13424
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlangeNut, { ...props }),
12702
13425
  pads: "none"
12703
13426
  });
12704
- function register49(registry2) {
12705
- registry2.register(model49);
13427
+ function register57(registry2) {
13428
+ registry2.register(model57);
12706
13429
  }
12707
13430
 
12708
13431
  // lib/models/flatheadscrew/mesh.ts
@@ -12829,14 +13552,14 @@ function FlatHeadScrew({
12829
13552
  }
12830
13553
 
12831
13554
  // lib/models/flatheadscrew/register.tsx
12832
- var model50 = defineModelRenderer({
13555
+ var model58 = defineModelRenderer({
12833
13556
  name: "flatheadscrew",
12834
13557
  schema: flatHeadScrewModelDefinitionSchema,
12835
13558
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlatHeadScrew, { ...props }),
12836
13559
  pads: "none"
12837
13560
  });
12838
- function register50(registry2) {
12839
- registry2.register(model50);
13561
+ function register58(registry2) {
13562
+ registry2.register(model58);
12840
13563
  }
12841
13564
 
12842
13565
  // lib/Screen.tsx
@@ -13511,14 +14234,14 @@ var FlexScreen = (props) => {
13511
14234
  };
13512
14235
 
13513
14236
  // lib/models/flexscreen/register.tsx
13514
- var model51 = defineModelRenderer({
14237
+ var model59 = defineModelRenderer({
13515
14238
  name: "flexscreen",
13516
14239
  schema: flexScreenModelDefinitionSchema,
13517
14240
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlexScreen, { ...props }),
13518
14241
  pads: "footprinter"
13519
14242
  });
13520
- function register51(registry2) {
13521
- registry2.register(model51);
14243
+ function register59(registry2) {
14244
+ registry2.register(model59);
13522
14245
  }
13523
14246
 
13524
14247
  // lib/models/heatsetinsert/mesh.ts
@@ -13603,14 +14326,14 @@ function HeatSetInsert({
13603
14326
  }
13604
14327
 
13605
14328
  // lib/models/heatsetinsert/register.tsx
13606
- var model52 = defineModelRenderer({
14329
+ var model60 = defineModelRenderer({
13607
14330
  name: "heatsetinsert",
13608
14331
  schema: heatSetInsertModelDefinitionSchema,
13609
14332
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HeatSetInsert, { ...props }),
13610
14333
  pads: "none"
13611
14334
  });
13612
- function register52(registry2) {
13613
- registry2.register(model52);
14335
+ function register60(registry2) {
14336
+ registry2.register(model60);
13614
14337
  }
13615
14338
 
13616
14339
  // lib/mechanical/spur-gear-mesh.ts
@@ -13691,7 +14414,7 @@ function createTwistedSpurGearMesh(input, twist = 0, segmentsPerTurn = 32) {
13691
14414
  return start;
13692
14415
  };
13693
14416
  const circleSegments = Math.max(48, Math.min(256, props.toothCount * 4));
13694
- const circle2 = (radius) => Array.from({ length: circleSegments }, (_, segment) => {
14417
+ const circle3 = (radius) => Array.from({ length: circleSegments }, (_, segment) => {
13695
14418
  const angle = phase + segment * Math.PI * 2 / circleSegments;
13696
14419
  return [radius * Math.cos(angle), radius * Math.sin(angle)];
13697
14420
  });
@@ -13754,7 +14477,7 @@ function createTwistedSpurGearMesh(input, twist = 0, segmentsPerTurn = 32) {
13754
14477
  }
13755
14478
  const hasHub = props.hubDiameter > 0 && props.hubLength > 0;
13756
14479
  const height10 = props.faceWidth + (hasHub ? props.hubLength : 0);
13757
- const bore = props.boreDiameter > 0 ? circle2(props.boreDiameter / 2) : void 0;
14480
+ const bore = props.boreDiameter > 0 ? circle3(props.boreDiameter / 2) : void 0;
13758
14481
  const boreBottom = bore ? ring(bore, 0) : void 0;
13759
14482
  const boreTop = bore ? ring(bore, height10) : void 0;
13760
14483
  if (bore) connect(boreBottom, boreTop, bore.length, true);
@@ -13765,7 +14488,7 @@ function createTwistedSpurGearMesh(input, twist = 0, segmentsPerTurn = 32) {
13765
14488
  bore ? { points: bore, start: boreBottom } : void 0
13766
14489
  );
13767
14490
  if (hasHub) {
13768
- const hub = circle2(props.hubDiameter / 2);
14491
+ const hub = circle3(props.hubDiameter / 2);
13769
14492
  const hubBottom = ring(hub, props.faceWidth);
13770
14493
  const hubTop = ring(hub, height10);
13771
14494
  cap2(topOutline, top, true, { points: hub, start: hubBottom });
@@ -13803,14 +14526,14 @@ function HelicalGear({ color = "#737e8f", ...props }) {
13803
14526
  }
13804
14527
 
13805
14528
  // lib/models/helicalgear/register.tsx
13806
- var model53 = defineModelRenderer({
14529
+ var model61 = defineModelRenderer({
13807
14530
  name: "helicalgear",
13808
14531
  schema: helicalGearModelDefinitionSchema,
13809
14532
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HelicalGear, { ...props }),
13810
14533
  pads: "none"
13811
14534
  });
13812
- function register53(registry2) {
13813
- registry2.register(model53);
14535
+ function register61(registry2) {
14536
+ registry2.register(model61);
13814
14537
  }
13815
14538
 
13816
14539
  // lib/models/hexbolt/mesh.ts
@@ -13945,14 +14668,14 @@ function HexBolt({ color = "#737e8f", ...props }) {
13945
14668
  }
13946
14669
 
13947
14670
  // lib/models/hexbolt/register.tsx
13948
- var model54 = defineModelRenderer({
14671
+ var model62 = defineModelRenderer({
13949
14672
  name: "hexbolt",
13950
14673
  schema: hexBoltModelDefinitionSchema,
13951
14674
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexBolt, { ...props }),
13952
14675
  pads: "none"
13953
14676
  });
13954
- function register54(registry2) {
13955
- registry2.register(model54);
14677
+ function register62(registry2) {
14678
+ registry2.register(model62);
13956
14679
  }
13957
14680
 
13958
14681
  // lib/models/hexnut/mesh.ts
@@ -14071,14 +14794,14 @@ function HexNut({ color = "#737e8f", ...props }) {
14071
14794
  }
14072
14795
 
14073
14796
  // lib/models/hexnut/register.tsx
14074
- var model55 = defineModelRenderer({
14797
+ var model63 = defineModelRenderer({
14075
14798
  name: "hexnut",
14076
14799
  schema: hexNutModelDefinitionSchema,
14077
14800
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexNut, { ...props }),
14078
14801
  pads: "none"
14079
14802
  });
14080
- function register55(registry2) {
14081
- registry2.register(model55);
14803
+ function register63(registry2) {
14804
+ registry2.register(model63);
14082
14805
  }
14083
14806
 
14084
14807
  // lib/mechanical/hex-socket-bolt-mesh.ts
@@ -14092,9 +14815,9 @@ var createHexSocketBoltMesh = (input) => {
14092
14815
  socketWidth,
14093
14816
  socketDepth
14094
14817
  } = hexSocketBoltDimensions[props.metricSize];
14095
- const { length: length20, showThreads } = props;
14818
+ const { length: length26, showThreads } = props;
14096
14819
  const segments = 96;
14097
- const steps = showThreads ? Math.max(2, Math.ceil(length20 / pitch * 24)) : 2;
14820
+ const steps = showThreads ? Math.max(2, Math.ceil(length26 / pitch * 24)) : 2;
14098
14821
  if (steps > 24e3)
14099
14822
  throw new Error(
14100
14823
  "Bolt length exceeds mesh resolution limit (1000 thread turns)"
@@ -14104,7 +14827,7 @@ var createHexSocketBoltMesh = (input) => {
14104
14827
  const radius = diameter / 2;
14105
14828
  const depth = pitch * 0.61343;
14106
14829
  const bevel = Math.min(0.2, headHeight * 0.08);
14107
- const tipBevel = Math.min(pitch * 0.6, length20 / 3);
14830
+ const tipBevel = Math.min(pitch * 0.6, length26 / 3);
14108
14831
  const ring = (z, radiusAt) => {
14109
14832
  const start = positions.length / 3;
14110
14833
  for (let i = 0; i < segments; i++) {
@@ -14132,8 +14855,8 @@ var createHexSocketBoltMesh = (input) => {
14132
14855
  let previous = -1;
14133
14856
  const shaftLevels = showThreads ? Array.from(
14134
14857
  { length: steps + 1 },
14135
- (_, step) => -length20 + length20 * step / steps
14136
- ) : [-length20, -length20 + tipBevel, 0];
14858
+ (_, step) => -length26 + length26 * step / steps
14859
+ ) : [-length26, -length26 + tipBevel, 0];
14137
14860
  for (const z of shaftLevels) {
14138
14861
  const current = ring(z, (angle) => {
14139
14862
  const phase = ((z / pitch - angle / (2 * Math.PI)) % 1 + 1) % 1;
@@ -14144,10 +14867,10 @@ var createHexSocketBoltMesh = (input) => {
14144
14867
  );
14145
14868
  const endRamp = Math.min(
14146
14869
  1,
14147
- (z + length20) / tipBevel,
14148
- -z / Math.min(pitch / 2, length20 / 3)
14870
+ (z + length26) / tipBevel,
14871
+ -z / Math.min(pitch / 2, length26 / 3)
14149
14872
  );
14150
- const tipCut = tipBevel * Math.max(0, 1 - (z + length20) / tipBevel);
14873
+ const tipCut = tipBevel * Math.max(0, 1 - (z + length26) / tipBevel);
14151
14874
  return radius - (showThreads ? groove * endRamp : 0) - tipCut;
14152
14875
  });
14153
14876
  if (previous < 0) cap2(current, z, false);
@@ -14183,14 +14906,14 @@ function HexSocketBolt({
14183
14906
  }
14184
14907
 
14185
14908
  // lib/models/hexsocketbolt/register.tsx
14186
- var model56 = defineModelRenderer({
14909
+ var model64 = defineModelRenderer({
14187
14910
  name: "hexsocketbolt",
14188
14911
  schema: hexSocketBoltModelDefinitionSchema,
14189
14912
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexSocketBolt, { ...props }),
14190
14913
  pads: "none"
14191
14914
  });
14192
- function register56(registry2) {
14193
- registry2.register(model56);
14915
+ function register64(registry2) {
14916
+ registry2.register(model64);
14194
14917
  }
14195
14918
 
14196
14919
  // lib/models/hollowpositioningarmtube/mesh.ts
@@ -14303,14 +15026,14 @@ function HollowPositioningArmTube({
14303
15026
  }
14304
15027
 
14305
15028
  // lib/models/hollowpositioningarmtube/register.tsx
14306
- var model57 = defineModelRenderer({
15029
+ var model65 = defineModelRenderer({
14307
15030
  name: "hollowpositioningarmtube",
14308
15031
  schema: hollowPositioningArmTubeModelDefinitionSchema,
14309
15032
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HollowPositioningArmTube, { ...props }),
14310
15033
  pads: "none"
14311
15034
  });
14312
- function register57(registry2) {
14313
- registry2.register(model57);
15035
+ function register65(registry2) {
15036
+ registry2.register(model65);
14314
15037
  }
14315
15038
 
14316
15039
  // lib/models/malefemalestandoff/mesh.ts
@@ -14442,21 +15165,21 @@ function MaleFemaleStandoff({
14442
15165
  }
14443
15166
 
14444
15167
  // lib/models/malefemalestandoff/register.tsx
14445
- var model58 = defineModelRenderer({
15168
+ var model66 = defineModelRenderer({
14446
15169
  name: "malefemalestandoff",
14447
15170
  schema: maleFemaleStandoffModelDefinitionSchema,
14448
15171
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(MaleFemaleStandoff, { ...props }),
14449
15172
  pads: "none"
14450
15173
  });
14451
- function register58(registry2) {
14452
- registry2.register(model58);
15174
+ function register66(registry2) {
15175
+ registry2.register(model66);
14453
15176
  }
14454
15177
 
14455
15178
  // lib/NemaMotor.tsx
14456
- import jscad5 from "@jscad/modeling";
15179
+ import jscad7 from "@jscad/modeling";
14457
15180
 
14458
15181
  // lib/utils/nemaMotorWireGeometry.ts
14459
- import jscad4 from "@jscad/modeling";
15182
+ import jscad6 from "@jscad/modeling";
14460
15183
 
14461
15184
  // lib/utils/nemaMotorParameters.ts
14462
15185
  var resolveNemaMotorProps = nemaMotorModelPropsSchema.parse.bind(nemaMotorModelPropsSchema);
@@ -14467,9 +15190,9 @@ function createNemaMotorWireGeometry(input) {
14467
15190
  if (p.wireConnection === "none") return [];
14468
15191
  const { position } = getNemaMotorReferencePoints(p).wireside;
14469
15192
  const angle = p.wireSideAngle * Math.PI / 180;
14470
- const place = (geometry) => jscad4.transforms.translate(
15193
+ const place = (geometry) => jscad6.transforms.translate(
14471
15194
  [position.x, position.y, position.z],
14472
- jscad4.transforms.rotateZ(angle, geometry)
15195
+ jscad6.transforms.rotateZ(angle, geometry)
14473
15196
  );
14474
15197
  if (p.wireConnection === "stubs") {
14475
15198
  const colors = [
@@ -14485,15 +15208,15 @@ function createNemaMotorWireGeometry(input) {
14485
15208
  return Array.from({ length: p.wireCount }, (_, i) => ({
14486
15209
  color: colors[i],
14487
15210
  geometry: place(
14488
- jscad4.transforms.translate(
15211
+ jscad6.transforms.translate(
14489
15212
  [
14490
15213
  (p.wireLength - 0.15) / 2,
14491
15214
  (i - (p.wireCount - 1) / 2) * p.wireDiameter * 1.5,
14492
15215
  0
14493
15216
  ],
14494
- jscad4.transforms.rotateY(
15217
+ jscad6.transforms.rotateY(
14495
15218
  Math.PI / 2,
14496
- jscad4.primitives.cylinder({
15219
+ jscad6.primitives.cylinder({
14497
15220
  height: p.wireLength + 0.15,
14498
15221
  radius: p.wireDiameter / 2,
14499
15222
  segments: 24
@@ -14508,12 +15231,12 @@ function createNemaMotorWireGeometry(input) {
14508
15231
  const wall = pitch === 2 ? 0.6 : 0.3;
14509
15232
  const contactLength = pitch === 2 ? 3.4 : 2.4;
14510
15233
  const contactSize = pitch === 2 ? 0.5 : 0.3;
14511
- const shell = jscad4.booleans.subtract(
14512
- jscad4.primitives.cuboid({
15234
+ const shell = jscad6.booleans.subtract(
15235
+ jscad6.primitives.cuboid({
14513
15236
  size: [matingDepth + 0.1, bodyWidth, bodyHeight],
14514
15237
  center: [(matingDepth - 0.1) / 2, 0, 0]
14515
15238
  }),
14516
- jscad4.primitives.cuboid({
15239
+ jscad6.primitives.cuboid({
14517
15240
  size: [matingDepth - 0.5, bodyWidth - 2 * wall, bodyHeight - 2 * wall],
14518
15241
  center: [matingDepth / 2 + 0.55, 0, 0]
14519
15242
  })
@@ -14523,7 +15246,7 @@ function createNemaMotorWireGeometry(input) {
14523
15246
  ...Array.from({ length: pinCount }, (_, i) => ({
14524
15247
  color: "#b8bec6",
14525
15248
  geometry: place(
14526
- jscad4.primitives.cuboid({
15249
+ jscad6.primitives.cuboid({
14527
15250
  size: [contactLength, contactSize, contactSize],
14528
15251
  center: [contactLength / 2, (i - (pinCount - 1) / 2) * pitch, 0]
14529
15252
  })
@@ -14615,12 +15338,12 @@ function createNemaMotorSections(input) {
14615
15338
  else {
14616
15339
  const cut = r - p.shaftFlatDepth;
14617
15340
  const angle = Math.acos(cut / r);
14618
- const profile = Array.from({ length: 97 }, (_, i) => {
15341
+ const profile6 = Array.from({ length: 97 }, (_, i) => {
14619
15342
  const a = angle + (2 * Math.PI - 2 * angle) * i / 96;
14620
15343
  return [r * Math.cos(a), r * Math.sin(a)];
14621
15344
  });
14622
15345
  const rotation = p.shaftFlatAngle * Math.PI / 180;
14623
- const d = profile.map(([x, y]) => [
15346
+ const d = profile6.map(([x, y]) => [
14624
15347
  x * Math.cos(rotation) - y * Math.sin(rotation),
14625
15348
  x * Math.sin(rotation) + y * Math.cos(rotation)
14626
15349
  ]);
@@ -14631,7 +15354,7 @@ function createNemaMotorSections(input) {
14631
15354
  }
14632
15355
 
14633
15356
  // lib/NemaMotor.tsx
14634
- var generalize = jscad5.modifiers.generalize;
15357
+ var generalize3 = jscad7.modifiers.generalize;
14635
15358
  function NemaMotor({
14636
15359
  bodyColor = "#242830",
14637
15360
  capColor = "#aeb5bd",
@@ -14640,7 +15363,7 @@ function NemaMotor({
14640
15363
  ...props
14641
15364
  }) {
14642
15365
  const p = resolveNemaMotorProps(props);
14643
- const screw = p.backFace === "screws" ? jscad5.transforms.rotateX(
15366
+ const screw = p.backFace === "screws" ? jscad7.transforms.rotateX(
14644
15367
  Math.PI,
14645
15368
  createHexSocketBoltGeom({
14646
15369
  metricSize: p.backFaceScrewSize,
@@ -14651,16 +15374,16 @@ function NemaMotor({
14651
15374
  const halfPitch = p.backFaceHoleSpacing / 2;
14652
15375
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
14653
15376
  createNemaMotorSections(p).map((section, index) => {
14654
- const outline = jscad5.geometries.geom2.fromPoints(section.outline);
14655
- const profile = section.holes.length ? jscad5.booleans.subtract(
15377
+ const outline = jscad7.geometries.geom2.fromPoints(section.outline);
15378
+ const profile6 = section.holes.length ? jscad7.booleans.subtract(
14656
15379
  outline,
14657
- ...section.holes.map((h2) => jscad5.geometries.geom2.fromPoints(h2))
15380
+ ...section.holes.map((h2) => jscad7.geometries.geom2.fromPoints(h2))
14658
15381
  ) : outline;
14659
- const geometry = jscad5.transforms.translate(
15382
+ const geometry = jscad7.transforms.translate(
14660
15383
  [0, 0, section.zMin],
14661
- jscad5.extrusions.extrudeLinear(
15384
+ jscad7.extrusions.extrudeLinear(
14662
15385
  { height: section.zMax - section.zMin },
14663
- profile
15386
+ profile6
14664
15387
  )
14665
15388
  );
14666
15389
  return /* @__PURE__ */ jsx(
@@ -14668,7 +15391,7 @@ function NemaMotor({
14668
15391
  {
14669
15392
  material: section.name === "body" ? componentMaterials.moldedPlastic : section.name === "shaft" ? componentMaterials.steel : componentMaterials.brushedMetal,
14670
15393
  color: section.name === "body" ? bodyColor : section.name === "shaft" ? shaftColor : capColor,
14671
- children: /* @__PURE__ */ jsx(Custom, { geometry: generalize({ simplify: true }, geometry) })
15394
+ children: /* @__PURE__ */ jsx(Custom, { geometry: generalize3({ simplify: true }, geometry) })
14672
15395
  },
14673
15396
  `${section.name}-${index}`
14674
15397
  );
@@ -14678,7 +15401,7 @@ function NemaMotor({
14678
15401
  {
14679
15402
  material: componentMaterials.rubber,
14680
15403
  color,
14681
- children: /* @__PURE__ */ jsx(Custom, { geometry: generalize({ simplify: true }, geometry) })
15404
+ children: /* @__PURE__ */ jsx(Custom, { geometry: generalize3({ simplify: true }, geometry) })
14682
15405
  },
14683
15406
  `wire-${index}`
14684
15407
  )),
@@ -14691,9 +15414,9 @@ function NemaMotor({
14691
15414
  children: /* @__PURE__ */ jsx(
14692
15415
  Custom,
14693
15416
  {
14694
- geometry: jscad5.transforms.translate(
15417
+ geometry: jscad7.transforms.translate(
14695
15418
  [x, y, -p.bodyLength],
14696
- generalize({ simplify: true }, screw)
15419
+ generalize3({ simplify: true }, screw)
14697
15420
  )
14698
15421
  }
14699
15422
  )
@@ -14708,14 +15431,14 @@ var NEMA17 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 17
14708
15431
  var NEMA23 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 23 });
14709
15432
 
14710
15433
  // lib/models/nema/register.tsx
14711
- var model59 = defineModelRenderer({
15434
+ var model67 = defineModelRenderer({
14712
15435
  name: "nema",
14713
15436
  schema: nemaMotorModelDefinitionSchema,
14714
15437
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(NemaMotor, { ...props }),
14715
15438
  pads: "none"
14716
15439
  });
14717
- function register59(registry2) {
14718
- registry2.register(model59);
15440
+ function register67(registry2) {
15441
+ registry2.register(model67);
14719
15442
  }
14720
15443
 
14721
15444
  // lib/models/nylonlocknut/mesh.ts
@@ -14851,14 +15574,14 @@ function NylonLockNut({
14851
15574
  }
14852
15575
 
14853
15576
  // lib/models/nylonlocknut/register.tsx
14854
- var model60 = defineModelRenderer({
15577
+ var model68 = defineModelRenderer({
14855
15578
  name: "nylonlocknut",
14856
15579
  schema: nylonLockNutModelDefinitionSchema,
14857
15580
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(NylonLockNut, { ...props }),
14858
15581
  pads: "none"
14859
15582
  });
14860
- function register60(registry2) {
14861
- registry2.register(model60);
15583
+ function register68(registry2) {
15584
+ registry2.register(model68);
14862
15585
  }
14863
15586
 
14864
15587
  // lib/models/panscrew/mesh.ts
@@ -15064,14 +15787,107 @@ function PanScrew({ color = "#737e8f", ...props }) {
15064
15787
  }
15065
15788
 
15066
15789
  // lib/models/panscrew/register.tsx
15067
- var model61 = defineModelRenderer({
15790
+ var model69 = defineModelRenderer({
15068
15791
  name: "panscrew",
15069
15792
  schema: panScrewModelDefinitionSchema,
15070
15793
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PanScrew, { ...props }),
15071
15794
  pads: "none"
15072
15795
  });
15073
- function register61(registry2) {
15074
- registry2.register(model61);
15796
+ function register69(registry2) {
15797
+ registry2.register(model69);
15798
+ }
15799
+
15800
+ // lib/models/perforatedsheet/geometry.ts
15801
+ import jscad8 from "@jscad/modeling";
15802
+ var {
15803
+ booleans,
15804
+ primitives: primitives3,
15805
+ extrusions: extrusions3,
15806
+ geometries: geometries3,
15807
+ modifiers: modifiers3,
15808
+ measurements: measurements3
15809
+ } = jscad8;
15810
+ var generalize4 = modifiers3.generalize;
15811
+ var { subtract } = booleans;
15812
+ var { rectangle: rectangle3, roundedRectangle: roundedRectangle3, circle: circle2 } = primitives3;
15813
+ var profile3 = (shape39, height10) => extrusions3.extrudeLinear({ height: height10 }, shape39);
15814
+ function perforated(p) {
15815
+ const holes = [];
15816
+ const rows = Math.floor((p.width - 2 * p.edgeY) / p.pitchY + 1 + 1e-10);
15817
+ const cols = Math.floor((p.length - 2 * p.edgeX) / p.pitchX + 1 + 1e-10);
15818
+ for (let row = 0; row < rows; row++)
15819
+ for (let col = 0; col < cols; col++) {
15820
+ const x = p.edgeX + col * p.pitchX + (row % 2 ? p.stagger : 0);
15821
+ if (x > p.length - p.edgeX + 1e-10) continue;
15822
+ holes.push(
15823
+ circle2({
15824
+ radius: p.holeDiameter / 2,
15825
+ segments: 48,
15826
+ center: [x - p.length / 2, p.edgeY + row * p.pitchY - p.width / 2]
15827
+ })
15828
+ );
15829
+ }
15830
+ return profile3(
15831
+ subtract(rectangle3({ size: [p.length, p.width] }), ...holes),
15832
+ p.thickness
15833
+ );
15834
+ }
15835
+ function createPerforatedSheetGeom(input) {
15836
+ const p = perforatedSheetModelPropsSchema.parse(input);
15837
+ return perforated(p);
15838
+ }
15839
+ function createPerforatedSheetMesh(input) {
15840
+ const geom = generalize4(
15841
+ { snap: true, triangulate: true },
15842
+ createPerforatedSheetGeom(input)
15843
+ );
15844
+ const epsilon = Math.max(...measurements3.measureDimensions(geom)) * 1e-10;
15845
+ const positions = [];
15846
+ const indices = [];
15847
+ const lookup = /* @__PURE__ */ new Map();
15848
+ const vertex = (v) => {
15849
+ const key = v.map((x) => Math.round(x / epsilon)).join(",");
15850
+ let index = lookup.get(key);
15851
+ if (index === void 0) {
15852
+ index = positions.length / 3;
15853
+ positions.push(...v);
15854
+ lookup.set(key, index);
15855
+ }
15856
+ return index;
15857
+ };
15858
+ for (const poly of geometries3.geom3.toPolygons(geom)) {
15859
+ for (let i = 1; i < poly.vertices.length - 1; i++) {
15860
+ const a = poly.vertices[0], b = poly.vertices[i], c = poly.vertices[i + 1];
15861
+ const u = b.map((x, j) => x - a[j]), v = c.map((x, j) => x - a[j]);
15862
+ const area = Math.hypot(
15863
+ u[1] * v[2] - u[2] * v[1],
15864
+ u[2] * v[0] - u[0] * v[2],
15865
+ u[0] * v[1] - u[1] * v[0]
15866
+ );
15867
+ if (area > epsilon * epsilon)
15868
+ indices.push(vertex(a), vertex(b), vertex(c));
15869
+ }
15870
+ }
15871
+ return { positions, indices };
15872
+ }
15873
+
15874
+ // lib/models/perforatedsheet/PerforatedSheet.tsx
15875
+ function PerforatedSheet({
15876
+ color = "#929da9",
15877
+ ...props
15878
+ }) {
15879
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createPerforatedSheetGeom(props) }) });
15880
+ }
15881
+
15882
+ // lib/models/perforatedsheet/register.tsx
15883
+ var model70 = defineModelRenderer({
15884
+ name: "perforatedsheet",
15885
+ schema: perforatedSheetModelDefinitionSchema,
15886
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PerforatedSheet, { ...props }),
15887
+ pads: "none"
15888
+ });
15889
+ function register70(registry2) {
15890
+ registry2.register(model70);
15075
15891
  }
15076
15892
 
15077
15893
  // lib/models/plainbushing/mesh.ts
@@ -15081,7 +15897,7 @@ function createPlainBushingMesh(input) {
15081
15897
  const ri = d.innerDiameter / 2;
15082
15898
  const ro = d.outerDiameter / 2;
15083
15899
  const c = props.edgeChamfer;
15084
- const profile = c > 0 ? [
15900
+ const profile6 = c > 0 ? [
15085
15901
  [d.endOuterDiameter / 2, 0],
15086
15902
  [ro, c],
15087
15903
  [ro, d.length - c],
@@ -15099,14 +15915,14 @@ function createPlainBushingMesh(input) {
15099
15915
  const segments = 96;
15100
15916
  const positions = [];
15101
15917
  const indices = [];
15102
- for (const [radius, z] of profile)
15918
+ for (const [radius, z] of profile6)
15103
15919
  for (let i = 0; i < segments; i++) {
15104
15920
  const angle = i * Math.PI * 2 / segments;
15105
15921
  positions.push(radius * Math.cos(angle), radius * Math.sin(angle), z);
15106
15922
  }
15107
- for (let ring = 0; ring < profile.length; ring++) {
15923
+ for (let ring = 0; ring < profile6.length; ring++) {
15108
15924
  const a = ring * segments;
15109
- const b = (ring + 1) % profile.length * segments;
15925
+ const b = (ring + 1) % profile6.length * segments;
15110
15926
  for (let i = 0; i < segments; i++) {
15111
15927
  const next = (i + 1) % segments;
15112
15928
  indices.push(a + i, a + next, b + next, a + i, b + next, b + i);
@@ -15127,14 +15943,242 @@ function PlainBushing({
15127
15943
  }
15128
15944
 
15129
15945
  // lib/models/plainbushing/register.tsx
15130
- var model62 = defineModelRenderer({
15946
+ var model71 = defineModelRenderer({
15131
15947
  name: "plainbushing",
15132
15948
  schema: plainBushingModelDefinitionSchema,
15133
15949
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PlainBushing, { ...props }),
15134
15950
  pads: "none"
15135
15951
  });
15136
- function register62(registry2) {
15137
- registry2.register(model62);
15952
+ function register71(registry2) {
15953
+ registry2.register(model71);
15954
+ }
15955
+
15956
+ // lib/models/pushfitplug/geometry.ts
15957
+ import jscad9 from "@jscad/modeling";
15958
+ var { primitives: primitives4, extrusions: extrusions4, geometries: geometries4, modifiers: modifiers4, measurements: measurements4 } = jscad9;
15959
+ var generalize5 = modifiers4.generalize;
15960
+ var { rectangle: rectangle4, roundedRectangle: roundedRectangle4, polygon: polygon3 } = primitives4;
15961
+ function createPushFitPlugGeom(input) {
15962
+ const p = pushFitPlugModelPropsSchema.parse(input);
15963
+ return extrusions4.extrudeRotate(
15964
+ { segments: 64 },
15965
+ polygon3({
15966
+ points: [
15967
+ [0, 0],
15968
+ [p.tubeDiameter / 2, 0],
15969
+ [p.tubeDiameter / 2, p.length - p.headThickness],
15970
+ [p.headDiameter / 2, p.length - p.headThickness],
15971
+ [p.headDiameter / 2, p.length],
15972
+ [0, p.length]
15973
+ ]
15974
+ })
15975
+ );
15976
+ }
15977
+ function createPushFitPlugMesh(input) {
15978
+ const geom = generalize5(
15979
+ { snap: true, triangulate: true },
15980
+ createPushFitPlugGeom(input)
15981
+ );
15982
+ const epsilon = Math.max(...measurements4.measureDimensions(geom)) * 1e-10;
15983
+ const positions = [];
15984
+ const indices = [];
15985
+ const lookup = /* @__PURE__ */ new Map();
15986
+ const vertex = (v) => {
15987
+ const key = v.map((x) => Math.round(x / epsilon)).join(",");
15988
+ let index = lookup.get(key);
15989
+ if (index === void 0) {
15990
+ index = positions.length / 3;
15991
+ positions.push(...v);
15992
+ lookup.set(key, index);
15993
+ }
15994
+ return index;
15995
+ };
15996
+ for (const poly of geometries4.geom3.toPolygons(geom)) {
15997
+ for (let i = 1; i < poly.vertices.length - 1; i++) {
15998
+ const a = poly.vertices[0], b = poly.vertices[i], c = poly.vertices[i + 1];
15999
+ const u = b.map((x, j) => x - a[j]), v = c.map((x, j) => x - a[j]);
16000
+ const area = Math.hypot(
16001
+ u[1] * v[2] - u[2] * v[1],
16002
+ u[2] * v[0] - u[0] * v[2],
16003
+ u[0] * v[1] - u[1] * v[0]
16004
+ );
16005
+ if (area > epsilon * epsilon)
16006
+ indices.push(vertex(a), vertex(b), vertex(c));
16007
+ }
16008
+ }
16009
+ return { positions, indices };
16010
+ }
16011
+
16012
+ // lib/models/pushfitplug/PushFitPlug.tsx
16013
+ function PushFitPlug({ color = "#929da9", ...props }) {
16014
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createPushFitPlugGeom(props) }) });
16015
+ }
16016
+
16017
+ // lib/models/pushfitplug/register.tsx
16018
+ var model72 = defineModelRenderer({
16019
+ name: "pushfitplug",
16020
+ schema: pushFitPlugModelDefinitionSchema,
16021
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PushFitPlug, { ...props }),
16022
+ pads: "none"
16023
+ });
16024
+ function register72(registry2) {
16025
+ registry2.register(model72);
16026
+ }
16027
+
16028
+ // lib/models/rectangularbar/geometry.ts
16029
+ import jscad10 from "@jscad/modeling";
16030
+ var { primitives: primitives5, extrusions: extrusions5, geometries: geometries5, modifiers: modifiers5, measurements: measurements5 } = jscad10;
16031
+ var generalize6 = modifiers5.generalize;
16032
+ var { rectangle: rectangle5, roundedRectangle: roundedRectangle5 } = primitives5;
16033
+ var profile4 = (shape39, height10) => extrusions5.extrudeLinear({ height: height10 }, shape39);
16034
+ var roundedRect = (width10, height10, radius) => radius ? roundedRectangle5({
16035
+ size: [width10, height10],
16036
+ roundRadius: radius,
16037
+ segments: 64
16038
+ }) : rectangle5({ size: [width10, height10] });
16039
+ function createRectangularBarGeom(input) {
16040
+ const p = rectangularBarModelPropsSchema.parse(input);
16041
+ return profile4(roundedRect(p.width, p.height, p.cornerRadius), p.length);
16042
+ }
16043
+ function createRectangularBarMesh(input) {
16044
+ const geom = generalize6(
16045
+ { snap: true, triangulate: true },
16046
+ createRectangularBarGeom(input)
16047
+ );
16048
+ const epsilon = Math.max(...measurements5.measureDimensions(geom)) * 1e-10;
16049
+ const positions = [];
16050
+ const indices = [];
16051
+ const lookup = /* @__PURE__ */ new Map();
16052
+ const vertex = (v) => {
16053
+ const key = v.map((x) => Math.round(x / epsilon)).join(",");
16054
+ let index = lookup.get(key);
16055
+ if (index === void 0) {
16056
+ index = positions.length / 3;
16057
+ positions.push(...v);
16058
+ lookup.set(key, index);
16059
+ }
16060
+ return index;
16061
+ };
16062
+ for (const poly of geometries5.geom3.toPolygons(geom)) {
16063
+ for (let i = 1; i < poly.vertices.length - 1; i++) {
16064
+ const a = poly.vertices[0], b = poly.vertices[i], c = poly.vertices[i + 1];
16065
+ const u = b.map((x, j) => x - a[j]), v = c.map((x, j) => x - a[j]);
16066
+ const area = Math.hypot(
16067
+ u[1] * v[2] - u[2] * v[1],
16068
+ u[2] * v[0] - u[0] * v[2],
16069
+ u[0] * v[1] - u[1] * v[0]
16070
+ );
16071
+ if (area > epsilon * epsilon)
16072
+ indices.push(vertex(a), vertex(b), vertex(c));
16073
+ }
16074
+ }
16075
+ return { positions, indices };
16076
+ }
16077
+
16078
+ // lib/models/rectangularbar/RectangularBar.tsx
16079
+ function RectangularBar({
16080
+ color = "#929da9",
16081
+ ...props
16082
+ }) {
16083
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createRectangularBarGeom(props) }) });
16084
+ }
16085
+
16086
+ // lib/models/rectangularbar/register.tsx
16087
+ var model73 = defineModelRenderer({
16088
+ name: "rectangularbar",
16089
+ schema: rectangularBarModelDefinitionSchema,
16090
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(RectangularBar, { ...props }),
16091
+ pads: "none"
16092
+ });
16093
+ function register73(registry2) {
16094
+ registry2.register(model73);
16095
+ }
16096
+
16097
+ // lib/models/rectangulartube/geometry.ts
16098
+ import jscad11 from "@jscad/modeling";
16099
+ var {
16100
+ booleans: booleans2,
16101
+ primitives: primitives6,
16102
+ extrusions: extrusions6,
16103
+ geometries: geometries6,
16104
+ modifiers: modifiers6,
16105
+ measurements: measurements6
16106
+ } = jscad11;
16107
+ var generalize7 = modifiers6.generalize;
16108
+ var { subtract: subtract2 } = booleans2;
16109
+ var { rectangle: rectangle6, roundedRectangle: roundedRectangle6 } = primitives6;
16110
+ var profile5 = (shape39, height10) => extrusions6.extrudeLinear({ height: height10 }, shape39);
16111
+ var roundedRect2 = (width10, height10, radius) => radius ? roundedRectangle6({
16112
+ size: [width10, height10],
16113
+ roundRadius: radius,
16114
+ segments: 64
16115
+ }) : rectangle6({ size: [width10, height10] });
16116
+ function createRectangularTubeGeom(input) {
16117
+ const p = rectangularTubeModelPropsSchema.parse(input);
16118
+ return profile5(
16119
+ subtract2(
16120
+ roundedRect2(p.width, p.height, p.outerRadius),
16121
+ roundedRect2(
16122
+ p.width - 2 * p.wallThickness,
16123
+ p.height - 2 * p.wallThickness,
16124
+ p.innerRadius
16125
+ )
16126
+ ),
16127
+ p.length
16128
+ );
16129
+ }
16130
+ function createRectangularTubeMesh(input) {
16131
+ const geom = generalize7(
16132
+ { snap: true, triangulate: true },
16133
+ createRectangularTubeGeom(input)
16134
+ );
16135
+ const epsilon = Math.max(...measurements6.measureDimensions(geom)) * 1e-10;
16136
+ const positions = [];
16137
+ const indices = [];
16138
+ const lookup = /* @__PURE__ */ new Map();
16139
+ const vertex = (v) => {
16140
+ const key = v.map((x) => Math.round(x / epsilon)).join(",");
16141
+ let index = lookup.get(key);
16142
+ if (index === void 0) {
16143
+ index = positions.length / 3;
16144
+ positions.push(...v);
16145
+ lookup.set(key, index);
16146
+ }
16147
+ return index;
16148
+ };
16149
+ for (const poly of geometries6.geom3.toPolygons(geom)) {
16150
+ for (let i = 1; i < poly.vertices.length - 1; i++) {
16151
+ const a = poly.vertices[0], b = poly.vertices[i], c = poly.vertices[i + 1];
16152
+ const u = b.map((x, j) => x - a[j]), v = c.map((x, j) => x - a[j]);
16153
+ const area = Math.hypot(
16154
+ u[1] * v[2] - u[2] * v[1],
16155
+ u[2] * v[0] - u[0] * v[2],
16156
+ u[0] * v[1] - u[1] * v[0]
16157
+ );
16158
+ if (area > epsilon * epsilon)
16159
+ indices.push(vertex(a), vertex(b), vertex(c));
16160
+ }
16161
+ }
16162
+ return { positions, indices };
16163
+ }
16164
+
16165
+ // lib/models/rectangulartube/RectangularTube.tsx
16166
+ function RectangularTube({
16167
+ color = "#929da9",
16168
+ ...props
16169
+ }) {
16170
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createRectangularTubeGeom(props) }) });
16171
+ }
16172
+
16173
+ // lib/models/rectangulartube/register.tsx
16174
+ var model74 = defineModelRenderer({
16175
+ name: "rectangulartube",
16176
+ schema: rectangularTubeModelDefinitionSchema,
16177
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(RectangularTube, { ...props }),
16178
+ pads: "none"
16179
+ });
16180
+ function register74(registry2) {
16181
+ registry2.register(model74);
15138
16182
  }
15139
16183
 
15140
16184
  // lib/models/rigidcoupler/mesh.ts
@@ -15171,14 +16215,14 @@ function RigidCoupler({
15171
16215
  }
15172
16216
 
15173
16217
  // lib/models/rigidcoupler/register.tsx
15174
- var model63 = defineModelRenderer({
16218
+ var model75 = defineModelRenderer({
15175
16219
  name: "rigidcoupler",
15176
16220
  schema: rigidCouplerModelDefinitionSchema,
15177
16221
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(RigidCoupler, { ...props }),
15178
16222
  pads: "none"
15179
16223
  });
15180
- function register63(registry2) {
15181
- registry2.register(model63);
16224
+ function register75(registry2) {
16225
+ registry2.register(model75);
15182
16226
  }
15183
16227
 
15184
16228
  // lib/models/setscrew/mesh.ts
@@ -15293,14 +16337,14 @@ function SetScrew({ color = "#737e8f", ...props }) {
15293
16337
  }
15294
16338
 
15295
16339
  // lib/models/setscrew/register.tsx
15296
- var model64 = defineModelRenderer({
16340
+ var model76 = defineModelRenderer({
15297
16341
  name: "setscrew",
15298
16342
  schema: setscrewModelDefinitionSchema,
15299
16343
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SetScrew, { ...props }),
15300
16344
  pads: "none"
15301
16345
  });
15302
- function register64(registry2) {
15303
- registry2.register(model64);
16346
+ function register76(registry2) {
16347
+ registry2.register(model76);
15304
16348
  }
15305
16349
 
15306
16350
  // lib/models/shaftcollar/mesh.ts
@@ -15332,14 +16376,14 @@ function ShaftCollar({ color = "#737e8f", ...props }) {
15332
16376
  }
15333
16377
 
15334
16378
  // lib/models/shaftcollar/register.tsx
15335
- var model65 = defineModelRenderer({
16379
+ var model77 = defineModelRenderer({
15336
16380
  name: "shaftcollar",
15337
16381
  schema: shaftCollarModelDefinitionSchema,
15338
16382
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ShaftCollar, { ...props }),
15339
16383
  pads: "none"
15340
16384
  });
15341
- function register65(registry2) {
15342
- registry2.register(model65);
16385
+ function register77(registry2) {
16386
+ registry2.register(model77);
15343
16387
  }
15344
16388
 
15345
16389
  // lib/mechanical/sheet-metal-mesh.ts
@@ -15365,7 +16409,7 @@ function holeOutline(hole) {
15365
16409
  }
15366
16410
  function createSheetMetalMesh(input) {
15367
16411
  const props = sheetMetalModelPropsSchema.parse(input);
15368
- const { width: width10, baseLength, flangeHeight, thickness, profile } = props;
16412
+ const { width: width10, baseLength, flangeHeight, thickness, profile: profile6 } = props;
15369
16413
  const radius = props.insideBendRadius + thickness / 2;
15370
16414
  const positions = [];
15371
16415
  const indices = [];
@@ -15378,13 +16422,13 @@ function createSheetMetalMesh(input) {
15378
16422
  addTriangle([vertices[0], vertices[1], vertices[2]], reverse);
15379
16423
  addTriangle([vertices[0], vertices[2], vertices[3]], reverse);
15380
16424
  };
15381
- const panels = profile === "plate" ? ["base"] : profile === "angle" ? ["base", "right"] : ["base", "left", "right"];
16425
+ const panels = profile6 === "plate" ? ["base"] : profile6 === "angle" ? ["base", "right"] : ["base", "left", "right"];
15382
16426
  for (const hole of props.holes) {
15383
16427
  if (!panels.includes(hole.panel))
15384
- throw new Error(`No ${hole.panel} panel on ${profile}`);
16428
+ throw new Error(`No ${hole.panel} panel on ${profile6}`);
15385
16429
  }
15386
16430
  for (const panel of panels) {
15387
- const length20 = panel === "base" ? baseLength : flangeHeight;
16431
+ const length26 = panel === "base" ? baseLength : flangeHeight;
15388
16432
  const holes = props.holes.filter((hole) => hole.panel === panel).map(holeOutline);
15389
16433
  const bounds = holes.map((outline2) => ({
15390
16434
  minU: Math.min(...outline2.map((p) => p.u)),
@@ -15393,17 +16437,17 @@ function createSheetMetalMesh(input) {
15393
16437
  maxV: Math.max(...outline2.map((p) => p.v))
15394
16438
  }));
15395
16439
  for (const [i, box] of bounds.entries()) {
15396
- if (box.minU <= -length20 / 2 || box.maxU >= length20 / 2 || box.minV <= -width10 / 2 || box.maxV >= width10 / 2)
16440
+ if (box.minU <= -length26 / 2 || box.maxU >= length26 / 2 || box.minV <= -width10 / 2 || box.maxV >= width10 / 2)
15397
16441
  throw new Error(`Hole crosses ${panel} panel edge or bend tangent`);
15398
16442
  for (const previous of bounds.slice(0, i))
15399
16443
  if (box.minU <= previous.maxU && box.maxU >= previous.minU && box.minV <= previous.maxV && box.maxV >= previous.minV)
15400
16444
  throw new Error("Hole bounding boxes must not overlap");
15401
16445
  }
15402
16446
  const outline = [
15403
- { u: -length20 / 2, v: -width10 / 2 },
15404
- { u: length20 / 2, v: -width10 / 2 },
15405
- { u: length20 / 2, v: width10 / 2 },
15406
- { u: -length20 / 2, v: width10 / 2 }
16447
+ { u: -length26 / 2, v: -width10 / 2 },
16448
+ { u: length26 / 2, v: -width10 / 2 },
16449
+ { u: length26 / 2, v: width10 / 2 },
16450
+ { u: -length26 / 2, v: width10 / 2 }
15407
16451
  ];
15408
16452
  const loops = [outline, ...holes.map((hole) => [...hole].reverse())];
15409
16453
  const points = loops.flat();
@@ -15432,7 +16476,7 @@ function createSheetMetalMesh(input) {
15432
16476
  for (const [loopIndex, loop] of loops.entries())
15433
16477
  for (let i = 0; i < loop.length; i++) {
15434
16478
  const a = loop[i], b = loop[(i + 1) % loop.length];
15435
- if (loopIndex === 0 && a.u === b.u && (panel === "base" && (a.u > 0 && profile !== "plate" || a.u < 0 && profile === "channel") || panel !== "base" && a.u < 0))
16479
+ if (loopIndex === 0 && a.u === b.u && (panel === "base" && (a.u > 0 && profile6 !== "plate" || a.u < 0 && profile6 === "channel") || panel !== "base" && a.u < 0))
15436
16480
  continue;
15437
16481
  addQuad(
15438
16482
  [
@@ -15445,7 +16489,7 @@ function createSheetMetalMesh(input) {
15445
16489
  );
15446
16490
  }
15447
16491
  }
15448
- const sides = profile === "plate" ? [] : profile === "angle" ? [1] : [-1, 1];
16492
+ const sides = profile6 === "plate" ? [] : profile6 === "angle" ? [1] : [-1, 1];
15449
16493
  for (const side of sides) {
15450
16494
  const project = (angle, crossSection) => {
15451
16495
  const r = radius - crossSection.offset;
@@ -15493,14 +16537,14 @@ function SheetMetal({ color = "#737e8f", ...props }) {
15493
16537
  }
15494
16538
 
15495
16539
  // lib/models/sheetmetal/register.tsx
15496
- var model66 = defineModelRenderer({
16540
+ var model78 = defineModelRenderer({
15497
16541
  name: "sheetmetal",
15498
16542
  schema: sheetMetalModelDefinitionSchema,
15499
16543
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SheetMetal, { ...props }),
15500
16544
  pads: "none"
15501
16545
  });
15502
- function register66(registry2) {
15503
- registry2.register(model66);
16546
+ function register78(registry2) {
16547
+ registry2.register(model78);
15504
16548
  }
15505
16549
 
15506
16550
  // lib/models/spacer/mesh.ts
@@ -15523,14 +16567,14 @@ function Spacer({ color = "#a18450", ...props }) {
15523
16567
  }
15524
16568
 
15525
16569
  // lib/models/spacer/register.tsx
15526
- var model67 = defineModelRenderer({
16570
+ var model79 = defineModelRenderer({
15527
16571
  name: "spacer",
15528
16572
  schema: spacerModelDefinitionSchema,
15529
16573
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(Spacer, { ...props }),
15530
16574
  pads: "none"
15531
16575
  });
15532
- function register67(registry2) {
15533
- registry2.register(model67);
16576
+ function register79(registry2) {
16577
+ registry2.register(model79);
15534
16578
  }
15535
16579
 
15536
16580
  // lib/models/splitwasher/mesh.ts
@@ -15593,14 +16637,14 @@ function SplitWasher({ color = "#929ba6", ...props }) {
15593
16637
  }
15594
16638
 
15595
16639
  // lib/models/splitwasher/register.tsx
15596
- var model68 = defineModelRenderer({
16640
+ var model80 = defineModelRenderer({
15597
16641
  name: "splitwasher",
15598
16642
  schema: splitWasherModelDefinitionSchema,
15599
16643
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SplitWasher, { ...props }),
15600
16644
  pads: "none"
15601
16645
  });
15602
- function register68(registry2) {
15603
- registry2.register(model68);
16646
+ function register80(registry2) {
16647
+ registry2.register(model80);
15604
16648
  }
15605
16649
 
15606
16650
  // lib/SpurGear.tsx
@@ -15612,14 +16656,14 @@ function SpurGear({ color = "#737e8f", ...props }) {
15612
16656
  }
15613
16657
 
15614
16658
  // lib/models/spurgear/register.tsx
15615
- var model69 = defineModelRenderer({
16659
+ var model81 = defineModelRenderer({
15616
16660
  name: "spurgear",
15617
16661
  schema: spurGearModelDefinitionSchema,
15618
16662
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SpurGear, { ...props }),
15619
16663
  pads: "none"
15620
16664
  });
15621
- function register69(registry2) {
15622
- registry2.register(model69);
16665
+ function register81(registry2) {
16666
+ registry2.register(model81);
15623
16667
  }
15624
16668
 
15625
16669
  // lib/models/threadedrod/mesh.ts
@@ -15709,14 +16753,14 @@ function ThreadedRod({ color = "#737e8f", ...props }) {
15709
16753
  }
15710
16754
 
15711
16755
  // lib/models/threadedrod/register.tsx
15712
- var model70 = defineModelRenderer({
16756
+ var model82 = defineModelRenderer({
15713
16757
  name: "threadedrod",
15714
16758
  schema: threadedRodModelDefinitionSchema,
15715
16759
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ThreadedRod, { ...props }),
15716
16760
  pads: "none"
15717
16761
  });
15718
- function register70(registry2) {
15719
- registry2.register(model70);
16762
+ function register82(registry2) {
16763
+ registry2.register(model82);
15720
16764
  }
15721
16765
 
15722
16766
  // lib/models/torsionspring/mesh.ts
@@ -15805,20 +16849,20 @@ function TorsionSpring({
15805
16849
  }
15806
16850
 
15807
16851
  // lib/models/torsionspring/register.tsx
15808
- var model71 = defineModelRenderer({
16852
+ var model83 = defineModelRenderer({
15809
16853
  name: "torsionspring",
15810
16854
  schema: torsionSpringModelDefinitionSchema,
15811
16855
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TorsionSpring, { ...props }),
15812
16856
  pads: "none"
15813
16857
  });
15814
- function register71(registry2) {
15815
- registry2.register(model71);
16858
+ function register83(registry2) {
16859
+ registry2.register(model83);
15816
16860
  }
15817
16861
 
15818
16862
  // lib/models/tslotextrusion/mesh.ts
15819
16863
  function createTSlotExtrusionMesh(input = {}) {
15820
16864
  const props = tSlotExtrusionModelPropsSchema.parse(input);
15821
- const { width: width10, height: height10, length: length20, cornerRadius, lipThickness, pocketDepth } = props;
16865
+ const { width: width10, height: height10, length: length26, cornerRadius, lipThickness, pocketDepth } = props;
15822
16866
  const slot = props.slotWidth / 2;
15823
16867
  const pocket = props.pocketWidth / 2;
15824
16868
  const depth = lipThickness + pocketDepth;
@@ -15855,7 +16899,7 @@ function createTSlotExtrusionMesh(input = {}) {
15855
16899
  outer,
15856
16900
  holes: props.boreDiameter > 0 ? [circularProfile(0, 0, props.boreDiameter / 2)] : [],
15857
16901
  start: 0,
15858
- end: length20
16902
+ end: length26
15859
16903
  });
15860
16904
  }
15861
16905
 
@@ -15871,14 +16915,14 @@ function TSlotExtrusion({
15871
16915
  }
15872
16916
 
15873
16917
  // lib/models/tslotextrusion/register.tsx
15874
- var model72 = defineModelRenderer({
16918
+ var model84 = defineModelRenderer({
15875
16919
  name: "tslotextrusion",
15876
16920
  schema: tSlotExtrusionModelDefinitionSchema,
15877
16921
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TSlotExtrusion, { ...props }),
15878
16922
  pads: "none"
15879
16923
  });
15880
- function register72(registry2) {
15881
- registry2.register(model72);
16924
+ function register84(registry2) {
16925
+ registry2.register(model84);
15882
16926
  }
15883
16927
 
15884
16928
  // lib/models/tslotgusset/mesh.ts
@@ -15924,14 +16968,14 @@ function TSlotGusset({ color = "#8995a3", ...props }) {
15924
16968
  }
15925
16969
 
15926
16970
  // lib/models/tslotgusset/register.tsx
15927
- var model73 = defineModelRenderer({
16971
+ var model85 = defineModelRenderer({
15928
16972
  name: "tslotgusset",
15929
16973
  schema: tSlotGussetModelDefinitionSchema,
15930
16974
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TSlotGusset, { ...props }),
15931
16975
  pads: "none"
15932
16976
  });
15933
- function register73(registry2) {
15934
- registry2.register(model73);
16977
+ function register85(registry2) {
16978
+ registry2.register(model85);
15935
16979
  }
15936
16980
 
15937
16981
  // lib/models/tslotinsidecorner/mesh.ts
@@ -16005,14 +17049,14 @@ function TSlotInsideCorner({
16005
17049
  }
16006
17050
 
16007
17051
  // lib/models/tslotinsidecorner/register.tsx
16008
- var model74 = defineModelRenderer({
17052
+ var model86 = defineModelRenderer({
16009
17053
  name: "tslotinsidecorner",
16010
17054
  schema: tSlotInsideCornerModelDefinitionSchema,
16011
17055
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TSlotInsideCorner, { ...props }),
16012
17056
  pads: "none"
16013
17057
  });
16014
- function register74(registry2) {
16015
- registry2.register(model74);
17058
+ function register86(registry2) {
17059
+ registry2.register(model86);
16016
17060
  }
16017
17061
 
16018
17062
  // lib/mechanical/worm-gear-mesh.ts
@@ -16066,17 +17110,17 @@ var createWormGearMesh = (input) => {
16066
17110
  fractions.push(fraction);
16067
17111
  }
16068
17112
  }
16069
- const profile = [];
17113
+ const profile6 = [];
16070
17114
  for (let start = 0; start < props.starts; start++) {
16071
17115
  for (const fraction of fractions) {
16072
17116
  const distance2 = Math.min(fraction, 1 - fraction) * axialPitch;
16073
- profile.push({
17117
+ profile6.push({
16074
17118
  angle: (start + fraction) * Math.PI * 2 / props.starts,
16075
17119
  radius: distance2 <= tipHalfWidth ? outsideRadius : distance2 >= rootHalfWidth ? rootRadius : pitchRadius + (toothThickness / 2 - distance2) / pressureTangent
16076
17120
  });
16077
17121
  }
16078
17122
  }
16079
- const count = profile.length;
17123
+ const count = profile6.length;
16080
17124
  const positions = [];
16081
17125
  const indices = [];
16082
17126
  const phase = props.phase % 360 * Math.PI / 180;
@@ -16084,7 +17128,7 @@ var createWormGearMesh = (input) => {
16084
17128
  const ring = (z) => {
16085
17129
  const first = positions.length / 3;
16086
17130
  const rotation = phase + direction * (z / lead) * Math.PI * 2;
16087
- for (const sample of profile) {
17131
+ for (const sample of profile6) {
16088
17132
  const angle = sample.angle + rotation;
16089
17133
  positions.push(
16090
17134
  sample.radius * Math.cos(angle),
@@ -16197,24 +17241,18 @@ function WormGear({ color = "#737e8f", ...props }) {
16197
17241
  }
16198
17242
 
16199
17243
  // lib/models/wormgear/register.tsx
16200
- var model75 = defineModelRenderer({
17244
+ var model87 = defineModelRenderer({
16201
17245
  name: "wormgear",
16202
17246
  schema: wormGearModelDefinitionSchema,
16203
17247
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(WormGear, { ...props }),
16204
17248
  pads: "none"
16205
17249
  });
16206
- function register75(registry2) {
16207
- registry2.register(model75);
17250
+ function register87(registry2) {
17251
+ registry2.register(model87);
16208
17252
  }
16209
17253
 
16210
17254
  // lib/generated/model-renderers.ts
16211
17255
  function registerAllModelRenderers(registry2) {
16212
- register39(registry2);
16213
- register40(registry2);
16214
- register41(registry2);
16215
- register42(registry2);
16216
- register43(registry2);
16217
- register44(registry2);
16218
17256
  register45(registry2);
16219
17257
  register46(registry2);
16220
17258
  register47(registry2);
@@ -16246,6 +17284,18 @@ function registerAllModelRenderers(registry2) {
16246
17284
  register73(registry2);
16247
17285
  register74(registry2);
16248
17286
  register75(registry2);
17287
+ register76(registry2);
17288
+ register77(registry2);
17289
+ register78(registry2);
17290
+ register79(registry2);
17291
+ register80(registry2);
17292
+ register81(registry2);
17293
+ register82(registry2);
17294
+ register83(registry2);
17295
+ register84(registry2);
17296
+ register85(registry2);
17297
+ register86(registry2);
17298
+ register87(registry2);
16249
17299
  }
16250
17300
 
16251
17301
  // lib/default-model-registry.ts
@@ -16587,7 +17637,7 @@ import { fp as fp10 } from "@tscircuit/footprinter";
16587
17637
  var ChipBody = ({
16588
17638
  center,
16589
17639
  width: width10,
16590
- length: length20,
17640
+ length: length26,
16591
17641
  height: height10,
16592
17642
  heightAboveSurface: heightAboveSurface2 = 0.15,
16593
17643
  color = "#555",
@@ -16604,24 +17654,24 @@ var ChipBody = ({
16604
17654
  }) => {
16605
17655
  const straightHeight = height10 * straightHeightRatio;
16606
17656
  const taperHeight = height10 - straightHeight;
16607
- const taperInset = Math.min(width10, length20) * taperRatio;
17657
+ const taperInset = Math.min(width10, length26) * taperRatio;
16608
17658
  const faceWidth = Math.max(width10 - taperInset, width10 * faceRatio);
16609
- const faceLength = Math.max(length20 - taperInset, length20 * faceRatio);
16610
- const defaultNotchRadius = Math.min(width10, length20) * 0.12;
17659
+ const faceLength = Math.max(length26 - taperInset, length26 * faceRatio);
17660
+ const defaultNotchRadius = Math.min(width10, length26) * 0.12;
16611
17661
  const actualNotchRadius = notchRadius ?? defaultNotchRadius;
16612
17662
  const defaultNotchPosition = {
16613
17663
  x: 0,
16614
- y: length20 / 2 - actualNotchRadius * 0.25,
17664
+ y: length26 / 2 - actualNotchRadius * 0.25,
16615
17665
  z: height10
16616
17666
  };
16617
17667
  const actualNotchPosition = notchPosition ?? defaultNotchPosition;
16618
17668
  const body = /* @__PURE__ */ jsxs(Union, { children: [
16619
17669
  /* @__PURE__ */ jsxs(Hull, { children: [
16620
17670
  /* @__PURE__ */ jsx(Translate, { z: 5e-3, children: /* @__PURE__ */ jsx(Cuboid, { size: [faceWidth, faceLength, 0.01] }) }),
16621
- /* @__PURE__ */ jsx(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [width10, length20, 0.01] }) })
17671
+ /* @__PURE__ */ jsx(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [width10, length26, 0.01] }) })
16622
17672
  ] }),
16623
17673
  /* @__PURE__ */ jsxs(Hull, { children: [
16624
- /* @__PURE__ */ jsx(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [width10, length20, 0.01] }) }),
17674
+ /* @__PURE__ */ jsx(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [width10, length26, 0.01] }) }),
16625
17675
  /* @__PURE__ */ jsx(Translate, { z: straightHeight + taperHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [faceWidth, faceLength, 0.01] }) })
16626
17676
  ] })
16627
17677
  ] });
@@ -16638,7 +17688,7 @@ var ChipBody = ({
16638
17688
  let finalBody = body;
16639
17689
  if (chamferSize > 0) {
16640
17690
  const xOffset = width10 / 2;
16641
- const yOffset = length20 / 2;
17691
+ const yOffset = length26 / 2;
16642
17692
  finalBody = /* @__PURE__ */ jsxs(Subtract, { children: [
16643
17693
  body,
16644
17694
  chamferCutout(xOffset, yOffset),
@@ -16668,8 +17718,8 @@ function getExpandedStroke(strokeInput, width10) {
16668
17718
  function getNormal(p1, p2) {
16669
17719
  const dx = p2.x - p1.x;
16670
17720
  const dy = p2.y - p1.y;
16671
- const length20 = Math.sqrt(dx * dx + dy * dy);
16672
- return { x: -dy / length20, y: dx / length20 };
17721
+ const length26 = Math.sqrt(dx * dx + dy * dy);
17722
+ return { x: -dy / length26, y: dx / length26 };
16673
17723
  }
16674
17724
  function addPoint(point, normal, factor) {
16675
17725
  const newPoint = {
@@ -16844,8 +17894,8 @@ var SmdChipLead = (props) => {
16844
17894
  const { thickness, width: width10, padContactLength, bodyDistance, height: height10, rotation } = props;
16845
17895
  const N = 15;
16846
17896
  const points = Array.from({ length: N }).map((_, i) => i / (N - 1) * bodyDistance).map((x) => [x, calculateSCurve(x, props)]);
16847
- const polygon = getExpandedStroke(points, thickness);
16848
- return /* @__PURE__ */ jsx(Colorize, { color: "#c4c7ca", material: componentMaterials.tinnedLead, children: /* @__PURE__ */ jsx(Translate, { offset: { z: 0, y: 0, x: 0, ...props.position }, children: /* @__PURE__ */ jsx(Rotate, { rotation: ["90deg", 0, rotation ?? 0], children: /* @__PURE__ */ jsx(Translate, { offset: { x: 0, y: 0, z: -width10 / 2 }, children: /* @__PURE__ */ jsx(ExtrudeLinear, { height: width10, children: /* @__PURE__ */ jsx(Polygon, { points: polygon.map((p) => [p.x, p.y]) }) }) }) }) }) });
17897
+ const polygon4 = getExpandedStroke(points, thickness);
17898
+ return /* @__PURE__ */ jsx(Colorize, { color: "#c4c7ca", material: componentMaterials.tinnedLead, children: /* @__PURE__ */ jsx(Translate, { offset: { z: 0, y: 0, x: 0, ...props.position }, children: /* @__PURE__ */ jsx(Rotate, { rotation: ["90deg", 0, rotation ?? 0], children: /* @__PURE__ */ jsx(Translate, { offset: { x: 0, y: 0, z: -width10 / 2 }, children: /* @__PURE__ */ jsx(ExtrudeLinear, { height: width10, children: /* @__PURE__ */ jsx(Polygon, { points: polygon4.map((p) => [p.x, p.y]) }) }) }) }) }) });
16849
17899
  };
16850
17900
 
16851
17901
  // lib/Tssop.tsx
@@ -18337,11 +19387,11 @@ var FemaleHeaderRow = ({
18337
19387
  // lib/PushButton.tsx
18338
19388
  var PushButton = ({
18339
19389
  width: width10,
18340
- length: length20,
19390
+ length: length26,
18341
19391
  innerDiameter = 1
18342
19392
  }) => {
18343
19393
  const bodyWidth = width10;
18344
- const bodyLength10 = length20;
19394
+ const bodyLength10 = length26;
18345
19395
  const bodyHeight = width10 * 0.7;
18346
19396
  const legWidth = innerDiameter / 2.5;
18347
19397
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
@@ -18495,7 +19545,7 @@ var PushButtonLeg = (props) => {
18495
19545
  [-verticalLength / 5, horizontalLength / 4],
18496
19546
  [0, 0]
18497
19547
  ];
18498
- const polygon = getExpandedStroke(points, thickness);
19548
+ const polygon4 = getExpandedStroke(points, thickness);
18499
19549
  return /* @__PURE__ */ jsx(Colorize, { color: "#f2f2f2", children: /* @__PURE__ */ jsx(
18500
19550
  Translate,
18501
19551
  {
@@ -18504,7 +19554,7 @@ var PushButtonLeg = (props) => {
18504
19554
  y: position?.y || 0,
18505
19555
  z: position?.z || 0
18506
19556
  },
18507
- children: /* @__PURE__ */ jsx(Rotate, { rotation: [0, 55, rotation], children: /* @__PURE__ */ jsx(ExtrudeLinear, { height: width10, children: /* @__PURE__ */ jsx(Polygon, { points: polygon.map((p) => [p.y, p.x]) }) }) })
19557
+ children: /* @__PURE__ */ jsx(Rotate, { rotation: [0, 55, rotation], children: /* @__PURE__ */ jsx(ExtrudeLinear, { height: width10, children: /* @__PURE__ */ jsx(Polygon, { points: polygon4.map((p) => [p.y, p.x]) }) }) })
18508
19558
  }
18509
19559
  ) });
18510
19560
  };
@@ -22275,12 +23325,12 @@ var JstSh = ({ footprint = "jst6_sh" }) => {
22275
23325
  };
22276
23326
 
22277
23327
  // lib/Crystal.tsx
22278
- var getTerminalPoints = ([centerX, centerY], width10, length20, chamfer, isPinOne) => {
23328
+ var getTerminalPoints = ([centerX, centerY], width10, length26, chamfer, isPinOne) => {
22279
23329
  const xDirection = Math.sign(centerX);
22280
23330
  const yDirection = Math.sign(centerY);
22281
23331
  const halfWidth = width10 / 2;
22282
- const halfLength = length20 / 2;
22283
- const innerChamfer = isPinOne ? Math.min(0.32, length20 * 0.36) : 0;
23332
+ const halfLength = length26 / 2;
23333
+ const innerChamfer = isPinOne ? Math.min(0.32, length26 * 0.36) : 0;
22284
23334
  const outerChamfer = Math.min(chamfer, halfWidth, halfLength);
22285
23335
  const points = [
22286
23336
  [-halfWidth, -halfLength],
@@ -22300,13 +23350,13 @@ var getTerminalPoints = ([centerX, centerY], width10, length20, chamfer, isPinOn
22300
23350
  };
22301
23351
  var getRoundedRectProfile = ({
22302
23352
  width: width10,
22303
- length: length20,
23353
+ length: length26,
22304
23354
  radius,
22305
23355
  height: height10,
22306
23356
  z
22307
23357
  }) => {
22308
23358
  const x = width10 / 2 - radius;
22309
- const y = length20 / 2 - radius;
23359
+ const y = length26 / 2 - radius;
22310
23360
  return [
22311
23361
  [-x, -y],
22312
23362
  [x, -y],
@@ -22450,12 +23500,12 @@ var FPC = ({
22450
23500
  const contactRows = Array.from({ length: pinCount }, (_, index) => {
22451
23501
  const isUpperRow = staggered && index % 2 === 1 !== reverse;
22452
23502
  const y = staggered ? isUpperRow ? rowPitch / 2 : -rowPitch / 2 : 0;
22453
- const length20 = isUpperRow ? topPadLength : bottomPadLength;
23503
+ const length26 = isUpperRow ? topPadLength : bottomPadLength;
22454
23504
  return {
22455
23505
  index,
22456
23506
  x: contactStartX + index * pitch,
22457
23507
  y,
22458
- length: length20
23508
+ length: length26
22459
23509
  };
22460
23510
  });
22461
23511
  const contactMaxY = Math.max(
@@ -23007,7 +24057,7 @@ var Led2835 = ({
23007
24057
  };
23008
24058
 
23009
24059
  // lib/RJ45.tsx
23010
- var range2 = (length20) => Array.from({ length: length20 }, (_, index) => index);
24060
+ var range2 = (length26) => Array.from({ length: length26 }, (_, index) => index);
23011
24061
  var RJ45 = ({
23012
24062
  bodyWidth = 16.26,
23013
24063
  bodyDepth = 15.88,
@@ -23827,10 +24877,10 @@ var SOT143 = ({ footprint = "sot143" }) => {
23827
24877
  var Footprinter3d = ({ footprint }) => {
23828
24878
  const modelFn = mp.string(footprint.split("_", 1)[0]).params().fn;
23829
24879
  if (mp.getModelNames().includes(modelFn)) {
23830
- const model76 = mp.string(footprint).json();
23831
- const renderer = modelRendererRegistry.get(model76.fn);
24880
+ const model88 = mp.string(footprint).json();
24881
+ const renderer = modelRendererRegistry.get(model88.fn);
23832
24882
  if (renderer) {
23833
- return renderer.render(model76);
24883
+ return renderer.render(model88);
23834
24884
  }
23835
24885
  }
23836
24886
  let normalizedFootprint = footprint;
@@ -24514,7 +25564,7 @@ var toVec3 = (v) => {
24514
25564
  };
24515
25565
  function renderNode(node, colorCtx, renderCtx) {
24516
25566
  const {
24517
- jscad: { primitives, booleans, hulls, geometries, extrusions, transforms }
25567
+ jscad: { primitives: primitives7, booleans: booleans3, hulls, geometries: geometries7, extrusions: extrusions7, transforms }
24518
25568
  } = renderCtx;
24519
25569
  if (node == null || node === false) return [];
24520
25570
  if (Array.isArray(node))
@@ -24579,9 +25629,9 @@ function renderNode(node, colorCtx, renderCtx) {
24579
25629
  const geoms = entries.map((g) => g.geom);
24580
25630
  if (geoms.length === 0) return [];
24581
25631
  let geom;
24582
- if (type === Union) geom = booleans.union(geoms);
25632
+ if (type === Union) geom = booleans3.union(geoms);
24583
25633
  else if (type === Subtract)
24584
- geom = booleans.subtract(geoms[0], geoms.slice(1));
25634
+ geom = booleans3.subtract(geoms[0], geoms.slice(1));
24585
25635
  else geom = hulls.hull(geoms);
24586
25636
  return [
24587
25637
  {
@@ -24596,7 +25646,7 @@ function renderNode(node, colorCtx, renderCtx) {
24596
25646
  }
24597
25647
  if (type === Polygon) {
24598
25648
  const points = props?.points ?? [];
24599
- const g2 = geometries.geom2.fromPoints(points);
25649
+ const g2 = geometries7.geom2.fromPoints(points);
24600
25650
  return [{ geom: g2, color: colorCtx ?? props?.color }];
24601
25651
  }
24602
25652
  if (type === ExtrudeLinear) {
@@ -24605,9 +25655,9 @@ function renderNode(node, colorCtx, renderCtx) {
24605
25655
  );
24606
25656
  const geoms2 = entries.map((g) => g.geom);
24607
25657
  if (geoms2.length === 0) return [];
24608
- const base2 = geoms2.length > 1 ? booleans.union(geoms2) : geoms2[0];
25658
+ const base2 = geoms2.length > 1 ? booleans3.union(geoms2) : geoms2[0];
24609
25659
  const height10 = props?.height ?? props?.h ?? 1;
24610
- let g3 = extrusions.extrudeLinear({ height: height10 }, base2);
25660
+ let g3 = extrusions7.extrudeLinear({ height: height10 }, base2);
24611
25661
  if (g3.polygons) {
24612
25662
  for (const poly of g3.polygons) {
24613
25663
  if (!poly.plane || !poly.vertices || poly.vertices.length < 3) continue;
@@ -24628,32 +25678,32 @@ function renderNode(node, colorCtx, renderCtx) {
24628
25678
  const size = props?.size ?? [1, 1, 1];
24629
25679
  const offset = props?.offset;
24630
25680
  const center = props?.center ?? (offset ? [offset[0], offset[1], offset[2]] : [0, 0, 0]);
24631
- g = primitives.cuboid({ size, center });
25681
+ g = primitives7.cuboid({ size, center });
24632
25682
  } else if (type === Cube) {
24633
25683
  const size = props?.size ?? 1;
24634
25684
  const offset = props?.offset;
24635
25685
  const center = props?.center ?? (offset ? [offset[0], offset[1], offset[2]] : [0, 0, 0]);
24636
- g = primitives.cube({ size, center });
25686
+ g = primitives7.cube({ size, center });
24637
25687
  } else if (type === Cylinder) {
24638
25688
  const height10 = props?.height ?? 1;
24639
25689
  const radius = props?.radius ?? 1;
24640
25690
  const center = props?.center ?? [0, 0, 0];
24641
- g = primitives.cylinder({ height: height10, radius, center });
25691
+ g = primitives7.cylinder({ height: height10, radius, center });
24642
25692
  } else if (type === Sphere) {
24643
25693
  const radius = props?.radius ?? 1;
24644
25694
  const center = props?.center ?? [0, 0, 0];
24645
- g = primitives.sphere({ radius, center });
25695
+ g = primitives7.sphere({ radius, center });
24646
25696
  } else if (type === RoundedCylinder) {
24647
25697
  const height10 = props?.height ?? 1;
24648
25698
  const radius = props?.radius ?? 1;
24649
25699
  const roundRadius = props?.roundRadius ?? 0.1;
24650
25700
  const center = props?.center ?? [0, 0, 0];
24651
- g = primitives.roundedCylinder({ height: height10, radius, roundRadius, center });
25701
+ g = primitives7.roundedCylinder({ height: height10, radius, roundRadius, center });
24652
25702
  } else {
24653
25703
  const size = props?.size ?? [1, 1, 1];
24654
25704
  const roundRadius = props?.roundRadius ?? 0.1;
24655
25705
  const center = props?.center ?? [0, 0, 0];
24656
- g = primitives.roundedCuboid({ size, roundRadius, center });
25706
+ g = primitives7.roundedCuboid({ size, roundRadius, center });
24657
25707
  }
24658
25708
  return [{ geom: g, color: colorCtx ?? props?.color }];
24659
25709
  }
@@ -24663,10 +25713,10 @@ function renderNode(node, colorCtx, renderCtx) {
24663
25713
  }
24664
25714
  return (children ?? []).flatMap((c) => renderNode(c, colorCtx, renderCtx));
24665
25715
  }
24666
- function render(root, jscad8) {
24667
- const geometries = renderNode(root, void 0, { jscad: jscad8 });
25716
+ function render(root, jscad14) {
25717
+ const geometries7 = renderNode(root, void 0, { jscad: jscad14 });
24668
25718
  return {
24669
- geometries: geometries.map(
25719
+ geometries: geometries7.map(
24670
25720
  (entry) => entry.material ? { ...entry, geom: { ...entry.geom, material: entry.material } } : entry
24671
25721
  )
24672
25722
  };
@@ -24684,8 +25734,8 @@ function convertCSGToThreeGeom(csg) {
24684
25734
  const indices = [];
24685
25735
  const colors = [];
24686
25736
  let idx = 0;
24687
- for (const polygon of csg.polygons) {
24688
- for (const vertex of polygon.vertices) {
25737
+ for (const polygon4 of csg.polygons) {
25738
+ for (const vertex of polygon4.vertices) {
24689
25739
  vertex.index = idx;
24690
25740
  vertices.push(vertex[0], vertex[1], vertex[2]);
24691
25741
  if (csg.color && csg.color.length >= 3) {
@@ -24695,10 +25745,10 @@ function convertCSGToThreeGeom(csg) {
24695
25745
  }
24696
25746
  idx++;
24697
25747
  }
24698
- const first = polygon.vertices[0].index;
24699
- for (let i = 2; i < polygon.vertices.length; i++) {
24700
- const second = polygon.vertices[i - 1].index;
24701
- const third = polygon.vertices[i].index;
25748
+ const first = polygon4.vertices[0].index;
25749
+ for (let i = 2; i < polygon4.vertices.length; i++) {
25750
+ const second = polygon4.vertices[i - 1].index;
25751
+ const third = polygon4.vertices[i].index;
24702
25752
  indices.push(first, second, third);
24703
25753
  }
24704
25754
  }
@@ -24756,35 +25806,37 @@ function convertCSGToThreeGeom(csg) {
24756
25806
  }
24757
25807
 
24758
25808
  // lib/vanilla/index.ts
24759
- function getJscadModelForFootprint(footprint, jscad8) {
25809
+ function getJscadModelForFootprint(footprint, jscad14) {
24760
25810
  const vnode = h(Footprinter3d, { footprint });
24761
- return render(vnode, jscad8);
25811
+ return render(vnode, jscad14);
24762
25812
  }
24763
- function getJscadModelForFootprintWithPads(footprint, jscad8) {
25813
+ function getJscadModelForFootprintWithPads(footprint, jscad14) {
24764
25814
  const vnode = h(
24765
25815
  Fragment,
24766
25816
  {},
24767
25817
  h(Footprinter3d, { footprint }),
24768
25818
  h(ExtrudedPads, { footprint })
24769
25819
  );
24770
- return render(vnode, jscad8);
25820
+ return render(vnode, jscad14);
24771
25821
  }
24772
- function createJSCADRenderer(jscad8) {
25822
+ function createJSCADRenderer(jscad14) {
24773
25823
  function createJSCADRoot(container) {
24774
25824
  return {
24775
25825
  render(element) {
24776
- const { geometries } = render(element, jscad8);
24777
- container.splice(0, container.length, ...geometries);
25826
+ const { geometries: geometries7 } = render(element, jscad14);
25827
+ container.splice(0, container.length, ...geometries7);
24778
25828
  }
24779
25829
  };
24780
25830
  }
24781
25831
  return { createJSCADRoot };
24782
25832
  }
24783
25833
  export {
25834
+ AngleBar,
24784
25835
  BallBearing,
24785
25836
  BallTransferUnit,
24786
25837
  ButtonScrew,
24787
25838
  CableGrommet,
25839
+ ChannelBar,
24788
25840
  ClampingShaftCollar,
24789
25841
  CompressionSpring,
24790
25842
  DowelPin,
@@ -24807,7 +25859,11 @@ export {
24807
25859
  NemaMotor,
24808
25860
  NylonLockNut,
24809
25861
  PanScrew,
25862
+ PerforatedSheet,
24810
25863
  PlainBushing,
25864
+ PushFitPlug,
25865
+ RectangularBar,
25866
+ RectangularTube,
24811
25867
  RigidCoupler,
24812
25868
  SetScrew,
24813
25869
  ShaftCollar,
@@ -24822,6 +25878,8 @@ export {
24822
25878
  TorsionSpring,
24823
25879
  WormGear,
24824
25880
  convertCSGToThreeGeom,
25881
+ createAngleBarGeom,
25882
+ createAngleBarMesh,
24825
25883
  createBallBearingGeom,
24826
25884
  createBallBearingMesh,
24827
25885
  createBallTransferUnitGeom,
@@ -24830,6 +25888,8 @@ export {
24830
25888
  createButtonScrewMesh,
24831
25889
  createCableGrommetGeom,
24832
25890
  createCableGrommetMesh,
25891
+ createChannelBarGeom,
25892
+ createChannelBarMesh,
24833
25893
  createClampingShaftCollarGeom,
24834
25894
  createClampingShaftCollarMesh,
24835
25895
  createCompressionSpringGeom,
@@ -24867,8 +25927,16 @@ export {
24867
25927
  createNylonLockNutMeshes,
24868
25928
  createPanScrewGeom,
24869
25929
  createPanScrewMesh,
25930
+ createPerforatedSheetGeom,
25931
+ createPerforatedSheetMesh,
24870
25932
  createPlainBushingGeom,
24871
25933
  createPlainBushingMesh,
25934
+ createPushFitPlugGeom,
25935
+ createPushFitPlugMesh,
25936
+ createRectangularBarGeom,
25937
+ createRectangularBarMesh,
25938
+ createRectangularTubeGeom,
25939
+ createRectangularTubeMesh,
24872
25940
  createRigidCouplerGeom,
24873
25941
  createRigidCouplerMesh,
24874
25942
  createSetScrewGeom,