jscad-electronics 0.0.227 → 0.0.232

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/a2cdaa0ea42c20364c601d990971fef4f4e234fc-v2/node_modules/zod/v3/external.js
27
+ // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-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/a2cdaa0ea42c20364c601d990971fef4f4e234fc-v2/node_modules/zod/v3/helpers/util.js
139
+ // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-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/a2cdaa0ea42c20364c601d990971fef4f4e234fc-v2/node_modules/zod/v3/ZodError.js
273
+ // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-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/a2cdaa0ea42c20364c601d990971fef4f4e234fc-v2/node_modules/zod/v3/locales/en.js
391
+ // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-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/a2cdaa0ea42c20364c601d990971fef4f4e234fc-v2/node_modules/zod/v3/errors.js
494
+ // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-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/a2cdaa0ea42c20364c601d990971fef4f4e234fc-v2/node_modules/zod/v3/helpers/parseUtil.js
503
+ // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-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/a2cdaa0ea42c20364c601d990971fef4f4e234fc-v2/node_modules/zod/v3/helpers/errorUtil.js
613
+ // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-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/a2cdaa0ea42c20364c601d990971fef4f4e234fc-v2/node_modules/zod/v3/types.js
620
+ // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-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 shape39 = this._def.shape();
2406
- const keys = util.objectKeys(shape39);
2407
- this._cached = { shape: shape39, keys };
2405
+ const shape44 = this._def.shape();
2406
+ const keys = util.objectKeys(shape44);
2407
+ this._cached = { shape: shape44, 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: shape39, keys: shapeKeys } = this._getCached();
2422
+ const { shape: shape44, 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 = shape39[key];
2433
+ const keyValidator = shape44[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 shape39 = {};
2639
+ const shape44 = {};
2640
2640
  for (const key of util.objectKeys(mask)) {
2641
2641
  if (mask[key] && this.shape[key]) {
2642
- shape39[key] = this.shape[key];
2642
+ shape44[key] = this.shape[key];
2643
2643
  }
2644
2644
  }
2645
2645
  return new _ZodObject({
2646
2646
  ...this._def,
2647
- shape: () => shape39
2647
+ shape: () => shape44
2648
2648
  });
2649
2649
  }
2650
2650
  omit(mask) {
2651
- const shape39 = {};
2651
+ const shape44 = {};
2652
2652
  for (const key of util.objectKeys(this.shape)) {
2653
2653
  if (!mask[key]) {
2654
- shape39[key] = this.shape[key];
2654
+ shape44[key] = this.shape[key];
2655
2655
  }
2656
2656
  }
2657
2657
  return new _ZodObject({
2658
2658
  ...this._def,
2659
- shape: () => shape39
2659
+ shape: () => shape44
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 = (shape39, params) => {
2706
+ ZodObject.create = (shape44, params) => {
2707
2707
  return new ZodObject({
2708
- shape: () => shape39,
2708
+ shape: () => shape44,
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 = (shape39, params) => {
2715
+ ZodObject.strictCreate = (shape44, params) => {
2716
2716
  return new ZodObject({
2717
- shape: () => shape39,
2717
+ shape: () => shape44,
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 = (shape39, params) => {
2724
+ ZodObject.lazycreate = (shape44, params) => {
2725
2725
  return new ZodObject({
2726
- shape: shape39,
2726
+ shape: shape44,
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/a2cdaa0ea42c20364c601d990971fef4f4e234fc-v2/node_modules/@tscircuit/mm/dist/index.js
4068
+ // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-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/a2cdaa0ea42c20364c601d990971fef4f4e234fc-v2/index.js
4095
+ // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-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");
@@ -4148,21 +4148,21 @@ var parseModelStringParams = (definition) => {
4148
4148
  params.string = normalizedDefinition;
4149
4149
  return params;
4150
4150
  };
4151
- function expandModelStringFlags(value, flags6) {
4151
+ function expandModelStringFlags(value, flags9) {
4152
4152
  return splitModelStringTokens(value).map(
4153
- (token, index) => index > 0 && Object.hasOwn(flags6, token.toLowerCase()) ? flags6[token.toLowerCase()] : token
4153
+ (token, index) => index > 0 && Object.hasOwn(flags9, token.toLowerCase()) ? flags9[token.toLowerCase()] : token
4154
4154
  ).join("_");
4155
4155
  }
4156
- function normalizeModelStringFlags(value, flags6, parse, omittedFlags) {
4156
+ function normalizeModelStringFlags(value, flags9, parse, omittedFlags) {
4157
4157
  const tokens = splitModelStringTokens(value);
4158
- if (!tokens.slice(1).some((token) => Object.hasOwn(flags6, token.toLowerCase())))
4158
+ if (!tokens.slice(1).some((token) => Object.hasOwn(flags9, token.toLowerCase())))
4159
4159
  return value;
4160
- const expanded = expandModelStringFlags(value, flags6);
4160
+ const expanded = expandModelStringFlags(value, flags9);
4161
4161
  parse(parseModelStringParams(expanded));
4162
4162
  const preferred = new Map(
4163
- Object.entries(flags6).map(([flag, selector]) => [selector, flag])
4163
+ Object.entries(flags9).map(([flag, selector]) => [selector, flag])
4164
4164
  );
4165
- const omitted = new Set(omittedFlags.map((flag) => flags6[flag]));
4165
+ const omitted = new Set(omittedFlags.map((flag) => flags9[flag]));
4166
4166
  return splitModelStringTokens(expanded).flatMap((token, index) => {
4167
4167
  if (index === 0) return [token.toLowerCase()];
4168
4168
  const lower = token.toLowerCase();
@@ -4178,55 +4178,55 @@ var stringFlags = {
4178
4178
  male: "threadgender(male)"
4179
4179
  };
4180
4180
  var omittedStringFlags = ["righthanded", "male"];
4181
- function defineModel(model452) {
4182
- return model452;
4181
+ function defineModel(model502) {
4182
+ return model502;
4183
4183
  }
4184
4184
  var ModelRegistry = class {
4185
4185
  models = /* @__PURE__ */ new Map();
4186
- register(model452) {
4187
- if (typeof model452.name !== "string" || !/^[a-z]+$/.test(model452.name)) {
4186
+ register(model502) {
4187
+ if (typeof model502.name !== "string" || !/^[a-z]+$/.test(model502.name)) {
4188
4188
  throw new Error("Model names must contain only lowercase letters");
4189
4189
  }
4190
- if (this.models.has(model452.name)) {
4190
+ if (this.models.has(model502.name)) {
4191
4191
  throw new Error(
4192
- `Modelprinter function "${model452.name}" is already registered`
4192
+ `Modelprinter function "${model502.name}" is already registered`
4193
4193
  );
4194
4194
  }
4195
- if (model452.normalizeString !== void 0 && typeof model452.normalizeString !== "function")
4195
+ if (model502.normalizeString !== void 0 && typeof model502.normalizeString !== "function")
4196
4196
  throw new Error("Model string normalizer must be a function");
4197
- this.models.set(model452.name, {
4198
- name: model452.name,
4199
- schema: model452.schema,
4200
- parse: model452.parse,
4201
- normalizeString: model452.normalizeString
4197
+ this.models.set(model502.name, {
4198
+ name: model502.name,
4199
+ schema: model502.schema,
4200
+ parse: model502.parse,
4201
+ normalizeString: model502.normalizeString
4202
4202
  });
4203
4203
  }
4204
4204
  getModelNames() {
4205
4205
  return [...this.models.keys()];
4206
4206
  }
4207
4207
  normalize(params) {
4208
- const model452 = this.models.get(params.fn);
4209
- if (!model452?.normalizeString) return params;
4210
- const value = model452.normalizeString(params.string);
4208
+ const model502 = this.models.get(params.fn);
4209
+ if (!model502?.normalizeString) return params;
4210
+ const value = model502.normalizeString(params.string);
4211
4211
  if (typeof value !== "string")
4212
- throw new Error(`Normalizer for "${model452.name}" must return a string`);
4212
+ throw new Error(`Normalizer for "${model502.name}" must return a string`);
4213
4213
  if (value === params.string) return params;
4214
4214
  const normalized = parseModelStringParams(value);
4215
- if (normalized.fn !== model452.name)
4215
+ if (normalized.fn !== model502.name)
4216
4216
  throw new Error(
4217
- `Normalizer for "${model452.name}" must preserve the model name`
4217
+ `Normalizer for "${model502.name}" must preserve the model name`
4218
4218
  );
4219
4219
  return normalized;
4220
4220
  }
4221
4221
  parse(params) {
4222
- const model452 = this.models.get(params.fn);
4223
- if (!model452) {
4222
+ const model502 = this.models.get(params.fn);
4223
+ if (!model502) {
4224
4224
  throw new Error(`Unsupported modelprinter function "${params.fn}"`);
4225
4225
  }
4226
- const definition = model452.parse(params);
4227
- if (definition === null || typeof definition !== "object" || Array.isArray(definition) || definition.fn !== model452.name) {
4226
+ const definition = model502.parse(params);
4227
+ if (definition === null || typeof definition !== "object" || Array.isArray(definition) || definition.fn !== model502.name) {
4228
4228
  throw new Error(
4229
- `Parser for "${model452.name}" must return a model with fn "${model452.name}"`
4229
+ `Parser for "${model502.name}" must return a model with fn "${model502.name}"`
4230
4230
  );
4231
4231
  }
4232
4232
  return definition;
@@ -5155,12 +5155,12 @@ function parseSheetMetalFeature(feature, profile6) {
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 length26 = distance2("l"), width10 = distance2("w");
5159
- if (length26 < width10) throw new Error("Slot length must be at least its width");
5158
+ const length29 = distance2("l"), width10 = distance2("w");
5159
+ if (length29 < 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: length26,
5163
+ length: length29,
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((model452, context) => {
5367
- validateTailLengths(model452, context);
5368
- addOrientationShortcutIssue(model452, (path) => {
5366
+ }).strict().superRefine((model502, context) => {
5367
+ validateTailLengths(model502, context);
5368
+ addOrientationShortcutIssue(model502, (path) => {
5369
5369
  context.addIssue({
5370
5370
  code: "custom",
5371
5371
  message: "Only one FlexScreen orientation shortcut can be true",
@@ -6475,12 +6475,12 @@ function parseButtonScrewModelParams(raw) {
6475
6475
  if (raw.fn !== "buttonscrew" || tokens[0]?.toLowerCase() !== "buttonscrew")
6476
6476
  throw new Error("Expected buttonscrew without an inline argument");
6477
6477
  const props = { fn: "buttonscrew" };
6478
- const lengths22 = {
6478
+ const lengths24 = {
6479
6479
  l: "length",
6480
6480
  length: "length",
6481
6481
  threadpitch: "threadPitch"
6482
6482
  };
6483
- const selectors4 = {
6483
+ const selectors6 = {
6484
6484
  drive: "drive",
6485
6485
  thread: "thread",
6486
6486
  threadhand: "threadHand",
@@ -6502,9 +6502,9 @@ function parseButtonScrewModelParams(raw) {
6502
6502
  if (name === "m") {
6503
6503
  property = "metricSize";
6504
6504
  parsed = `M${value}`;
6505
- } else if (name in lengths22) property = lengths22[name];
6506
- else if (name in selectors4) {
6507
- property = selectors4[name];
6505
+ } else if (name in lengths24) property = lengths24[name];
6506
+ else if (name in selectors6) {
6507
+ property = selectors6[name];
6508
6508
  if (!/^\([^()]+\)$/.test(value))
6509
6509
  throw new Error(`Expected a parenthesized ${name}`);
6510
6510
  parsed = value.slice(1, -1).toLowerCase();
@@ -6994,8 +6994,8 @@ function getCompressionSpringCenterlinePoint(input, turn) {
6994
6994
  const radius = (props.outerDiameter - props.wireDiameter) / 2;
6995
6995
  const pitch = (props.freeLength - 2 * props.wireDiameter) / props.activeTurns;
6996
6996
  const phase = (props.hand === "right" ? 1 : -1) * 2 * Math.PI * (turn % 1);
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 };
6997
+ const z54 = 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: z54 };
6999
6999
  }
7000
7000
  function parseCompressionSpringModelParams(raw) {
7001
7001
  const tokens = splitModelStringTokens(
@@ -7004,14 +7004,14 @@ function parseCompressionSpringModelParams(raw) {
7004
7004
  if (raw.fn !== "compressionspring" || tokens[0]?.toLowerCase() !== "compressionspring")
7005
7005
  throw new Error("Expected compressionspring without an inline argument");
7006
7006
  const props = { fn: "compressionspring" };
7007
- const lengths22 = {
7007
+ const lengths24 = {
7008
7008
  od: "outerDiameter",
7009
7009
  wire: "wireDiameter",
7010
7010
  l: "freeLength",
7011
7011
  length: "freeLength",
7012
7012
  freelength: "freeLength"
7013
7013
  };
7014
- const selectors4 = {
7014
+ const selectors6 = {
7015
7015
  spec: "spec",
7016
7016
  ends: "ends",
7017
7017
  hand: "hand",
@@ -7024,14 +7024,14 @@ function parseCompressionSpringModelParams(raw) {
7024
7024
  const value = match[2];
7025
7025
  let property;
7026
7026
  let parsed = value;
7027
- if (name in lengths22) property = lengths22[name];
7027
+ if (name in lengths24) property = lengths24[name];
7028
7028
  else if (name === "turns" || name === "active") {
7029
7029
  property = name === "turns" ? "totalTurns" : "activeTurns";
7030
7030
  if (!/^\d+$/.test(value))
7031
7031
  throw new Error(`${name} requires a unitless integer`);
7032
7032
  parsed = Number(value);
7033
- } else if (name in selectors4) {
7034
- property = selectors4[name];
7033
+ } else if (name in selectors6) {
7034
+ property = selectors6[name];
7035
7035
  if (!/^\([^()]+\)$/.test(value))
7036
7036
  throw new Error(`Expected a parenthesized ${name}`);
7037
7037
  parsed = value.slice(1, -1).toLowerCase();
@@ -8540,11 +8540,11 @@ function validate19(props, context) {
8540
8540
  const issue = (path, message) => context.addIssue({ code: "custom", path: [path], message });
8541
8541
  if (!!props.metricSize === !!props.imperialSize)
8542
8542
  issue("metricSize", "Select exactly one metric or imperial size");
8543
- const flags6 = ["iso4032", "din934", "asmeb1822"];
8543
+ const flags9 = ["iso4032", "din934", "asmeb1822"];
8544
8544
  const family = selectedFamily(props);
8545
- if (flags6.filter((flag) => props[flag] === true).length > 1)
8545
+ if (flags9.filter((flag) => props[flag] === true).length > 1)
8546
8546
  issue("iso4032", "Select only one ISO, DIN or ASME family");
8547
- for (const flag of flags6)
8547
+ for (const flag of flags9)
8548
8548
  if (family[flag] && props[flag] === false)
8549
8549
  issue(
8550
8550
  flag,
@@ -8598,7 +8598,7 @@ function parseHexNutModelParams(raw) {
8598
8598
  if (raw.fn !== "hexnut" || tokens[0]?.toLowerCase() !== "hexnut")
8599
8599
  throw new Error("Expected hexnut without an inline argument");
8600
8600
  const props = { fn: "hexnut" };
8601
- const selectors4 = {
8601
+ const selectors6 = {
8602
8602
  threadhand: "threadHand",
8603
8603
  threadclass: "threadClass"
8604
8604
  };
@@ -8637,8 +8637,8 @@ function parseHexNutModelParams(raw) {
8637
8637
  props.threadPitch = 25.4 / Number(parts[1]);
8638
8638
  }
8639
8639
  } else if (name === "threadpitch") property = "threadPitch";
8640
- else if (name in selectors4) {
8641
- property = selectors4[name];
8640
+ else if (name in selectors6) {
8641
+ property = selectors6[name];
8642
8642
  if (!/^\([^()]+\)$/.test(value))
8643
8643
  throw new Error(`Expected a parenthesized ${name}`);
8644
8644
  parsed = value.slice(1, -1).toLowerCase();
@@ -9774,7 +9774,10 @@ function register33(registry2) {
9774
9774
  }
9775
9775
  var length19 = external_exports.union([
9776
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())
9777
+ external_exports.string().regex(
9778
+ /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i,
9779
+ "Expected a complete numeric length with an optional unit"
9780
+ ).transform((value) => value.toLowerCase())
9778
9781
  ]).pipe(modelLengthSchema);
9779
9782
  var positiveLength14 = length19.refine(
9780
9783
  (value) => value > 0,
@@ -9787,12 +9790,120 @@ var nonnegativeLength6 = length19.refine(
9787
9790
  var shape28 = {
9788
9791
  width: positiveLength14,
9789
9792
  height: positiveLength14,
9790
- wallThickness: positiveLength14,
9791
- length: positiveLength14,
9792
- outerRadius: nonnegativeLength6.default(0),
9793
- innerRadius: nonnegativeLength6.default(0)
9793
+ border: positiveLength14,
9794
+ thickness: positiveLength14,
9795
+ cornerRadius: nonnegativeLength6.default(0),
9796
+ flatFrame: external_exports.literal(true).default(true)
9794
9797
  };
9795
9798
  function validate27(p, context) {
9799
+ const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
9800
+ if (2 * p.border >= Math.min(p.width, p.height))
9801
+ issue(
9802
+ "The border must leave a positive-width and positive-height opening",
9803
+ "border"
9804
+ );
9805
+ if (2 * p.cornerRadius >= Math.min(p.width, p.height))
9806
+ issue(
9807
+ "Outside corner radius must be smaller than half the short side",
9808
+ "cornerRadius"
9809
+ );
9810
+ if (!Number.isFinite(
9811
+ 8 * Math.max(p.width, p.height, p.border, p.thickness, p.cornerRadius) ** 3
9812
+ ))
9813
+ issue("Dimensions exceed finite derived geometry limits", "width");
9814
+ }
9815
+ var rectangularGasketModelPropsSchema = external_exports.object(shape28).strict().superRefine(validate27);
9816
+ var rectangularGasketModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rectangulargasket"), ...shape28 }).strict().superRefine(validate27);
9817
+ function getRectangularGasketDimensions(input) {
9818
+ const p = rectangularGasketModelPropsSchema.parse(input);
9819
+ return {
9820
+ ...p,
9821
+ size: [p.width, p.height, p.thickness],
9822
+ bottomZ: 0,
9823
+ topZ: p.thickness,
9824
+ innerWidth: p.width - 2 * p.border,
9825
+ innerHeight: p.height - 2 * p.border,
9826
+ innerCornerRadius: Math.max(0, p.cornerRadius - p.border),
9827
+ nominalVolume: (p.width * p.height - (4 - Math.PI) * p.cornerRadius ** 2 - ((p.width - 2 * p.border) * (p.height - 2 * p.border) - (4 - Math.PI) * Math.max(0, p.cornerRadius - p.border) ** 2)) * p.thickness
9828
+ };
9829
+ }
9830
+ var lengths16 = {
9831
+ w: "width",
9832
+ h: "height",
9833
+ border: "border",
9834
+ t: "thickness",
9835
+ cornerr: "cornerRadius",
9836
+ width: "width",
9837
+ height: "height",
9838
+ thickness: "thickness",
9839
+ cornerradius: "cornerRadius"
9840
+ };
9841
+ var flags5 = { flatframe: "flatFrame" };
9842
+ var selectors4 = {
9843
+ profile: { value: "flatframe", property: "flatFrame" }
9844
+ };
9845
+ var integers = {};
9846
+ var tuples = {};
9847
+ function parseRectangularGasketModelParams(raw) {
9848
+ const [name, ...tokens] = splitModelStringTokens(raw.string);
9849
+ if (raw.fn !== "rectangulargasket" || name?.toLowerCase() !== "rectangulargasket")
9850
+ throw new Error("Expected rectangulargasket without inline values");
9851
+ const props = { fn: "rectangulargasket" };
9852
+ const assign = (property, value) => {
9853
+ if (Object.hasOwn(props, property))
9854
+ throw new Error(`Duplicate rectangulargasket property "${property}"`);
9855
+ props[property] = value;
9856
+ };
9857
+ for (const token of tokens) {
9858
+ const match = token.match(/^([a-z]+)(.*)$/i);
9859
+ if (!match) throw new Error(`Malformed rectangulargasket token "${token}"`);
9860
+ const key = match[1].toLowerCase(), value = match[2];
9861
+ if (Object.hasOwn(lengths16, key) && value) assign(lengths16[key], value);
9862
+ else if (Object.hasOwn(flags5, key) && !value) assign(flags5[key], true);
9863
+ else if (Object.hasOwn(selectors4, key) && value.toLowerCase() === `(${selectors4[key].value})`)
9864
+ assign(selectors4[key].property, true);
9865
+ else if (Object.hasOwn(integers, key) && /^\d+$/.test(value))
9866
+ assign(integers[key], Number(value));
9867
+ else if (Object.hasOwn(tuples, key)) {
9868
+ const pair = value.match(/^\(([^(),]+),([^(),]+)\)$/);
9869
+ if (!pair)
9870
+ throw new Error(`Token "${key}" requires two parenthesized lengths`);
9871
+ assign(tuples[key][0], pair[1].trim());
9872
+ assign(tuples[key][1], pair[2].trim());
9873
+ } else
9874
+ throw new Error(`Unknown or malformed rectangulargasket token "${token}"`);
9875
+ }
9876
+ return rectangularGasketModelDefinitionSchema.parse(props);
9877
+ }
9878
+ var model34 = defineModel({
9879
+ name: "rectangulargasket",
9880
+ schema: rectangularGasketModelDefinitionSchema,
9881
+ parse: parseRectangularGasketModelParams
9882
+ });
9883
+ function register34(registry2) {
9884
+ registry2.register(model34);
9885
+ }
9886
+ var length20 = external_exports.union([
9887
+ external_exports.number(),
9888
+ external_exports.string().regex(/^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
9889
+ ]).pipe(modelLengthSchema);
9890
+ var positiveLength15 = length20.refine(
9891
+ (value) => value > 0,
9892
+ "Length must be positive"
9893
+ );
9894
+ var nonnegativeLength7 = length20.refine(
9895
+ (value) => value >= 0,
9896
+ "Length cannot be negative"
9897
+ );
9898
+ var shape29 = {
9899
+ width: positiveLength15,
9900
+ height: positiveLength15,
9901
+ wallThickness: positiveLength15,
9902
+ length: positiveLength15,
9903
+ outerRadius: nonnegativeLength7.default(0),
9904
+ innerRadius: nonnegativeLength7.default(0)
9905
+ };
9906
+ function validate28(p, context) {
9796
9907
  if (2 * p.wallThickness >= Math.min(p.width, p.height))
9797
9908
  context.addIssue({
9798
9909
  code: "custom",
@@ -9814,8 +9925,8 @@ function validate27(p, context) {
9814
9925
  message: "Invalid rectangulartube dimensions: constraint 4"
9815
9926
  });
9816
9927
  }
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);
9928
+ var rectangularTubeModelPropsSchema = external_exports.object(shape29).strict().superRefine(validate28);
9929
+ var rectangularTubeModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rectangulartube"), ...shape29 }).strict().superRefine(validate28);
9819
9930
  var aliases11 = {
9820
9931
  w: "width",
9821
9932
  h: "height",
@@ -9848,13 +9959,13 @@ function parseRectangularTubeModelParams(raw) {
9848
9959
  }
9849
9960
  return rectangularTubeModelDefinitionSchema.parse(props);
9850
9961
  }
9851
- var model34 = defineModel({
9962
+ var model35 = defineModel({
9852
9963
  name: "rectangulartube",
9853
9964
  schema: rectangularTubeModelDefinitionSchema,
9854
9965
  parse: parseRectangularTubeModelParams
9855
9966
  });
9856
- function register34(registry2) {
9857
- registry2.register(model34);
9967
+ function register35(registry2) {
9968
+ registry2.register(model35);
9858
9969
  }
9859
9970
  var stringFlags11 = {
9860
9971
  setscrew: "mount(setscrew)",
@@ -9862,19 +9973,19 @@ var stringFlags11 = {
9862
9973
  righthanded: "threadhand(right)"
9863
9974
  };
9864
9975
  var omittedStringFlags11 = ["righthanded"];
9865
- var length20 = external_exports.union([
9976
+ var length21 = external_exports.union([
9866
9977
  external_exports.number().finite(),
9867
9978
  external_exports.string().regex(
9868
9979
  /^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i,
9869
9980
  "Expected a complete length with a supported unit"
9870
9981
  ).transform((value) => value.toLowerCase())
9871
9982
  ]).pipe(modelLengthSchema);
9872
- var positive5 = length20.refine((value) => value > 0, "Length must be positive");
9873
- var nonnegative4 = length20.refine(
9983
+ var positive5 = length21.refine((value) => value > 0, "Length must be positive");
9984
+ var nonnegative4 = length21.refine(
9874
9985
  (value) => value >= 0,
9875
9986
  "Length cannot be negative"
9876
9987
  );
9877
- var shape29 = {
9988
+ var shape30 = {
9878
9989
  boreDiameter: positive5,
9879
9990
  outerDiameter: positive5,
9880
9991
  boreBDiameter: positive5.optional(),
@@ -9899,7 +10010,7 @@ function resolve6(props) {
9899
10010
  screwAngle: (props.screwAngle % 360 + 360) % 360
9900
10011
  };
9901
10012
  }
9902
- function validate28(props, context) {
10013
+ function validate29(props, context) {
9903
10014
  const p = resolve6(props);
9904
10015
  const issue = (message) => context.addIssue({ code: "custom", message });
9905
10016
  const diameter = hexSocketBoltDimensions[p.metricSize].diameter;
@@ -9923,8 +10034,8 @@ function validate28(props, context) {
9923
10034
  if (p.length - 2 * p.screwEndOffset <= diameter)
9924
10035
  issue("Each end must have a separate, nonintersecting screw-hole plane");
9925
10036
  }
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) }));
10037
+ var rigidCouplerModelPropsSchema = external_exports.object(shape30).strict().superRefine(validate29).transform(resolve6);
10038
+ var rigidCouplerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rigidcoupler"), ...shape30 }).strict().superRefine(validate29).transform((props) => ({ fn: props.fn, ...resolve6(props) }));
9928
10039
  function getRigidCouplerDimensions(input) {
9929
10040
  const p = rigidCouplerModelPropsSchema.parse(input);
9930
10041
  const threadDiameter = hexSocketBoltDimensions[p.metricSize].diameter;
@@ -10024,7 +10135,7 @@ function parseRigidCouplerModelParams(raw) {
10024
10135
  ...props
10025
10136
  });
10026
10137
  }
10027
- var model35 = defineModel({
10138
+ var model36 = defineModel({
10028
10139
  name: "rigidcoupler",
10029
10140
  schema: rigidCouplerModelDefinitionSchema,
10030
10141
  parse: parseRigidCouplerModelParams,
@@ -10035,10 +10146,10 @@ var model35 = defineModel({
10035
10146
  omittedStringFlags11
10036
10147
  )
10037
10148
  });
10038
- function register35(registry2) {
10039
- registry2.register(model35);
10149
+ function register36(registry2) {
10150
+ registry2.register(model36);
10040
10151
  }
10041
- var positiveLength15 = external_exports.union([
10152
+ var positiveLength16 = external_exports.union([
10042
10153
  external_exports.number(),
10043
10154
  external_exports.string().regex(/^(?:\d+(?:\.\d+)?|\.\d+)(?:mm|cm|m|in|inch)?$/i).transform((value) => value.toLowerCase())
10044
10155
  ]).pipe(modelLengthSchema).refine((value) => value > 0, "Length must be positive");
@@ -10093,26 +10204,26 @@ var setscrewDimensions = {
10093
10204
  }
10094
10205
  };
10095
10206
  var setscrewMetricSizeSchema = external_exports.enum(["M3", "M4", "M5", "M6"]);
10096
- var shape30 = {
10207
+ var shape31 = {
10097
10208
  iso4029: external_exports.literal(true).default(true),
10098
10209
  metricSize: setscrewMetricSizeSchema,
10099
- length: positiveLength15,
10210
+ length: positiveLength16,
10100
10211
  hexSocket: external_exports.literal(true).default(true),
10101
10212
  cupPoint: external_exports.literal(true).default(true),
10102
10213
  leftHand: external_exports.boolean().default(false),
10103
10214
  showThreads: external_exports.boolean().default(true),
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) => {
10215
+ diameter: positiveLength16.optional(),
10216
+ threadPitch: positiveLength16.optional(),
10217
+ socketAcrossFlats: positiveLength16.optional(),
10218
+ socketDepth: positiveLength16.optional(),
10219
+ cupDiameter: positiveLength16.optional(),
10220
+ cupDepth: positiveLength16.optional(),
10221
+ pointTaperLength: positiveLength16.optional(),
10222
+ mouthChamfer: positiveLength16.optional(),
10223
+ threadRootDiameter: positiveLength16.optional(),
10224
+ threadPitchDiameter: positiveLength16.optional()
10225
+ };
10226
+ var validate30 = (props, context) => {
10116
10227
  const dimensions5 = setscrewDimensions[props.metricSize];
10117
10228
  for (const key of Object.keys(dimensions5)) {
10118
10229
  if (props[key] !== void 0 && Math.abs(props[key] - dimensions5[key]) > 1e-9)
@@ -10129,8 +10240,8 @@ var validate29 = (props, context) => {
10129
10240
  message: "Length must leave material between fixed end features"
10130
10241
  });
10131
10242
  };
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] }));
10243
+ var setscrewModelPropsSchema = external_exports.object(shape31).strict().superRefine(validate30).transform((props) => ({ ...props, ...setscrewDimensions[props.metricSize] }));
10244
+ var setscrewModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("setscrew"), ...shape31 }).strict().superRefine(validate30).transform((props) => ({ ...props, ...setscrewDimensions[props.metricSize] }));
10134
10245
  var aliases12 = {
10135
10246
  m: "metricSize",
10136
10247
  metricsize: "metricSize",
@@ -10149,7 +10260,7 @@ var aliases12 = {
10149
10260
  threadrootdiameter: "threadRootDiameter",
10150
10261
  threadpitchdiameter: "threadPitchDiameter"
10151
10262
  };
10152
- var flags5 = {
10263
+ var flags6 = {
10153
10264
  hexsocket: "hexSocket",
10154
10265
  cuppoint: "cupPoint",
10155
10266
  lefthanded: "leftHand",
@@ -10175,9 +10286,9 @@ function parseSetScrewModelParams(raw) {
10175
10286
  const value = match?.[2] ?? "";
10176
10287
  let property;
10177
10288
  let parsed;
10178
- if (flags5[key]) {
10289
+ if (flags6[key]) {
10179
10290
  if (value) throw new Error(`Flag ${key} does not accept a value`);
10180
- property = flags5[key];
10291
+ property = flags6[key];
10181
10292
  parsed = !["righthanded", "nothreads"].includes(key);
10182
10293
  } else {
10183
10294
  property = aliases12[key] ?? "";
@@ -10203,13 +10314,13 @@ function parseSetScrewModelParams(raw) {
10203
10314
  }
10204
10315
  return setscrewModelDefinitionSchema.parse({ fn: "setscrew", ...props });
10205
10316
  }
10206
- var model36 = defineModel({
10317
+ var model37 = defineModel({
10207
10318
  name: "setscrew",
10208
10319
  schema: setscrewModelDefinitionSchema,
10209
10320
  parse: parseSetScrewModelParams
10210
10321
  });
10211
- function register36(registry2) {
10212
- registry2.register(model36);
10322
+ function register37(registry2) {
10323
+ registry2.register(model37);
10213
10324
  }
10214
10325
  var stringFlags12 = {
10215
10326
  setscrew: "mount(setscrew)",
@@ -10217,19 +10328,19 @@ var stringFlags12 = {
10217
10328
  righthanded: "threadhand(right)"
10218
10329
  };
10219
10330
  var omittedStringFlags12 = ["righthanded"];
10220
- var length21 = external_exports.union([
10331
+ var length22 = external_exports.union([
10221
10332
  external_exports.number().finite(),
10222
10333
  external_exports.string().regex(
10223
10334
  /^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i,
10224
10335
  "Expected a complete length with a supported unit"
10225
10336
  ).transform((value) => value.toLowerCase())
10226
10337
  ]).pipe(modelLengthSchema);
10227
- var positive6 = length21.refine((value) => value > 0, "Length must be positive");
10228
- var nonnegative5 = length21.refine(
10338
+ var positive6 = length22.refine((value) => value > 0, "Length must be positive");
10339
+ var nonnegative5 = length22.refine(
10229
10340
  (value) => value >= 0,
10230
10341
  "Length cannot be negative"
10231
10342
  );
10232
- var shape31 = {
10343
+ var shape32 = {
10233
10344
  boreDiameter: positive6,
10234
10345
  outerDiameter: positive6,
10235
10346
  width: positive6,
@@ -10251,7 +10362,7 @@ function resolve7(props) {
10251
10362
  screwAngle: (props.screwAngle % 360 + 360) % 360
10252
10363
  };
10253
10364
  }
10254
- function validate30(props, context) {
10365
+ function validate31(props, context) {
10255
10366
  const p = resolve7(props);
10256
10367
  const issue = (message) => context.addIssue({ code: "custom", message });
10257
10368
  const diameter = hexSocketBoltDimensions[p.metricSize].diameter;
@@ -10268,8 +10379,8 @@ function validate30(props, context) {
10268
10379
  if (p.screwZ - diameter / 2 <= p.chamfer || p.screwZ + diameter / 2 >= p.width - p.chamfer)
10269
10380
  issue("Screw hole must clear both end faces and chamfers");
10270
10381
  }
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) }));
10382
+ var shaftCollarModelPropsSchema = external_exports.object(shape32).strict().superRefine(validate31).transform(resolve7);
10383
+ var shaftCollarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("shaftcollar"), ...shape32 }).strict().superRefine(validate31).transform((props) => ({ fn: props.fn, ...resolve7(props) }));
10273
10384
  function getShaftCollarDimensions(input) {
10274
10385
  const p = shaftCollarModelPropsSchema.parse(input);
10275
10386
  const threadDiameter = hexSocketBoltDimensions[p.metricSize].diameter;
@@ -10343,7 +10454,7 @@ function parseShaftCollarModelParams(raw) {
10343
10454
  }
10344
10455
  return shaftCollarModelDefinitionSchema.parse({ fn: "shaftcollar", ...props });
10345
10456
  }
10346
- var model37 = defineModel({
10457
+ var model38 = defineModel({
10347
10458
  name: "shaftcollar",
10348
10459
  schema: shaftCollarModelDefinitionSchema,
10349
10460
  parse: parseShaftCollarModelParams,
@@ -10354,27 +10465,118 @@ var model37 = defineModel({
10354
10465
  omittedStringFlags12
10355
10466
  )
10356
10467
  });
10357
- function register37(registry2) {
10358
- registry2.register(model37);
10468
+ function register38(registry2) {
10469
+ registry2.register(model38);
10359
10470
  }
10360
- var length22 = external_exports.union([
10471
+ var shape33 = {
10472
+ width: positiveGearLengthSchema,
10473
+ height: positiveGearLengthSchema,
10474
+ thickness: positiveGearLengthSchema,
10475
+ innerRadius: nonnegativeGearLengthSchema,
10476
+ length: positiveGearLengthSchema,
10477
+ slotCount: external_exports.number().finite().int().min(1).max(256),
10478
+ slotWidth: positiveGearLengthSchema,
10479
+ slotLength: positiveGearLengthSchema,
10480
+ pitch: positiveGearLengthSchema,
10481
+ endOffset: positiveGearLengthSchema
10482
+ };
10483
+ function validate32(p, context) {
10484
+ const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
10485
+ const largestDimension = Math.max(
10486
+ ...Object.values(p).filter(
10487
+ (value) => typeof value === "number"
10488
+ )
10489
+ );
10490
+ if (!Number.isFinite((4 * largestDimension) ** 3)) {
10491
+ issue(
10492
+ "Dimensions must permit finite derived coordinates and volume",
10493
+ "width"
10494
+ );
10495
+ return;
10496
+ }
10497
+ if (2 * (p.innerRadius + p.thickness) >= p.width)
10498
+ issue("The web must retain a straight portion between both bends", "width");
10499
+ if (p.innerRadius + p.thickness >= p.height)
10500
+ issue("Bends must leave a straight portion on both upright legs", "height");
10501
+ if (p.slotLength < p.slotWidth)
10502
+ issue("Overall slot length must be at least the slot width", "slotLength");
10503
+ if (p.slotWidth >= p.width - 2 * (p.innerRadius + p.thickness))
10504
+ issue("Slots must lie wholly within the straight web", "slotWidth");
10505
+ if (p.pitch <= p.slotLength && p.slotCount > 1)
10506
+ issue("Slot pitch must leave material between consecutive slots", "pitch");
10507
+ if (p.endOffset <= p.slotLength / 2)
10508
+ issue(
10509
+ "The first slot must leave material at the first cut end",
10510
+ "endOffset"
10511
+ );
10512
+ if (p.endOffset + (p.slotCount - 1) * p.pitch + p.slotLength / 2 >= p.length)
10513
+ issue("The last slot must leave material at the far cut end", "length");
10514
+ }
10515
+ var slottedChannelModelPropsSchema = external_exports.object(shape33).strict().superRefine(validate32);
10516
+ var slottedChannelModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("slottedchannel"), ...shape33 }).strict().superRefine(validate32);
10517
+ var aliases13 = {
10518
+ w: "width",
10519
+ h: "height",
10520
+ t: "thickness",
10521
+ innerr: "innerRadius",
10522
+ l: "length",
10523
+ slots: "slotCount",
10524
+ slotw: "slotWidth",
10525
+ slotl: "slotLength",
10526
+ pitch: "pitch",
10527
+ end: "endOffset",
10528
+ width: "width",
10529
+ height: "height",
10530
+ thickness: "thickness",
10531
+ innerradius: "innerRadius",
10532
+ length: "length",
10533
+ slotcount: "slotCount",
10534
+ slotwidth: "slotWidth",
10535
+ slotlength: "slotLength",
10536
+ endoffset: "endOffset"
10537
+ };
10538
+ function parseSlottedChannelModelParams(raw) {
10539
+ const [name, ...tokens] = splitModelStringTokens(raw.string);
10540
+ if (raw.fn !== "slottedchannel" || name?.toLowerCase() !== "slottedchannel")
10541
+ throw new Error("Expected slottedchannel without inline values");
10542
+ const props = { fn: "slottedchannel" };
10543
+ for (const token of tokens) {
10544
+ const [key, value] = parseGearToken(token);
10545
+ if (!Object.hasOwn(aliases13, key) || !value)
10546
+ throw new Error(`Unknown or malformed slottedchannel token "${token}"`);
10547
+ const property = aliases13[key];
10548
+ if (Object.hasOwn(props, property))
10549
+ throw new Error(`Repeated slottedchannel property "${property}"`);
10550
+ props[property] = ["slotCount"].includes(property) ? parseGearInteger(value, property) : value;
10551
+ }
10552
+ return slottedChannelModelDefinitionSchema.parse(props);
10553
+ }
10554
+ var model39 = defineModel({
10555
+ name: "slottedchannel",
10556
+ schema: slottedChannelModelDefinitionSchema,
10557
+ parse: parseSlottedChannelModelParams
10558
+ });
10559
+ function register39(registry2) {
10560
+ registry2.register(model39);
10561
+ }
10562
+ var length23 = external_exports.union([
10361
10563
  external_exports.number(),
10362
10564
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
10363
10565
  ]).pipe(modelLengthSchema);
10364
- var positiveLength16 = length22.refine(
10566
+ var positiveLength17 = length23.refine(
10365
10567
  (value) => value > 0,
10366
10568
  "Length must be positive"
10367
10569
  );
10368
- var shape32 = {
10369
- innerDiameter: positiveLength16,
10370
- outerDiameter: positiveLength16,
10570
+ var shape34 = {
10571
+ innerDiameter: positiveLength17,
10572
+ outerDiameter: positiveLength17,
10371
10573
  /** End-plane distance, including the rim chamfers. */
10372
- length: positiveLength16,
10574
+ length: positiveLength17,
10373
10575
  round: external_exports.literal(true).default(true),
10374
10576
  /** Equal axial/radial setbacks at all four 45-degree rims. */
10375
- chamfer: length22.refine((value) => value >= 0, "Chamfer cannot be negative").default(0)
10577
+ chamfer: length23.refine((value) => value >= 0, "Chamfer cannot be negative").default(0)
10376
10578
  };
10377
- function validate31(props, context) {
10579
+ function validate33(props, context) {
10378
10580
  if (props.outerDiameter <= props.innerDiameter)
10379
10581
  context.addIssue({
10380
10582
  code: "custom",
@@ -10394,9 +10596,9 @@ function validate31(props, context) {
10394
10596
  message: "Chamfers must leave positive straight bore length"
10395
10597
  });
10396
10598
  }
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 = {
10599
+ var spacerModelPropsSchema = external_exports.object(shape34).strict().superRefine(validate33);
10600
+ var spacerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("spacer"), ...shape34 }).strict().superRefine(validate33);
10601
+ var aliases14 = {
10400
10602
  id: "innerDiameter",
10401
10603
  innerdiameter: "innerDiameter",
10402
10604
  od: "outerDiameter",
@@ -10420,8 +10622,8 @@ function parseSpacerModelParams(raw) {
10420
10622
  if (key === "round" && value === "") {
10421
10623
  property = "round";
10422
10624
  parsed = true;
10423
- } else if (key && Object.hasOwn(aliases13, key) && value) {
10424
- property = aliases13[key];
10625
+ } else if (key && Object.hasOwn(aliases14, key) && value) {
10626
+ property = aliases14[key];
10425
10627
  parsed = value;
10426
10628
  } else throw new Error(`Unknown or malformed spacer token "${token}"`);
10427
10629
  if (Object.hasOwn(props, property))
@@ -10430,34 +10632,169 @@ function parseSpacerModelParams(raw) {
10430
10632
  }
10431
10633
  return spacerModelDefinitionSchema.parse(props);
10432
10634
  }
10433
- var model38 = defineModel({
10635
+ var model40 = defineModel({
10434
10636
  name: "spacer",
10435
10637
  schema: spacerModelDefinitionSchema,
10436
10638
  parse: parseSpacerModelParams
10437
10639
  });
10438
- function register38(registry2) {
10439
- registry2.register(model38);
10640
+ function register40(registry2) {
10641
+ registry2.register(model40);
10440
10642
  }
10441
- var length23 = external_exports.union([
10643
+ var length24 = external_exports.union([
10644
+ external_exports.number(),
10645
+ external_exports.string().regex(
10646
+ /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i,
10647
+ "Expected a complete numeric length with an optional unit"
10648
+ ).transform((value) => value.toLowerCase())
10649
+ ]).pipe(modelLengthSchema);
10650
+ var positiveLength18 = length24.refine(
10651
+ (value) => value > 0,
10652
+ "Length must be positive"
10653
+ );
10654
+ var nonnegativeLength8 = length24.refine(
10655
+ (value) => value >= 0,
10656
+ "Length cannot be negative"
10657
+ );
10658
+ var shape35 = {
10659
+ panelHoleDiameter: positiveLength18,
10660
+ innerDiameter: positiveLength18,
10661
+ outerDiameter: positiveLength18,
10662
+ height: positiveLength18,
10663
+ grooveWidth: positiveLength18,
10664
+ grooveDepth: positiveLength18,
10665
+ splitWidth: positiveLength18
10666
+ };
10667
+ function validate34(p, context) {
10668
+ const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
10669
+ if (p.innerDiameter >= p.panelHoleDiameter || p.panelHoleDiameter >= p.outerDiameter)
10670
+ issue(
10671
+ "Diameters must satisfy bore < panel hole < outside diameter",
10672
+ "panelHoleDiameter"
10673
+ );
10674
+ if (p.grooveWidth >= p.height)
10675
+ issue("The groove must leave two positive-thickness flanges", "grooveWidth");
10676
+ if (Math.abs(p.outerDiameter - 2 * p.grooveDepth - p.panelHoleDiameter) > 1e-9 * p.outerDiameter)
10677
+ issue(
10678
+ "Panel hole diameter must equal OD minus twice the radial groove depth",
10679
+ "grooveDepth"
10680
+ );
10681
+ if (p.splitWidth >= p.innerDiameter)
10682
+ issue(
10683
+ "The slit must be narrower than the bore to retain the opposite wall",
10684
+ "splitWidth"
10685
+ );
10686
+ if (!Number.isFinite(
10687
+ 8 * Math.max(
10688
+ p.panelHoleDiameter,
10689
+ p.innerDiameter,
10690
+ p.outerDiameter,
10691
+ p.height,
10692
+ p.grooveWidth,
10693
+ p.grooveDepth,
10694
+ p.splitWidth
10695
+ ) ** 3
10696
+ ))
10697
+ issue(
10698
+ "Dimensions exceed finite derived geometry limits",
10699
+ "panelHoleDiameter"
10700
+ );
10701
+ }
10702
+ var splitGrommetModelPropsSchema = external_exports.object(shape35).strict().superRefine(validate34);
10703
+ var splitGrommetModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("splitgrommet"), ...shape35 }).strict().superRefine(validate34);
10704
+ function getSplitGrommetDimensions(input) {
10705
+ const p = splitGrommetModelPropsSchema.parse(input);
10706
+ return {
10707
+ ...p,
10708
+ size: [p.outerDiameter, p.outerDiameter, p.height],
10709
+ bottomZ: -p.height / 2,
10710
+ topZ: p.height / 2,
10711
+ grooveRootDiameter: p.outerDiameter - 2 * p.grooveDepth,
10712
+ flangeThickness: (p.height - p.grooveWidth) / 2,
10713
+ grooveStartZ: -p.grooveWidth / 2,
10714
+ grooveEndZ: p.grooveWidth / 2,
10715
+ slitMinY: -p.splitWidth / 2,
10716
+ slitMaxY: p.splitWidth / 2,
10717
+ minimumWallThickness: (p.panelHoleDiameter - p.innerDiameter) / 2
10718
+ };
10719
+ }
10720
+ var lengths17 = {
10721
+ panelhole: "panelHoleDiameter",
10722
+ id: "innerDiameter",
10723
+ od: "outerDiameter",
10724
+ h: "height",
10725
+ groovew: "grooveWidth",
10726
+ grooved: "grooveDepth",
10727
+ split: "splitWidth",
10728
+ panelholediameter: "panelHoleDiameter",
10729
+ innerdiameter: "innerDiameter",
10730
+ outerdiameter: "outerDiameter",
10731
+ height: "height",
10732
+ groovewidth: "grooveWidth",
10733
+ groovedepth: "grooveDepth",
10734
+ splitwidth: "splitWidth"
10735
+ };
10736
+ var flags7 = {};
10737
+ var selectors5 = {};
10738
+ var integers2 = {};
10739
+ var tuples2 = {};
10740
+ function parseSplitGrommetModelParams(raw) {
10741
+ const [name, ...tokens] = splitModelStringTokens(raw.string);
10742
+ if (raw.fn !== "splitgrommet" || name?.toLowerCase() !== "splitgrommet")
10743
+ throw new Error("Expected splitgrommet without inline values");
10744
+ const props = { fn: "splitgrommet" };
10745
+ const assign = (property, value) => {
10746
+ if (Object.hasOwn(props, property))
10747
+ throw new Error(`Duplicate splitgrommet property "${property}"`);
10748
+ props[property] = value;
10749
+ };
10750
+ for (const token of tokens) {
10751
+ const match = token.match(/^([a-z]+)(.*)$/i);
10752
+ if (!match) throw new Error(`Malformed splitgrommet token "${token}"`);
10753
+ const key = match[1].toLowerCase(), value = match[2];
10754
+ if (Object.hasOwn(lengths17, key) && value) assign(lengths17[key], value);
10755
+ else if (Object.hasOwn(flags7, key) && !value) assign(flags7[key], true);
10756
+ else if (Object.hasOwn(selectors5, key) && value.toLowerCase() === `(${selectors5[key].value})`)
10757
+ assign(selectors5[key].property, true);
10758
+ else if (Object.hasOwn(integers2, key) && /^\d+$/.test(value))
10759
+ assign(integers2[key], Number(value));
10760
+ else if (Object.hasOwn(tuples2, key)) {
10761
+ const pair = value.match(/^\(([^(),]+),([^(),]+)\)$/);
10762
+ if (!pair)
10763
+ throw new Error(`Token "${key}" requires two parenthesized lengths`);
10764
+ assign(tuples2[key][0], pair[1].trim());
10765
+ assign(tuples2[key][1], pair[2].trim());
10766
+ } else throw new Error(`Unknown or malformed splitgrommet token "${token}"`);
10767
+ }
10768
+ return splitGrommetModelDefinitionSchema.parse(props);
10769
+ }
10770
+ var model41 = defineModel({
10771
+ name: "splitgrommet",
10772
+ schema: splitGrommetModelDefinitionSchema,
10773
+ parse: parseSplitGrommetModelParams
10774
+ });
10775
+ function register41(registry2) {
10776
+ registry2.register(model41);
10777
+ }
10778
+ var length25 = external_exports.union([
10442
10779
  external_exports.number(),
10443
10780
  external_exports.string().regex(/^(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i)
10444
10781
  ]).pipe(modelLengthSchema);
10445
- var positiveLength17 = length23.refine(
10782
+ var positiveLength19 = length25.refine(
10446
10783
  (value) => value > 0,
10447
10784
  "Length must be positive"
10448
10785
  );
10449
- var shape33 = {
10450
- innerDiameter: positiveLength17,
10451
- outerDiameter: positiveLength17,
10786
+ var shape36 = {
10787
+ innerDiameter: positiveLength19,
10788
+ outerDiameter: positiveLength19,
10452
10789
  /** Axial thickness of the rectangular radial/vertical section. */
10453
- thickness: positiveLength17,
10790
+ thickness: positiveLength19,
10454
10791
  /** End-to-end axial displacement, independent of section thickness. */
10455
- rise: length23.refine((value) => value >= 0, "Rise cannot be negative"),
10792
+ rise: length25.refine((value) => value >= 0, "Rise cannot be negative"),
10456
10793
  gapAngle: external_exports.number().finite().gt(0).lt(360),
10457
10794
  rectangular: external_exports.literal(true).default(true),
10458
10795
  leftHanded: external_exports.boolean().default(false)
10459
10796
  };
10460
- function validate32(p, context) {
10797
+ function validate35(p, context) {
10461
10798
  if (p.innerDiameter >= p.outerDiameter)
10462
10799
  context.addIssue({
10463
10800
  code: "custom",
@@ -10470,9 +10807,9 @@ function validate32(p, context) {
10470
10807
  message: "The washer envelope and volume must remain finite"
10471
10808
  });
10472
10809
  }
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);
10475
- var lengths16 = {
10810
+ var splitWasherModelPropsSchema = external_exports.object(shape36).strict().superRefine(validate35);
10811
+ var splitWasherModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("splitwasher"), ...shape36 }).strict().superRefine(validate35);
10812
+ var lengths18 = {
10476
10813
  id: "innerDiameter",
10477
10814
  innerdiameter: "innerDiameter",
10478
10815
  od: "outerDiameter",
@@ -10500,8 +10837,8 @@ function parseSplitWasherModelParams(raw) {
10500
10837
  const name = match?.[1]?.toLowerCase(), suffix = match?.[2];
10501
10838
  if (!name || !suffix)
10502
10839
  throw new Error(`Invalid split washer token "${token}"`);
10503
- if (Object.hasOwn(lengths16, name)) {
10504
- property = lengths16[name];
10840
+ if (Object.hasOwn(lengths18, name)) {
10841
+ property = lengths18[name];
10505
10842
  value = suffix;
10506
10843
  } else if (name === "gapangle") {
10507
10844
  const angle = suffix.match(/^(\d+(?:\.\d*)?|\.\d+)(?:deg)?$/i);
@@ -10516,20 +10853,20 @@ function parseSplitWasherModelParams(raw) {
10516
10853
  }
10517
10854
  return splitWasherModelDefinitionSchema.parse(props);
10518
10855
  }
10519
- var model39 = defineModel({
10856
+ var model42 = defineModel({
10520
10857
  name: "splitwasher",
10521
10858
  schema: splitWasherModelDefinitionSchema,
10522
10859
  parse: parseSplitWasherModelParams
10523
10860
  });
10524
- function register39(registry2) {
10525
- registry2.register(model39);
10861
+ function register42(registry2) {
10862
+ registry2.register(model42);
10526
10863
  }
10527
- var length24 = external_exports.union([
10864
+ var length26 = external_exports.union([
10528
10865
  external_exports.number(),
10529
10866
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
10530
10867
  ]).pipe(modelLengthSchema);
10531
- var positiveLength18 = length24.refine((value) => value > 0);
10532
- var nonnegativeLength7 = length24.refine((value) => value >= 0);
10868
+ var positiveLength20 = length26.refine((value) => value > 0);
10869
+ var nonnegativeLength9 = length26.refine((value) => value >= 0);
10533
10870
  var threadedRodCoarsePitches = {
10534
10871
  M2: 0.4,
10535
10872
  "M2.5": 0.45,
@@ -10556,13 +10893,13 @@ var threadedRodMetricSizeSchema = external_exports.enum([
10556
10893
  "M16",
10557
10894
  "M20"
10558
10895
  ]);
10559
- var shape34 = {
10896
+ var shape37 = {
10560
10897
  metricSize: threadedRodMetricSizeSchema,
10561
10898
  /** Overall end-plane distance, including terminal chamfers. */
10562
- length: positiveLength18,
10899
+ length: positiveLength20,
10563
10900
  /** Equal axial and radial setbacks of the two 45-degree outer chamfers. */
10564
- chamfer: nonnegativeLength7.default(0),
10565
- threadPitch: positiveLength18.optional(),
10901
+ chamfer: nonnegativeLength9.default(0),
10902
+ threadPitch: positiveLength20.optional(),
10566
10903
  leftHand: external_exports.boolean().default(false)
10567
10904
  };
10568
10905
  function resolve8(props) {
@@ -10571,7 +10908,7 @@ function resolve8(props) {
10571
10908
  threadPitch: props.threadPitch ?? threadedRodCoarsePitches[props.metricSize]
10572
10909
  };
10573
10910
  }
10574
- function validate33(props, context) {
10911
+ function validate36(props, context) {
10575
10912
  const diameter = Number(props.metricSize.slice(1));
10576
10913
  const pitch = resolve8(props).threadPitch;
10577
10914
  if (diameter - 1.226869 * pitch <= 0)
@@ -10587,8 +10924,8 @@ function validate33(props, context) {
10587
10924
  message: "Chamfer must leave flat end faces and separate end chamfers"
10588
10925
  });
10589
10926
  }
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) }));
10927
+ var threadedRodModelPropsSchema = external_exports.object(shape37).strict().superRefine(validate36).transform(resolve8);
10928
+ var threadedRodModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("threadedrod"), ...shape37 }).strict().superRefine(validate36).transform((model502) => ({ fn: model502.fn, ...resolve8(model502) }));
10592
10929
  function getThreadedRodDimensions(input) {
10593
10930
  const props = threadedRodModelPropsSchema.parse(input);
10594
10931
  const diameter = Number(props.metricSize.slice(1));
@@ -10601,7 +10938,7 @@ function getThreadedRodDimensions(input) {
10601
10938
  endDiameter: diameter - 2 * props.chamfer
10602
10939
  };
10603
10940
  }
10604
- var lengths17 = {
10941
+ var lengths19 = {
10605
10942
  l: "length",
10606
10943
  length: "length",
10607
10944
  chamfer: "chamfer",
@@ -10633,8 +10970,8 @@ function parseThreadedRodModelParams(raw) {
10633
10970
  if (!/^\d+(?:\.\d+)?$/.test(value))
10634
10971
  throw new Error("Metric size must be a unitless diameter");
10635
10972
  parsed = `M${value}`;
10636
- } else if (Object.hasOwn(lengths17, name)) {
10637
- property = lengths17[name];
10973
+ } else if (Object.hasOwn(lengths19, name)) {
10974
+ property = lengths19[name];
10638
10975
  parsed = value;
10639
10976
  } else throw new Error(`Unknown threaded rod token "${token}"`);
10640
10977
  if (seen.has(property))
@@ -10656,21 +10993,21 @@ function normalizeThreadedRodModelString(value) {
10656
10993
  return [lower === "lefthanded" ? lower : token];
10657
10994
  }).join("_");
10658
10995
  }
10659
- var model40 = defineModel({
10996
+ var model43 = defineModel({
10660
10997
  name: "threadedrod",
10661
10998
  schema: threadedRodModelDefinitionSchema,
10662
10999
  parse: parseThreadedRodModelParams,
10663
11000
  normalizeString: normalizeThreadedRodModelString
10664
11001
  });
10665
- function register40(registry2) {
10666
- registry2.register(model40);
11002
+ function register43(registry2) {
11003
+ registry2.register(model43);
10667
11004
  }
10668
- var length25 = external_exports.union([
11005
+ var length27 = external_exports.union([
10669
11006
  external_exports.number(),
10670
11007
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
10671
11008
  ]).pipe(modelLengthSchema);
10672
- var positive7 = length25.refine((value) => value > 0, "Length must be positive");
10673
- var shape35 = {
11009
+ var positive7 = length27.refine((value) => value > 0, "Length must be positive");
11010
+ var shape38 = {
10674
11011
  outerDiameter: positive7.default(8),
10675
11012
  wireDiameter: positive7.default(0.8),
10676
11013
  /** Fractional turns set the relative leg direction. */
@@ -10684,7 +11021,7 @@ var shape35 = {
10684
11021
  function normalize7(p) {
10685
11022
  return { ...p, pitch: p.pitch ?? p.wireDiameter * 1.25 };
10686
11023
  }
10687
- function validate34(p, context) {
11024
+ function validate37(p, context) {
10688
11025
  if (p.outerDiameter < 3 * p.wireDiameter)
10689
11026
  context.addIssue({
10690
11027
  code: "custom",
@@ -10706,8 +11043,8 @@ function validate34(p, context) {
10706
11043
  message: "Spring dimensions must remain finite"
10707
11044
  });
10708
11045
  }
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 }));
11046
+ var torsionSpringModelPropsSchema = external_exports.object(shape38).strict().superRefine(validate37).transform(normalize7);
11047
+ var torsionSpringModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("torsionspring"), ...shape38 }).strict().superRefine(validate37).transform((p) => ({ ...normalize7(p), fn: p.fn }));
10711
11048
  function getTorsionSpringDimensions(input) {
10712
11049
  const p = torsionSpringModelPropsSchema.parse(input);
10713
11050
  const meanRadius = (p.outerDiameter - p.wireDiameter) / 2;
@@ -10754,7 +11091,7 @@ function getTorsionSpringFrame(input, distance2) {
10754
11091
  ];
10755
11092
  return { position, tangent, normal, binormal };
10756
11093
  }
10757
- var lengths18 = {
11094
+ var lengths20 = {
10758
11095
  od: "outerDiameter",
10759
11096
  wire: "wireDiameter",
10760
11097
  pitch: "pitch",
@@ -10779,7 +11116,7 @@ function parseTorsionSpringModelParams(raw) {
10779
11116
  if (!name || !value)
10780
11117
  throw new Error(`Invalid torsion spring token "${token}"`);
10781
11118
  let property, parsed = value;
10782
- if (name in lengths18) property = lengths18[name];
11119
+ if (name in lengths20) property = lengths20[name];
10783
11120
  else if (name === "turns") {
10784
11121
  property = "turns";
10785
11122
  if (!/^[+]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(value))
@@ -10792,32 +11129,145 @@ function parseTorsionSpringModelParams(raw) {
10792
11129
  }
10793
11130
  return torsionSpringModelDefinitionSchema.parse(props);
10794
11131
  }
10795
- var model41 = defineModel({
11132
+ var model44 = defineModel({
10796
11133
  name: "torsionspring",
10797
11134
  schema: torsionSpringModelDefinitionSchema,
10798
11135
  parse: parseTorsionSpringModelParams
10799
11136
  });
10800
- function register41(registry2) {
10801
- registry2.register(model41);
11137
+ function register44(registry2) {
11138
+ registry2.register(model44);
10802
11139
  }
10803
- var stringFlags13 = {
10804
- fourtsolid: "profile(fourtsolid)"
10805
- };
10806
- var omittedStringFlags13 = [];
10807
- var shape36 = {
10808
- width: positiveGearLengthSchema.default(20),
10809
- height: positiveGearLengthSchema.default(20),
10810
- length: positiveGearLengthSchema.default(100),
10811
- profile: external_exports.literal("fourtsolid").default("fourtsolid"),
10812
- slotWidth: positiveGearLengthSchema.default(6),
10813
- pocketWidth: positiveGearLengthSchema.default(10),
10814
- pocketDepth: positiveGearLengthSchema.default(2),
10815
- /** Depth of the narrow slot opening before the wider pocket begins. */
10816
- lipThickness: positiveGearLengthSchema.default(2),
11140
+ var length28 = external_exports.union([
11141
+ external_exports.number(),
11142
+ external_exports.string().regex(/^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
11143
+ ]).pipe(modelLengthSchema);
11144
+ var positiveLength21 = length28.refine(
11145
+ (value) => value > 0,
11146
+ "Length must be positive"
11147
+ );
11148
+ var nonnegativeLength10 = length28.refine(
11149
+ (value) => value >= 0,
11150
+ "Length cannot be negative"
11151
+ );
11152
+ var shape39 = {
11153
+ length: positiveLength21,
11154
+ width: positiveLength21,
11155
+ thickness: positiveLength21,
11156
+ stemWidth: positiveLength21,
11157
+ stemHeight: positiveLength21,
11158
+ barbWidth: positiveLength21,
11159
+ barbHeight: positiveLength21.default(0.5),
11160
+ tee: external_exports.literal(true).default(true)
11161
+ };
11162
+ function validate38(p, context) {
11163
+ const span = Math.max(p.width, p.length, p.thickness + p.stemHeight);
11164
+ if (!Number.isFinite(span ** 3))
11165
+ context.addIssue({
11166
+ code: "custom",
11167
+ message: "Dimensions must have a finite bounding volume"
11168
+ });
11169
+ if (p.stemWidth >= p.barbWidth)
11170
+ context.addIssue({
11171
+ code: "custom",
11172
+ path: ["barbWidth"],
11173
+ message: "Retention bead must be wider than the stem"
11174
+ });
11175
+ if (p.barbWidth >= p.width)
11176
+ context.addIssue({
11177
+ code: "custom",
11178
+ path: ["width"],
11179
+ message: "Cover plate must extend beyond the retention bead"
11180
+ });
11181
+ if (p.barbHeight >= p.stemHeight)
11182
+ context.addIssue({
11183
+ code: "custom",
11184
+ path: ["barbHeight"],
11185
+ message: "Retention bead height must leave a positive narrow stem section"
11186
+ });
11187
+ }
11188
+ var tSlotCoverStripModelPropsSchema = external_exports.object(shape39).strict().superRefine(validate38);
11189
+ var tSlotCoverStripModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotcoverstrip"), ...shape39 }).strict().superRefine(validate38);
11190
+ var aliases15 = {
11191
+ l: "length",
11192
+ length: "length",
11193
+ w: "width",
11194
+ width: "width",
11195
+ t: "thickness",
11196
+ thickness: "thickness",
11197
+ stemw: "stemWidth",
11198
+ stemwidth: "stemWidth",
11199
+ stemh: "stemHeight",
11200
+ stemheight: "stemHeight",
11201
+ barbw: "barbWidth",
11202
+ barbwidth: "barbWidth",
11203
+ barbh: "barbHeight",
11204
+ barbheight: "barbHeight"
11205
+ };
11206
+ var flags8 = {
11207
+ tee: "tee"
11208
+ };
11209
+ var literals = {
11210
+ profile: ["tee", "tee"]
11211
+ };
11212
+ function parseTSlotCoverStripModelParams(raw) {
11213
+ const [name, ...tokens] = splitModelStringTokens(raw.string);
11214
+ if (raw.fn !== "tslotcoverstrip" || name?.toLowerCase() !== "tslotcoverstrip")
11215
+ throw new Error("Expected tslotcoverstrip without inline values");
11216
+ const props = { fn: "tslotcoverstrip" };
11217
+ const assign = (property, value) => {
11218
+ if (Object.hasOwn(props, property))
11219
+ throw new Error(`Duplicate tslotcoverstrip property "${property}"`);
11220
+ props[property] = value;
11221
+ };
11222
+ for (const token of tokens) {
11223
+ const match = token.match(/^([a-z]+)(.*)$/i);
11224
+ const key = match?.[1]?.toLowerCase();
11225
+ const value = match?.[2];
11226
+ if (!key || value === void 0)
11227
+ throw new Error(`Malformed tslotcoverstrip token "${token}"`);
11228
+ if (Object.hasOwn(flags8, key)) {
11229
+ if (value !== "")
11230
+ throw new Error(`tslotcoverstrip flag "${key}" takes no value`);
11231
+ assign(flags8[key], true);
11232
+ } else if (Object.hasOwn(literals, key)) {
11233
+ const [literal, property] = literals[key];
11234
+ if (value.toLowerCase() !== `(${literal})`)
11235
+ throw new Error(`Expected tslotcoverstrip ${key}(${literal})`);
11236
+ assign(property, true);
11237
+ } else if (Object.hasOwn(aliases15, key) && value) {
11238
+ const property = aliases15[key];
11239
+ assign(property, property === "pinCount" ? Number(value) : value);
11240
+ } else
11241
+ throw new Error(`Unknown or malformed tslotcoverstrip token "${token}"`);
11242
+ }
11243
+ return tSlotCoverStripModelDefinitionSchema.parse(props);
11244
+ }
11245
+ var model45 = defineModel({
11246
+ name: "tslotcoverstrip",
11247
+ schema: tSlotCoverStripModelDefinitionSchema,
11248
+ parse: parseTSlotCoverStripModelParams
11249
+ });
11250
+ function register45(registry2) {
11251
+ registry2.register(model45);
11252
+ }
11253
+ var stringFlags13 = {
11254
+ fourtsolid: "profile(fourtsolid)"
11255
+ };
11256
+ var omittedStringFlags13 = [];
11257
+ var shape40 = {
11258
+ width: positiveGearLengthSchema.default(20),
11259
+ height: positiveGearLengthSchema.default(20),
11260
+ length: positiveGearLengthSchema.default(100),
11261
+ profile: external_exports.literal("fourtsolid").default("fourtsolid"),
11262
+ slotWidth: positiveGearLengthSchema.default(6),
11263
+ pocketWidth: positiveGearLengthSchema.default(10),
11264
+ pocketDepth: positiveGearLengthSchema.default(2),
11265
+ /** Depth of the narrow slot opening before the wider pocket begins. */
11266
+ lipThickness: positiveGearLengthSchema.default(2),
10817
11267
  boreDiameter: nonnegativeGearLengthSchema.default(0),
10818
11268
  cornerRadius: nonnegativeGearLengthSchema.default(0)
10819
11269
  };
10820
- function validate35(props, context) {
11270
+ function validate39(props, context) {
10821
11271
  const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
10822
11272
  const halfSize = Math.min(props.width, props.height) / 2;
10823
11273
  const depth = props.lipThickness + props.pocketDepth;
@@ -10845,9 +11295,9 @@ function validate35(props, context) {
10845
11295
  "boreDiameter"
10846
11296
  );
10847
11297
  }
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);
10850
- var lengths19 = {
11298
+ var tSlotExtrusionModelPropsSchema = external_exports.object(shape40).strict().superRefine(validate39);
11299
+ var tSlotExtrusionModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotextrusion"), ...shape40 }).strict().superRefine(validate39);
11300
+ var lengths21 = {
10851
11301
  w: "width",
10852
11302
  width: "width",
10853
11303
  h: "height",
@@ -10878,7 +11328,7 @@ function parseTSlotExtrusionModelParams(raw) {
10878
11328
  const [name, value] = parseGearToken(token);
10879
11329
  let property;
10880
11330
  let parsed = value;
10881
- if (name in lengths19) property = lengths19[name];
11331
+ if (name in lengths21) property = lengths21[name];
10882
11332
  else if (name === "profile") {
10883
11333
  property = "profile";
10884
11334
  const match = value.match(/^\(([a-z]+)\)$/i);
@@ -10891,7 +11341,7 @@ function parseTSlotExtrusionModelParams(raw) {
10891
11341
  }
10892
11342
  return tSlotExtrusionModelDefinitionSchema.parse(props);
10893
11343
  }
10894
- var model42 = defineModel({
11344
+ var model46 = defineModel({
10895
11345
  name: "tslotextrusion",
10896
11346
  schema: tSlotExtrusionModelDefinitionSchema,
10897
11347
  parse: parseTSlotExtrusionModelParams,
@@ -10902,14 +11352,14 @@ var model42 = defineModel({
10902
11352
  omittedStringFlags13
10903
11353
  )
10904
11354
  });
10905
- function register42(registry2) {
10906
- registry2.register(model42);
11355
+ function register46(registry2) {
11356
+ registry2.register(model46);
10907
11357
  }
10908
11358
  var stringFlags14 = {
10909
11359
  righttriangle: "shape(righttriangle)"
10910
11360
  };
10911
11361
  var omittedStringFlags14 = [];
10912
- var shape37 = {
11362
+ var shape41 = {
10913
11363
  width: positiveGearLengthSchema.default(40),
10914
11364
  height: positiveGearLengthSchema.default(40),
10915
11365
  thickness: positiveGearLengthSchema.default(4),
@@ -10922,22 +11372,22 @@ var shape37 = {
10922
11372
  /** Ligament between each slot and its parallel outer plate edge. */
10923
11373
  edgeMargin: positiveGearLengthSchema.default(1)
10924
11374
  };
10925
- function validate36(props, context) {
11375
+ function validate40(props, context) {
10926
11376
  const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
10927
- const [width10, length26] = props.slot;
10928
- if (length26 < width10) {
11377
+ const [width10, length29] = props.slot;
11378
+ if (length29 < width10) {
10929
11379
  issue("Slot length must be at least its width", "slot");
10930
11380
  return;
10931
11381
  }
10932
11382
  const radius = width10 / 2;
10933
- const halfStraight = (length26 - width10) / 2;
11383
+ const halfStraight = (length29 - width10) / 2;
10934
11384
  const inset = props.edgeMargin + radius;
10935
11385
  const [x, y] = props.centers;
10936
11386
  if (!Number.isFinite(inset)) {
10937
11387
  issue("Derived slot centers must be finite", "edgeMargin");
10938
11388
  return;
10939
11389
  }
10940
- if (x <= length26 / 2 || y <= length26 / 2)
11390
+ if (x <= length29 / 2 || y <= length29 / 2)
10941
11391
  issue("Slots must leave material at the right-angle corner", "centers");
10942
11392
  const normalRatio = Math.min(props.width, props.height) / Math.max(props.width, props.height);
10943
11393
  const capSupport = radius / Math.min(props.width, props.height) * Math.hypot(1, normalRatio);
@@ -10953,18 +11403,18 @@ function validate36(props, context) {
10953
11403
  if (Math.hypot(dx, dy) <= width10)
10954
11404
  issue("The two slots must retain a positive separating ligament", "centers");
10955
11405
  }
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);
11406
+ var tSlotGussetModelPropsSchema = external_exports.object(shape41).strict().superRefine(validate40);
11407
+ var tSlotGussetModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotgusset"), ...shape41 }).strict().superRefine(validate40);
10958
11408
  function getTSlotGussetMountingSlots(input = {}) {
10959
11409
  const props = tSlotGussetModelPropsSchema.parse(input);
10960
- const [width10, length26] = props.slot;
11410
+ const [width10, length29] = props.slot;
10961
11411
  const inset = props.edgeMargin + width10 / 2;
10962
11412
  return [
10963
11413
  {
10964
11414
  center: { x: props.centers[0], y: inset, z: 0 },
10965
11415
  orientation: 0,
10966
11416
  width: width10,
10967
- length: length26,
11417
+ length: length29,
10968
11418
  depth: props.thickness,
10969
11419
  direction: { x: 0, y: 0, z: 1 }
10970
11420
  },
@@ -10972,13 +11422,13 @@ function getTSlotGussetMountingSlots(input = {}) {
10972
11422
  center: { x: inset, y: props.centers[1], z: 0 },
10973
11423
  orientation: 90,
10974
11424
  width: width10,
10975
- length: length26,
11425
+ length: length29,
10976
11426
  depth: props.thickness,
10977
11427
  direction: { x: 0, y: 0, z: 1 }
10978
11428
  }
10979
11429
  ];
10980
11430
  }
10981
- var lengths20 = {
11431
+ var lengths22 = {
10982
11432
  w: "width",
10983
11433
  width: "width",
10984
11434
  h: "height",
@@ -10998,7 +11448,7 @@ function parseTSlotGussetModelParams(raw) {
10998
11448
  const [name, value] = parseGearToken(token);
10999
11449
  let property;
11000
11450
  let parsed = value;
11001
- if (name in lengths20) property = lengths20[name];
11451
+ if (name in lengths22) property = lengths22[name];
11002
11452
  else if (name === "slots" || name === "slotcount") {
11003
11453
  property = "slotCount";
11004
11454
  parsed = parseGearInteger(value, "slotCount");
@@ -11019,7 +11469,7 @@ function parseTSlotGussetModelParams(raw) {
11019
11469
  }
11020
11470
  return tSlotGussetModelDefinitionSchema.parse(props);
11021
11471
  }
11022
- var model43 = defineModel({
11472
+ var model47 = defineModel({
11023
11473
  name: "tslotgusset",
11024
11474
  schema: tSlotGussetModelDefinitionSchema,
11025
11475
  parse: parseTSlotGussetModelParams,
@@ -11030,10 +11480,10 @@ var model43 = defineModel({
11030
11480
  omittedStringFlags14
11031
11481
  )
11032
11482
  });
11033
- function register43(registry2) {
11034
- registry2.register(model43);
11483
+ function register47(registry2) {
11484
+ registry2.register(model47);
11035
11485
  }
11036
- var shape38 = {
11486
+ var shape42 = {
11037
11487
  width: positiveGearLengthSchema.default(20),
11038
11488
  /** Equal leg extents from the virtual intersection of the inside flats. */
11039
11489
  legLength: positiveGearLengthSchema.default(40),
@@ -11045,7 +11495,7 @@ var shape38 = {
11045
11495
  holeOffset: positiveGearLengthSchema.default(20),
11046
11496
  bendRadius: nonnegativeGearLengthSchema.default(0)
11047
11497
  };
11048
- function validate37(props, context) {
11498
+ function validate41(props, context) {
11049
11499
  const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
11050
11500
  if (!Number.isFinite(props.bendRadius + props.thickness)) {
11051
11501
  issue("Outside bend radius must be finite", "bendRadius");
@@ -11063,9 +11513,9 @@ function validate37(props, context) {
11063
11513
  if (props.holeOffset + radius >= props.legLength)
11064
11514
  issue("Holes must leave material at the free leg ends", "holeOffset");
11065
11515
  }
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);
11068
- var lengths21 = {
11516
+ var tSlotInsideCornerModelPropsSchema = external_exports.object(shape42).strict().superRefine(validate41);
11517
+ var tSlotInsideCornerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotinsidecorner"), ...shape42 }).strict().superRefine(validate41);
11518
+ var lengths23 = {
11069
11519
  w: "width",
11070
11520
  width: "width",
11071
11521
  leg: "legLength",
@@ -11088,7 +11538,7 @@ function parseTSlotInsideCornerModelParams(raw) {
11088
11538
  const [name, value] = parseGearToken(token);
11089
11539
  let property;
11090
11540
  let parsed = value;
11091
- if (name in lengths21) property = lengths21[name];
11541
+ if (name in lengths23) property = lengths23[name];
11092
11542
  else if (name === "holes" || name === "holecount") {
11093
11543
  property = "holeCount";
11094
11544
  parsed = parseGearInteger(value, "holeCount");
@@ -11102,13 +11552,85 @@ function parseTSlotInsideCornerModelParams(raw) {
11102
11552
  }
11103
11553
  return tSlotInsideCornerModelDefinitionSchema.parse(props);
11104
11554
  }
11105
- var model44 = defineModel({
11555
+ var model48 = defineModel({
11106
11556
  name: "tslotinsidecorner",
11107
11557
  schema: tSlotInsideCornerModelDefinitionSchema,
11108
11558
  parse: parseTSlotInsideCornerModelParams
11109
11559
  });
11110
- function register44(registry2) {
11111
- registry2.register(model44);
11560
+ function register48(registry2) {
11561
+ registry2.register(model48);
11562
+ }
11563
+ var shape43 = {
11564
+ height: positiveGearLengthSchema,
11565
+ upperWidth: positiveGearLengthSchema,
11566
+ lowerWidth: positiveGearLengthSchema,
11567
+ thickness: positiveGearLengthSchema,
11568
+ bendRadius: nonnegativeGearLengthSchema,
11569
+ length: positiveGearLengthSchema
11570
+ };
11571
+ function validate42(p, context) {
11572
+ const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
11573
+ const largestDimension = Math.max(
11574
+ ...Object.values(p).filter(
11575
+ (value) => typeof value === "number"
11576
+ )
11577
+ );
11578
+ if (!Number.isFinite((4 * largestDimension) ** 3)) {
11579
+ issue(
11580
+ "Dimensions must permit finite derived coordinates and volume",
11581
+ "height"
11582
+ );
11583
+ return;
11584
+ }
11585
+ if (p.bendRadius + p.thickness >= Math.min(p.upperWidth, p.lowerWidth))
11586
+ issue(
11587
+ "Both flanges must retain straight portions beyond their bends",
11588
+ "bendRadius"
11589
+ );
11590
+ if (2 * (p.bendRadius + p.thickness) >= p.height)
11591
+ issue("Height must leave a straight web between both bends", "height");
11592
+ if (!Number.isFinite(p.upperWidth + p.lowerWidth - p.thickness))
11593
+ issue("The combined section width must be finite", "upperWidth");
11594
+ }
11595
+ var zeeBarModelPropsSchema = external_exports.object(shape43).strict().superRefine(validate42);
11596
+ var zeeBarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("zeebar"), ...shape43 }).strict().superRefine(validate42);
11597
+ var aliases16 = {
11598
+ h: "height",
11599
+ upperw: "upperWidth",
11600
+ lowerw: "lowerWidth",
11601
+ t: "thickness",
11602
+ bendr: "bendRadius",
11603
+ l: "length",
11604
+ height: "height",
11605
+ upperwidth: "upperWidth",
11606
+ lowerwidth: "lowerWidth",
11607
+ thickness: "thickness",
11608
+ bendradius: "bendRadius",
11609
+ length: "length"
11610
+ };
11611
+ function parseZeeBarModelParams(raw) {
11612
+ const [name, ...tokens] = splitModelStringTokens(raw.string);
11613
+ if (raw.fn !== "zeebar" || name?.toLowerCase() !== "zeebar")
11614
+ throw new Error("Expected zeebar without inline values");
11615
+ const props = { fn: "zeebar" };
11616
+ for (const token of tokens) {
11617
+ const [key, value] = parseGearToken(token);
11618
+ if (!Object.hasOwn(aliases16, key) || !value)
11619
+ throw new Error(`Unknown or malformed zeebar token "${token}"`);
11620
+ const property = aliases16[key];
11621
+ if (Object.hasOwn(props, property))
11622
+ throw new Error(`Repeated zeebar property "${property}"`);
11623
+ props[property] = value;
11624
+ }
11625
+ return zeeBarModelDefinitionSchema.parse(props);
11626
+ }
11627
+ var model49 = defineModel({
11628
+ name: "zeebar",
11629
+ schema: zeeBarModelDefinitionSchema,
11630
+ parse: parseZeeBarModelParams
11631
+ });
11632
+ function register49(registry2) {
11633
+ registry2.register(model49);
11112
11634
  }
11113
11635
  function getNemaMotorReferencePoints(input) {
11114
11636
  const p = nemaMotorModelPropsSchema.parse(input);
@@ -11198,7 +11720,12 @@ var modelDefinitionSchema = external_exports.union([
11198
11720
  model41.schema,
11199
11721
  model42.schema,
11200
11722
  model43.schema,
11201
- model44.schema
11723
+ model44.schema,
11724
+ model45.schema,
11725
+ model46.schema,
11726
+ model47.schema,
11727
+ model48.schema,
11728
+ model49.schema
11202
11729
  ]);
11203
11730
  function registerAllModels(registry2) {
11204
11731
  register(registry2);
@@ -11245,6 +11772,11 @@ function registerAllModels(registry2) {
11245
11772
  register42(registry2);
11246
11773
  register43(registry2);
11247
11774
  register44(registry2);
11775
+ register45(registry2);
11776
+ register46(registry2);
11777
+ register47(registry2);
11778
+ register48(registry2);
11779
+ register49(registry2);
11248
11780
  }
11249
11781
  var registry = new ModelRegistry();
11250
11782
  registerAllModels(registry);
@@ -11427,24 +11959,24 @@ var FootprintPlatedHole = ({
11427
11959
  };
11428
11960
 
11429
11961
  // lib/model-registry.ts
11430
- function defineModelRenderer(model88) {
11431
- return model88;
11962
+ function defineModelRenderer(model98) {
11963
+ return model98;
11432
11964
  }
11433
11965
  var ModelRendererRegistry = class {
11434
11966
  models = /* @__PURE__ */ new Map();
11435
- register(model88) {
11436
- if (typeof model88.name !== "string" || !/^[a-z]+$/.test(model88.name)) {
11967
+ register(model98) {
11968
+ if (typeof model98.name !== "string" || !/^[a-z]+$/.test(model98.name)) {
11437
11969
  throw new Error(
11438
11970
  "Model renderer names must contain only lowercase letters"
11439
11971
  );
11440
11972
  }
11441
- if (this.models.has(model88.name)) {
11442
- throw new Error(`Model renderer "${model88.name}" is already registered`);
11973
+ if (this.models.has(model98.name)) {
11974
+ throw new Error(`Model renderer "${model98.name}" is already registered`);
11443
11975
  }
11444
- if (model88.pads !== "none" && model88.pads !== "footprinter") {
11976
+ if (model98.pads !== "none" && model98.pads !== "footprinter") {
11445
11977
  throw new Error('Model renderer pads must be "none" or "footprinter"');
11446
11978
  }
11447
- const { name, schema, render: render2, pads } = model88;
11979
+ const { name, schema, render: render2, pads } = model98;
11448
11980
  this.models.set(name, {
11449
11981
  name,
11450
11982
  schema,
@@ -11475,7 +12007,7 @@ import jscad from "@jscad/modeling";
11475
12007
  var { primitives, extrusions, geometries, modifiers, measurements } = jscad;
11476
12008
  var generalize = modifiers.generalize;
11477
12009
  var { rectangle, roundedRectangle, polygon } = primitives;
11478
- var profile = (shape39, height10) => extrusions.extrudeLinear({ height: height10 }, shape39);
12010
+ var profile = (shape44, height10) => extrusions.extrudeLinear({ height: height10 }, shape44);
11479
12011
  function filletProfile(points, radii, width10, height10) {
11480
12012
  const outline = [];
11481
12013
  for (let i = 0; i < points.length; i++) {
@@ -11570,14 +12102,14 @@ function AngleBar({ color = "#929da9", ...props }) {
11570
12102
  }
11571
12103
 
11572
12104
  // lib/models/anglebar/register.tsx
11573
- var model45 = defineModelRenderer({
12105
+ var model50 = defineModelRenderer({
11574
12106
  name: "anglebar",
11575
12107
  schema: angleBarModelDefinitionSchema,
11576
12108
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(AngleBar, { ...props }),
11577
12109
  pads: "none"
11578
12110
  });
11579
- function register45(registry2) {
11580
- registry2.register(model45);
12111
+ function register50(registry2) {
12112
+ registry2.register(model50);
11581
12113
  }
11582
12114
 
11583
12115
  // lib/mechanical/indexedMeshToGeom3.ts
@@ -11708,7 +12240,7 @@ function createBallBearingMesh(input = {}, options = {}) {
11708
12240
  if (face2 === "open") continue;
11709
12241
  const t = d.closureThickness;
11710
12242
  const ri = d.innerRaceOuterRadius, ro = d.outerRaceInnerRadius;
11711
- const shape39 = face2 === "shielded" ? [
12243
+ const shape44 = face2 === "shielded" ? [
11712
12244
  [ro, 0],
11713
12245
  [ro, t * 0.45],
11714
12246
  [ri, t * 0.45],
@@ -11721,7 +12253,7 @@ function createBallBearingMesh(input = {}, options = {}) {
11721
12253
  [ri + 0.15 * (ro - ri), 0.5 * t],
11722
12254
  [ro - 0.15 * (ro - ri), 0.5 * t]
11723
12255
  ];
11724
- const profile6 = sign === -1 ? shape39 : shape39.map(([r, z]) => [r, d.width - z]).reverse();
12256
+ const profile6 = sign === -1 ? shape44 : shape44.map(([r, z]) => [r, d.width - z]).reverse();
11725
12257
  parts.push({
11726
12258
  name: `${face2} ${sign < 0 ? "lower" : "upper"}`,
11727
12259
  color: face2 === "sealed" ? "#252a30" : "#b5bbc3",
@@ -11735,9 +12267,9 @@ function segmentsFor(value = 96) {
11735
12267
  throw new Error("Segments must be a multiple of 24 from 96 to 192");
11736
12268
  return value;
11737
12269
  }
11738
- function checkPrecision(lengths22) {
11739
- const largest = Math.max(...lengths22);
11740
- if (!lengths22.every(Number.isFinite) || largest > 1e6 || Math.min(...lengths22) < Math.max(1e-5, largest * 1e-7))
12270
+ function checkPrecision(lengths24) {
12271
+ const largest = Math.max(...lengths24);
12272
+ if (!lengths24.every(Number.isFinite) || largest > 1e6 || Math.min(...lengths24) < Math.max(1e-5, largest * 1e-7))
11741
12273
  throw new Error(
11742
12274
  "Bearing dimensions exceed the renderer's numerical resolution"
11743
12275
  );
@@ -11845,14 +12377,14 @@ function BallBearing({ color, ...props }) {
11845
12377
  }
11846
12378
 
11847
12379
  // lib/models/ballbearing/register.tsx
11848
- var model46 = defineModelRenderer({
12380
+ var model51 = defineModelRenderer({
11849
12381
  name: "ballbearing",
11850
12382
  schema: ballBearingModelDefinitionSchema,
11851
12383
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(BallBearing, { ...props }),
11852
12384
  pads: "none"
11853
12385
  });
11854
- function register46(registry2) {
11855
- registry2.register(model46);
12386
+ function register51(registry2) {
12387
+ registry2.register(model51);
11856
12388
  }
11857
12389
 
11858
12390
  // lib/models/balltransferunit/mesh.ts
@@ -11944,7 +12476,7 @@ function circularProfile(x, y, radius, segments = 96) {
11944
12476
  // lib/models/balltransferunit/mesh.ts
11945
12477
  function createBallTransferUnitMesh(input = {}) {
11946
12478
  const d = getBallTransferUnitDimensions(input);
11947
- const lengths22 = [
12479
+ const lengths24 = [
11948
12480
  d.height,
11949
12481
  d.flangeDiameter,
11950
12482
  d.flangeThickness,
@@ -11958,9 +12490,9 @@ function createBallTransferUnitMesh(input = {}) {
11958
12490
  (d.pitchCircleDiameter - d.holeDiameter - d.bodyDiameter) / 2,
11959
12491
  (d.flangeDiameter - d.pitchCircleDiameter - d.holeDiameter) / 2
11960
12492
  ];
11961
- const largest = Math.max(...lengths22);
12493
+ const largest = Math.max(...lengths24);
11962
12494
  const resolution7 = Math.max(1e-5, largest * 1e-7);
11963
- if (!lengths22.every(Number.isFinite) || largest > 1e6 || Math.min(...lengths22) < resolution7)
12495
+ if (!lengths24.every(Number.isFinite) || largest > 1e6 || Math.min(...lengths24) < resolution7)
11964
12496
  throw new Error(
11965
12497
  "Ball transfer unit exceeds the renderer's numerical resolution"
11966
12498
  );
@@ -12101,14 +12633,14 @@ function BallTransferUnit({ color, ...props }) {
12101
12633
  }
12102
12634
 
12103
12635
  // lib/models/balltransferunit/register.tsx
12104
- var model47 = defineModelRenderer({
12636
+ var model52 = defineModelRenderer({
12105
12637
  name: "balltransferunit",
12106
12638
  schema: ballTransferUnitModelDefinitionSchema,
12107
12639
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(BallTransferUnit, { ...props }),
12108
12640
  pads: "none"
12109
12641
  });
12110
- function register47(registry2) {
12111
- registry2.register(model47);
12642
+ function register52(registry2) {
12643
+ registry2.register(model52);
12112
12644
  }
12113
12645
 
12114
12646
  // lib/models/buttonscrew/mesh.ts
@@ -12228,14 +12760,14 @@ function ButtonScrew({ color = "#737e8f", ...props }) {
12228
12760
  }
12229
12761
 
12230
12762
  // lib/models/buttonscrew/register.tsx
12231
- var model48 = defineModelRenderer({
12763
+ var model53 = defineModelRenderer({
12232
12764
  name: "buttonscrew",
12233
12765
  schema: buttonScrewModelDefinitionSchema,
12234
12766
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ButtonScrew, { ...props }),
12235
12767
  pads: "none"
12236
12768
  });
12237
- function register48(registry2) {
12238
- registry2.register(model48);
12769
+ function register53(registry2) {
12770
+ registry2.register(model53);
12239
12771
  }
12240
12772
 
12241
12773
  // lib/models/cablegrommet/mesh.ts
@@ -12303,14 +12835,14 @@ function CableGrommet({
12303
12835
  }
12304
12836
 
12305
12837
  // lib/models/cablegrommet/register.tsx
12306
- var model49 = defineModelRenderer({
12838
+ var model54 = defineModelRenderer({
12307
12839
  name: "cablegrommet",
12308
12840
  schema: cableGrommetModelDefinitionSchema,
12309
12841
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(CableGrommet, { ...props }),
12310
12842
  pads: "none"
12311
12843
  });
12312
- function register49(registry2) {
12313
- registry2.register(model49);
12844
+ function register54(registry2) {
12845
+ registry2.register(model54);
12314
12846
  }
12315
12847
 
12316
12848
  // lib/models/channelbar/geometry.ts
@@ -12318,7 +12850,7 @@ import jscad3 from "@jscad/modeling";
12318
12850
  var { primitives: primitives2, extrusions: extrusions2, geometries: geometries2, modifiers: modifiers2, measurements: measurements2 } = jscad3;
12319
12851
  var generalize2 = modifiers2.generalize;
12320
12852
  var { rectangle: rectangle2, roundedRectangle: roundedRectangle2, polygon: polygon2 } = primitives2;
12321
- var profile2 = (shape39, height10) => extrusions2.extrudeLinear({ height: height10 }, shape39);
12853
+ var profile2 = (shape44, height10) => extrusions2.extrudeLinear({ height: height10 }, shape44);
12322
12854
  function filletProfile2(points, radii, width10, height10) {
12323
12855
  const outline = [];
12324
12856
  for (let i = 0; i < points.length; i++) {
@@ -12424,14 +12956,14 @@ function ChannelBar({ color = "#929da9", ...props }) {
12424
12956
  }
12425
12957
 
12426
12958
  // lib/models/channelbar/register.tsx
12427
- var model50 = defineModelRenderer({
12959
+ var model55 = defineModelRenderer({
12428
12960
  name: "channelbar",
12429
12961
  schema: channelBarModelDefinitionSchema,
12430
12962
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ChannelBar, { ...props }),
12431
12963
  pads: "none"
12432
12964
  });
12433
- function register50(registry2) {
12434
- registry2.register(model50);
12965
+ function register55(registry2) {
12966
+ registry2.register(model55);
12435
12967
  }
12436
12968
 
12437
12969
  // lib/models/clampingshaftcollar/mesh.ts
@@ -12459,9 +12991,9 @@ function createAnnularSleeve({
12459
12991
  outerRadius,
12460
12992
  boreARadius,
12461
12993
  boreBRadius = boreARadius,
12462
- length: length26,
12994
+ length: length29,
12463
12995
  chamfer,
12464
- stepZ = length26 / 2
12996
+ stepZ = length29 / 2
12465
12997
  }) {
12466
12998
  const halfAngle = Math.PI / bodySegments;
12467
12999
  const cosine = Math.cos(halfAngle);
@@ -12472,10 +13004,10 @@ function createAnnularSleeve({
12472
13004
  const raw = [
12473
13005
  [0, outerRadius - chamfer, false],
12474
13006
  [chamfer, outerRadius, false],
12475
- [length26 - chamfer, outerRadius, false],
12476
- [length26, outerRadius - chamfer, false],
12477
- [length26, boreBRadius + chamfer, true],
12478
- [length26 - chamfer, boreBRadius, true],
13007
+ [length29 - chamfer, outerRadius, false],
13008
+ [length29, outerRadius - chamfer, false],
13009
+ [length29, boreBRadius + chamfer, true],
13010
+ [length29 - chamfer, boreBRadius, true],
12479
13011
  [stepZ, boreBRadius, true],
12480
13012
  [stepZ, boreARadius, true],
12481
13013
  [chamfer, boreARadius, true],
@@ -12725,14 +13257,14 @@ function ClampingShaftCollar({
12725
13257
  }
12726
13258
 
12727
13259
  // lib/models/clampingshaftcollar/register.tsx
12728
- var model51 = defineModelRenderer({
13260
+ var model56 = defineModelRenderer({
12729
13261
  name: "clampingshaftcollar",
12730
13262
  schema: clampingShaftCollarModelDefinitionSchema,
12731
13263
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ClampingShaftCollar, { ...props }),
12732
13264
  pads: "none"
12733
13265
  });
12734
- function register51(registry2) {
12735
- registry2.register(model51);
13266
+ function register56(registry2) {
13267
+ registry2.register(model56);
12736
13268
  }
12737
13269
 
12738
13270
  // lib/mechanical/clip-mesh-to-z-range.ts
@@ -12928,14 +13460,14 @@ function CompressionSpring({
12928
13460
  }
12929
13461
 
12930
13462
  // lib/models/compressionspring/register.tsx
12931
- var model52 = defineModelRenderer({
13463
+ var model57 = defineModelRenderer({
12932
13464
  name: "compressionspring",
12933
13465
  schema: compressionSpringModelDefinitionSchema,
12934
13466
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(CompressionSpring, { ...props }),
12935
13467
  pads: "none"
12936
13468
  });
12937
- function register52(registry2) {
12938
- registry2.register(model52);
13469
+ function register57(registry2) {
13470
+ registry2.register(model57);
12939
13471
  }
12940
13472
 
12941
13473
  // lib/models/dowelpin/mesh.ts
@@ -12986,14 +13518,14 @@ function DowelPin({ color = "#929da9", ...props }) {
12986
13518
  }
12987
13519
 
12988
13520
  // lib/models/dowelpin/register.tsx
12989
- var model53 = defineModelRenderer({
13521
+ var model58 = defineModelRenderer({
12990
13522
  name: "dowelpin",
12991
13523
  schema: dowelPinModelDefinitionSchema,
12992
13524
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(DowelPin, { ...props }),
12993
13525
  pads: "none"
12994
13526
  });
12995
- function register53(registry2) {
12996
- registry2.register(model53);
13527
+ function register58(registry2) {
13528
+ registry2.register(model58);
12997
13529
  }
12998
13530
 
12999
13531
  // lib/models/femalestandoff/mesh.ts
@@ -13095,14 +13627,14 @@ function FemaleStandoff({
13095
13627
  }
13096
13628
 
13097
13629
  // lib/models/femalestandoff/register.tsx
13098
- var model54 = defineModelRenderer({
13630
+ var model59 = defineModelRenderer({
13099
13631
  name: "femalestandoff",
13100
13632
  schema: femaleStandoffModelDefinitionSchema,
13101
13633
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FemaleStandoff, { ...props }),
13102
13634
  pads: "none"
13103
13635
  });
13104
- function register54(registry2) {
13105
- registry2.register(model54);
13636
+ function register59(registry2) {
13637
+ registry2.register(model59);
13106
13638
  }
13107
13639
 
13108
13640
  // lib/models/flangebolt/mesh.ts
@@ -13249,14 +13781,14 @@ function FlangeBolt({ color = "#737e8f", ...props }) {
13249
13781
  }
13250
13782
 
13251
13783
  // lib/models/flangebolt/register.tsx
13252
- var model55 = defineModelRenderer({
13784
+ var model60 = defineModelRenderer({
13253
13785
  name: "flangebolt",
13254
13786
  schema: flangeboltModelDefinitionSchema,
13255
13787
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlangeBolt, { ...props }),
13256
13788
  pads: "none"
13257
13789
  });
13258
- function register55(registry2) {
13259
- registry2.register(model55);
13790
+ function register60(registry2) {
13791
+ registry2.register(model60);
13260
13792
  }
13261
13793
 
13262
13794
  // lib/models/flangedbushing/mesh.ts
@@ -13305,14 +13837,14 @@ function FlangedBushing({
13305
13837
  }
13306
13838
 
13307
13839
  // lib/models/flangedbushing/register.tsx
13308
- var model56 = defineModelRenderer({
13840
+ var model61 = defineModelRenderer({
13309
13841
  name: "flangedbushing",
13310
13842
  schema: flangedBushingModelDefinitionSchema,
13311
13843
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlangedBushing, { ...props }),
13312
13844
  pads: "none"
13313
13845
  });
13314
- function register56(registry2) {
13315
- registry2.register(model56);
13846
+ function register61(registry2) {
13847
+ registry2.register(model61);
13316
13848
  }
13317
13849
 
13318
13850
  // lib/models/flangenut/mesh.ts
@@ -13418,14 +13950,14 @@ function FlangeNut({ color = "#737e8f", ...props }) {
13418
13950
  }
13419
13951
 
13420
13952
  // lib/models/flangenut/register.tsx
13421
- var model57 = defineModelRenderer({
13953
+ var model62 = defineModelRenderer({
13422
13954
  name: "flangenut",
13423
13955
  schema: flangeNutModelDefinitionSchema,
13424
13956
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlangeNut, { ...props }),
13425
13957
  pads: "none"
13426
13958
  });
13427
- function register57(registry2) {
13428
- registry2.register(model57);
13959
+ function register62(registry2) {
13960
+ registry2.register(model62);
13429
13961
  }
13430
13962
 
13431
13963
  // lib/models/flatheadscrew/mesh.ts
@@ -13552,14 +14084,14 @@ function FlatHeadScrew({
13552
14084
  }
13553
14085
 
13554
14086
  // lib/models/flatheadscrew/register.tsx
13555
- var model58 = defineModelRenderer({
14087
+ var model63 = defineModelRenderer({
13556
14088
  name: "flatheadscrew",
13557
14089
  schema: flatHeadScrewModelDefinitionSchema,
13558
14090
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlatHeadScrew, { ...props }),
13559
14091
  pads: "none"
13560
14092
  });
13561
- function register58(registry2) {
13562
- registry2.register(model58);
14093
+ function register63(registry2) {
14094
+ registry2.register(model63);
13563
14095
  }
13564
14096
 
13565
14097
  // lib/Screen.tsx
@@ -14234,14 +14766,14 @@ var FlexScreen = (props) => {
14234
14766
  };
14235
14767
 
14236
14768
  // lib/models/flexscreen/register.tsx
14237
- var model59 = defineModelRenderer({
14769
+ var model64 = defineModelRenderer({
14238
14770
  name: "flexscreen",
14239
14771
  schema: flexScreenModelDefinitionSchema,
14240
14772
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlexScreen, { ...props }),
14241
14773
  pads: "footprinter"
14242
14774
  });
14243
- function register59(registry2) {
14244
- registry2.register(model59);
14775
+ function register64(registry2) {
14776
+ registry2.register(model64);
14245
14777
  }
14246
14778
 
14247
14779
  // lib/models/heatsetinsert/mesh.ts
@@ -14326,14 +14858,14 @@ function HeatSetInsert({
14326
14858
  }
14327
14859
 
14328
14860
  // lib/models/heatsetinsert/register.tsx
14329
- var model60 = defineModelRenderer({
14861
+ var model65 = defineModelRenderer({
14330
14862
  name: "heatsetinsert",
14331
14863
  schema: heatSetInsertModelDefinitionSchema,
14332
14864
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HeatSetInsert, { ...props }),
14333
14865
  pads: "none"
14334
14866
  });
14335
- function register60(registry2) {
14336
- registry2.register(model60);
14867
+ function register65(registry2) {
14868
+ registry2.register(model65);
14337
14869
  }
14338
14870
 
14339
14871
  // lib/mechanical/spur-gear-mesh.ts
@@ -14526,14 +15058,14 @@ function HelicalGear({ color = "#737e8f", ...props }) {
14526
15058
  }
14527
15059
 
14528
15060
  // lib/models/helicalgear/register.tsx
14529
- var model61 = defineModelRenderer({
15061
+ var model66 = defineModelRenderer({
14530
15062
  name: "helicalgear",
14531
15063
  schema: helicalGearModelDefinitionSchema,
14532
15064
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HelicalGear, { ...props }),
14533
15065
  pads: "none"
14534
15066
  });
14535
- function register61(registry2) {
14536
- registry2.register(model61);
15067
+ function register66(registry2) {
15068
+ registry2.register(model66);
14537
15069
  }
14538
15070
 
14539
15071
  // lib/models/hexbolt/mesh.ts
@@ -14668,14 +15200,14 @@ function HexBolt({ color = "#737e8f", ...props }) {
14668
15200
  }
14669
15201
 
14670
15202
  // lib/models/hexbolt/register.tsx
14671
- var model62 = defineModelRenderer({
15203
+ var model67 = defineModelRenderer({
14672
15204
  name: "hexbolt",
14673
15205
  schema: hexBoltModelDefinitionSchema,
14674
15206
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexBolt, { ...props }),
14675
15207
  pads: "none"
14676
15208
  });
14677
- function register62(registry2) {
14678
- registry2.register(model62);
15209
+ function register67(registry2) {
15210
+ registry2.register(model67);
14679
15211
  }
14680
15212
 
14681
15213
  // lib/models/hexnut/mesh.ts
@@ -14794,14 +15326,14 @@ function HexNut({ color = "#737e8f", ...props }) {
14794
15326
  }
14795
15327
 
14796
15328
  // lib/models/hexnut/register.tsx
14797
- var model63 = defineModelRenderer({
15329
+ var model68 = defineModelRenderer({
14798
15330
  name: "hexnut",
14799
15331
  schema: hexNutModelDefinitionSchema,
14800
15332
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexNut, { ...props }),
14801
15333
  pads: "none"
14802
15334
  });
14803
- function register63(registry2) {
14804
- registry2.register(model63);
15335
+ function register68(registry2) {
15336
+ registry2.register(model68);
14805
15337
  }
14806
15338
 
14807
15339
  // lib/mechanical/hex-socket-bolt-mesh.ts
@@ -14815,9 +15347,9 @@ var createHexSocketBoltMesh = (input) => {
14815
15347
  socketWidth,
14816
15348
  socketDepth
14817
15349
  } = hexSocketBoltDimensions[props.metricSize];
14818
- const { length: length26, showThreads } = props;
15350
+ const { length: length29, showThreads } = props;
14819
15351
  const segments = 96;
14820
- const steps = showThreads ? Math.max(2, Math.ceil(length26 / pitch * 24)) : 2;
15352
+ const steps = showThreads ? Math.max(2, Math.ceil(length29 / pitch * 24)) : 2;
14821
15353
  if (steps > 24e3)
14822
15354
  throw new Error(
14823
15355
  "Bolt length exceeds mesh resolution limit (1000 thread turns)"
@@ -14827,7 +15359,7 @@ var createHexSocketBoltMesh = (input) => {
14827
15359
  const radius = diameter / 2;
14828
15360
  const depth = pitch * 0.61343;
14829
15361
  const bevel = Math.min(0.2, headHeight * 0.08);
14830
- const tipBevel = Math.min(pitch * 0.6, length26 / 3);
15362
+ const tipBevel = Math.min(pitch * 0.6, length29 / 3);
14831
15363
  const ring = (z, radiusAt) => {
14832
15364
  const start = positions.length / 3;
14833
15365
  for (let i = 0; i < segments; i++) {
@@ -14855,8 +15387,8 @@ var createHexSocketBoltMesh = (input) => {
14855
15387
  let previous = -1;
14856
15388
  const shaftLevels = showThreads ? Array.from(
14857
15389
  { length: steps + 1 },
14858
- (_, step) => -length26 + length26 * step / steps
14859
- ) : [-length26, -length26 + tipBevel, 0];
15390
+ (_, step) => -length29 + length29 * step / steps
15391
+ ) : [-length29, -length29 + tipBevel, 0];
14860
15392
  for (const z of shaftLevels) {
14861
15393
  const current = ring(z, (angle) => {
14862
15394
  const phase = ((z / pitch - angle / (2 * Math.PI)) % 1 + 1) % 1;
@@ -14867,10 +15399,10 @@ var createHexSocketBoltMesh = (input) => {
14867
15399
  );
14868
15400
  const endRamp = Math.min(
14869
15401
  1,
14870
- (z + length26) / tipBevel,
14871
- -z / Math.min(pitch / 2, length26 / 3)
15402
+ (z + length29) / tipBevel,
15403
+ -z / Math.min(pitch / 2, length29 / 3)
14872
15404
  );
14873
- const tipCut = tipBevel * Math.max(0, 1 - (z + length26) / tipBevel);
15405
+ const tipCut = tipBevel * Math.max(0, 1 - (z + length29) / tipBevel);
14874
15406
  return radius - (showThreads ? groove * endRamp : 0) - tipCut;
14875
15407
  });
14876
15408
  if (previous < 0) cap2(current, z, false);
@@ -14906,14 +15438,14 @@ function HexSocketBolt({
14906
15438
  }
14907
15439
 
14908
15440
  // lib/models/hexsocketbolt/register.tsx
14909
- var model64 = defineModelRenderer({
15441
+ var model69 = defineModelRenderer({
14910
15442
  name: "hexsocketbolt",
14911
15443
  schema: hexSocketBoltModelDefinitionSchema,
14912
15444
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexSocketBolt, { ...props }),
14913
15445
  pads: "none"
14914
15446
  });
14915
- function register64(registry2) {
14916
- registry2.register(model64);
15447
+ function register69(registry2) {
15448
+ registry2.register(model69);
14917
15449
  }
14918
15450
 
14919
15451
  // lib/models/hollowpositioningarmtube/mesh.ts
@@ -15026,14 +15558,14 @@ function HollowPositioningArmTube({
15026
15558
  }
15027
15559
 
15028
15560
  // lib/models/hollowpositioningarmtube/register.tsx
15029
- var model65 = defineModelRenderer({
15561
+ var model70 = defineModelRenderer({
15030
15562
  name: "hollowpositioningarmtube",
15031
15563
  schema: hollowPositioningArmTubeModelDefinitionSchema,
15032
15564
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HollowPositioningArmTube, { ...props }),
15033
15565
  pads: "none"
15034
15566
  });
15035
- function register65(registry2) {
15036
- registry2.register(model65);
15567
+ function register70(registry2) {
15568
+ registry2.register(model70);
15037
15569
  }
15038
15570
 
15039
15571
  // lib/models/malefemalestandoff/mesh.ts
@@ -15165,14 +15697,14 @@ function MaleFemaleStandoff({
15165
15697
  }
15166
15698
 
15167
15699
  // lib/models/malefemalestandoff/register.tsx
15168
- var model66 = defineModelRenderer({
15700
+ var model71 = defineModelRenderer({
15169
15701
  name: "malefemalestandoff",
15170
15702
  schema: maleFemaleStandoffModelDefinitionSchema,
15171
15703
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(MaleFemaleStandoff, { ...props }),
15172
15704
  pads: "none"
15173
15705
  });
15174
- function register66(registry2) {
15175
- registry2.register(model66);
15706
+ function register71(registry2) {
15707
+ registry2.register(model71);
15176
15708
  }
15177
15709
 
15178
15710
  // lib/NemaMotor.tsx
@@ -15431,14 +15963,14 @@ var NEMA17 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 17
15431
15963
  var NEMA23 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 23 });
15432
15964
 
15433
15965
  // lib/models/nema/register.tsx
15434
- var model67 = defineModelRenderer({
15966
+ var model72 = defineModelRenderer({
15435
15967
  name: "nema",
15436
15968
  schema: nemaMotorModelDefinitionSchema,
15437
15969
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(NemaMotor, { ...props }),
15438
15970
  pads: "none"
15439
15971
  });
15440
- function register67(registry2) {
15441
- registry2.register(model67);
15972
+ function register72(registry2) {
15973
+ registry2.register(model72);
15442
15974
  }
15443
15975
 
15444
15976
  // lib/models/nylonlocknut/mesh.ts
@@ -15574,14 +16106,14 @@ function NylonLockNut({
15574
16106
  }
15575
16107
 
15576
16108
  // lib/models/nylonlocknut/register.tsx
15577
- var model68 = defineModelRenderer({
16109
+ var model73 = defineModelRenderer({
15578
16110
  name: "nylonlocknut",
15579
16111
  schema: nylonLockNutModelDefinitionSchema,
15580
16112
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(NylonLockNut, { ...props }),
15581
16113
  pads: "none"
15582
16114
  });
15583
- function register68(registry2) {
15584
- registry2.register(model68);
16115
+ function register73(registry2) {
16116
+ registry2.register(model73);
15585
16117
  }
15586
16118
 
15587
16119
  // lib/models/panscrew/mesh.ts
@@ -15787,15 +16319,15 @@ function PanScrew({ color = "#737e8f", ...props }) {
15787
16319
  }
15788
16320
 
15789
16321
  // lib/models/panscrew/register.tsx
15790
- var model69 = defineModelRenderer({
16322
+ var model74 = defineModelRenderer({
15791
16323
  name: "panscrew",
15792
16324
  schema: panScrewModelDefinitionSchema,
15793
16325
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PanScrew, { ...props }),
15794
16326
  pads: "none"
15795
16327
  });
15796
- function register69(registry2) {
15797
- registry2.register(model69);
15798
- }
16328
+ function register74(registry2) {
16329
+ registry2.register(model74);
16330
+ }
15799
16331
 
15800
16332
  // lib/models/perforatedsheet/geometry.ts
15801
16333
  import jscad8 from "@jscad/modeling";
@@ -15810,7 +16342,7 @@ var {
15810
16342
  var generalize4 = modifiers3.generalize;
15811
16343
  var { subtract } = booleans;
15812
16344
  var { rectangle: rectangle3, roundedRectangle: roundedRectangle3, circle: circle2 } = primitives3;
15813
- var profile3 = (shape39, height10) => extrusions3.extrudeLinear({ height: height10 }, shape39);
16345
+ var profile3 = (shape44, height10) => extrusions3.extrudeLinear({ height: height10 }, shape44);
15814
16346
  function perforated(p) {
15815
16347
  const holes = [];
15816
16348
  const rows = Math.floor((p.width - 2 * p.edgeY) / p.pitchY + 1 + 1e-10);
@@ -15880,14 +16412,14 @@ function PerforatedSheet({
15880
16412
  }
15881
16413
 
15882
16414
  // lib/models/perforatedsheet/register.tsx
15883
- var model70 = defineModelRenderer({
16415
+ var model75 = defineModelRenderer({
15884
16416
  name: "perforatedsheet",
15885
16417
  schema: perforatedSheetModelDefinitionSchema,
15886
16418
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PerforatedSheet, { ...props }),
15887
16419
  pads: "none"
15888
16420
  });
15889
- function register70(registry2) {
15890
- registry2.register(model70);
16421
+ function register75(registry2) {
16422
+ registry2.register(model75);
15891
16423
  }
15892
16424
 
15893
16425
  // lib/models/plainbushing/mesh.ts
@@ -15943,14 +16475,14 @@ function PlainBushing({
15943
16475
  }
15944
16476
 
15945
16477
  // lib/models/plainbushing/register.tsx
15946
- var model71 = defineModelRenderer({
16478
+ var model76 = defineModelRenderer({
15947
16479
  name: "plainbushing",
15948
16480
  schema: plainBushingModelDefinitionSchema,
15949
16481
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PlainBushing, { ...props }),
15950
16482
  pads: "none"
15951
16483
  });
15952
- function register71(registry2) {
15953
- registry2.register(model71);
16484
+ function register76(registry2) {
16485
+ registry2.register(model76);
15954
16486
  }
15955
16487
 
15956
16488
  // lib/models/pushfitplug/geometry.ts
@@ -16015,14 +16547,14 @@ function PushFitPlug({ color = "#929da9", ...props }) {
16015
16547
  }
16016
16548
 
16017
16549
  // lib/models/pushfitplug/register.tsx
16018
- var model72 = defineModelRenderer({
16550
+ var model77 = defineModelRenderer({
16019
16551
  name: "pushfitplug",
16020
16552
  schema: pushFitPlugModelDefinitionSchema,
16021
16553
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PushFitPlug, { ...props }),
16022
16554
  pads: "none"
16023
16555
  });
16024
- function register72(registry2) {
16025
- registry2.register(model72);
16556
+ function register77(registry2) {
16557
+ registry2.register(model77);
16026
16558
  }
16027
16559
 
16028
16560
  // lib/models/rectangularbar/geometry.ts
@@ -16030,7 +16562,7 @@ import jscad10 from "@jscad/modeling";
16030
16562
  var { primitives: primitives5, extrusions: extrusions5, geometries: geometries5, modifiers: modifiers5, measurements: measurements5 } = jscad10;
16031
16563
  var generalize6 = modifiers5.generalize;
16032
16564
  var { rectangle: rectangle5, roundedRectangle: roundedRectangle5 } = primitives5;
16033
- var profile4 = (shape39, height10) => extrusions5.extrudeLinear({ height: height10 }, shape39);
16565
+ var profile4 = (shape44, height10) => extrusions5.extrudeLinear({ height: height10 }, shape44);
16034
16566
  var roundedRect = (width10, height10, radius) => radius ? roundedRectangle5({
16035
16567
  size: [width10, height10],
16036
16568
  roundRadius: radius,
@@ -16084,14 +16616,123 @@ function RectangularBar({
16084
16616
  }
16085
16617
 
16086
16618
  // lib/models/rectangularbar/register.tsx
16087
- var model73 = defineModelRenderer({
16619
+ var model78 = defineModelRenderer({
16088
16620
  name: "rectangularbar",
16089
16621
  schema: rectangularBarModelDefinitionSchema,
16090
16622
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(RectangularBar, { ...props }),
16091
16623
  pads: "none"
16092
16624
  });
16093
- function register73(registry2) {
16094
- registry2.register(model73);
16625
+ function register78(registry2) {
16626
+ registry2.register(model78);
16627
+ }
16628
+
16629
+ // lib/models/rectangulargasket/geometry.ts
16630
+ function retainCapSeams(mesh, tolerance) {
16631
+ const positions = [...mesh.positions], indices = [];
16632
+ const count = mesh.positions.length / 3;
16633
+ for (let i = 0; i < mesh.indices.length; i += 3) {
16634
+ const ids = mesh.indices.slice(i, i + 3), boundary = [];
16635
+ for (let side = 0; side < 3; side++) {
16636
+ const a = ids[side], b = ids[(side + 1) % 3];
16637
+ const origin = positions.slice(a * 3, a * 3 + 3);
16638
+ const delta = positions.slice(b * 3, b * 3 + 3).map((x, axis) => x - origin[axis]);
16639
+ const lengthSquared = delta.reduce((sum, x) => sum + x * x, 0);
16640
+ const length29 = Math.sqrt(lengthSquared);
16641
+ const intermediate = [];
16642
+ for (let id = 0; id < count; id++) {
16643
+ if (id === a || id === b) continue;
16644
+ const point = positions.slice(id * 3, id * 3 + 3);
16645
+ const t = point.reduce(
16646
+ (sum, x, axis) => sum + (x - origin[axis]) * delta[axis],
16647
+ 0
16648
+ ) / lengthSquared;
16649
+ if (t * length29 <= tolerance || (1 - t) * length29 <= tolerance) continue;
16650
+ if (Math.hypot(
16651
+ ...point.map((x, axis) => x - origin[axis] - t * delta[axis])
16652
+ ) <= tolerance)
16653
+ intermediate.push({ id, t });
16654
+ }
16655
+ boundary.push(
16656
+ a,
16657
+ ...intermediate.sort((a2, b2) => a2.t - b2.t).map((point) => point.id)
16658
+ );
16659
+ }
16660
+ if (boundary.length === 3) indices.push(...boundary);
16661
+ else {
16662
+ const center = positions.length / 3;
16663
+ for (let axis = 0; axis < 3; axis++)
16664
+ positions.push(
16665
+ ids.reduce((sum, id) => sum + mesh.positions[id * 3 + axis], 0) / 3
16666
+ );
16667
+ for (let side = 0; side < boundary.length; side++)
16668
+ indices.push(
16669
+ center,
16670
+ boundary[side],
16671
+ boundary[(side + 1) % boundary.length]
16672
+ );
16673
+ }
16674
+ }
16675
+ return { positions, indices };
16676
+ }
16677
+ function createRectangularGasketMesh(input) {
16678
+ const p = rectangularGasketModelPropsSchema.parse(input), d = getRectangularGasketDimensions(p);
16679
+ if (Math.min(p.thickness, p.border, d.innerWidth, d.innerHeight) <= Math.max(...d.size) * 1e-10)
16680
+ throw new Error(
16681
+ "rectangulargasket dimensions exceed mesh resolution limits"
16682
+ );
16683
+ const rounded = (width10, height10, radius) => {
16684
+ if (radius === 0)
16685
+ return [
16686
+ [-width10 / 2, -height10 / 2],
16687
+ [width10 / 2, -height10 / 2],
16688
+ [width10 / 2, height10 / 2],
16689
+ [-width10 / 2, height10 / 2]
16690
+ ];
16691
+ const points = [];
16692
+ for (let corner = 0; corner < 4; corner++) {
16693
+ const x = (corner === 0 || corner === 3 ? 1 : -1) * (width10 / 2 - radius);
16694
+ const y = (corner < 2 ? 1 : -1) * (height10 / 2 - radius);
16695
+ for (let step = 0; step <= 32; step++) {
16696
+ const angle = corner * Math.PI / 2 + step * Math.PI / 64;
16697
+ points.push([
16698
+ x + radius * Math.cos(angle),
16699
+ y + radius * Math.sin(angle)
16700
+ ]);
16701
+ }
16702
+ }
16703
+ return points;
16704
+ };
16705
+ return retainCapSeams(
16706
+ extrudePlanarProfile({
16707
+ outer: rounded(p.width, p.height, p.cornerRadius),
16708
+ holes: [rounded(d.innerWidth, d.innerHeight, d.innerCornerRadius)],
16709
+ start: d.bottomZ,
16710
+ end: d.topZ
16711
+ }),
16712
+ Math.max(...d.size) * 1e-10
16713
+ );
16714
+ }
16715
+ function createRectangularGasketGeom(input) {
16716
+ return indexedMeshToGeom3(createRectangularGasketMesh(input));
16717
+ }
16718
+
16719
+ // lib/models/rectangulargasket/RectangularGasket.tsx
16720
+ function RectangularGasket({
16721
+ color = "#394553",
16722
+ ...props
16723
+ }) {
16724
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createRectangularGasketGeom(props) }) });
16725
+ }
16726
+
16727
+ // lib/models/rectangulargasket/register.tsx
16728
+ var model79 = defineModelRenderer({
16729
+ name: "rectangulargasket",
16730
+ schema: rectangularGasketModelDefinitionSchema,
16731
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(RectangularGasket, { ...props }),
16732
+ pads: "none"
16733
+ });
16734
+ function register79(registry2) {
16735
+ registry2.register(model79);
16095
16736
  }
16096
16737
 
16097
16738
  // lib/models/rectangulartube/geometry.ts
@@ -16107,7 +16748,7 @@ var {
16107
16748
  var generalize7 = modifiers6.generalize;
16108
16749
  var { subtract: subtract2 } = booleans2;
16109
16750
  var { rectangle: rectangle6, roundedRectangle: roundedRectangle6 } = primitives6;
16110
- var profile5 = (shape39, height10) => extrusions6.extrudeLinear({ height: height10 }, shape39);
16751
+ var profile5 = (shape44, height10) => extrusions6.extrudeLinear({ height: height10 }, shape44);
16111
16752
  var roundedRect2 = (width10, height10, radius) => radius ? roundedRectangle6({
16112
16753
  size: [width10, height10],
16113
16754
  roundRadius: radius,
@@ -16171,14 +16812,14 @@ function RectangularTube({
16171
16812
  }
16172
16813
 
16173
16814
  // lib/models/rectangulartube/register.tsx
16174
- var model74 = defineModelRenderer({
16815
+ var model80 = defineModelRenderer({
16175
16816
  name: "rectangulartube",
16176
16817
  schema: rectangularTubeModelDefinitionSchema,
16177
16818
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(RectangularTube, { ...props }),
16178
16819
  pads: "none"
16179
16820
  });
16180
- function register74(registry2) {
16181
- registry2.register(model74);
16821
+ function register80(registry2) {
16822
+ registry2.register(model80);
16182
16823
  }
16183
16824
 
16184
16825
  // lib/models/rigidcoupler/mesh.ts
@@ -16215,14 +16856,14 @@ function RigidCoupler({
16215
16856
  }
16216
16857
 
16217
16858
  // lib/models/rigidcoupler/register.tsx
16218
- var model75 = defineModelRenderer({
16859
+ var model81 = defineModelRenderer({
16219
16860
  name: "rigidcoupler",
16220
16861
  schema: rigidCouplerModelDefinitionSchema,
16221
16862
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(RigidCoupler, { ...props }),
16222
16863
  pads: "none"
16223
16864
  });
16224
- function register75(registry2) {
16225
- registry2.register(model75);
16865
+ function register81(registry2) {
16866
+ registry2.register(model81);
16226
16867
  }
16227
16868
 
16228
16869
  // lib/models/setscrew/mesh.ts
@@ -16337,14 +16978,14 @@ function SetScrew({ color = "#737e8f", ...props }) {
16337
16978
  }
16338
16979
 
16339
16980
  // lib/models/setscrew/register.tsx
16340
- var model76 = defineModelRenderer({
16981
+ var model82 = defineModelRenderer({
16341
16982
  name: "setscrew",
16342
16983
  schema: setscrewModelDefinitionSchema,
16343
16984
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SetScrew, { ...props }),
16344
16985
  pads: "none"
16345
16986
  });
16346
- function register76(registry2) {
16347
- registry2.register(model76);
16987
+ function register82(registry2) {
16988
+ registry2.register(model82);
16348
16989
  }
16349
16990
 
16350
16991
  // lib/models/shaftcollar/mesh.ts
@@ -16376,14 +17017,14 @@ function ShaftCollar({ color = "#737e8f", ...props }) {
16376
17017
  }
16377
17018
 
16378
17019
  // lib/models/shaftcollar/register.tsx
16379
- var model77 = defineModelRenderer({
17020
+ var model83 = defineModelRenderer({
16380
17021
  name: "shaftcollar",
16381
17022
  schema: shaftCollarModelDefinitionSchema,
16382
17023
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ShaftCollar, { ...props }),
16383
17024
  pads: "none"
16384
17025
  });
16385
- function register77(registry2) {
16386
- registry2.register(model77);
17026
+ function register83(registry2) {
17027
+ registry2.register(model83);
16387
17028
  }
16388
17029
 
16389
17030
  // lib/mechanical/sheet-metal-mesh.ts
@@ -16428,7 +17069,7 @@ function createSheetMetalMesh(input) {
16428
17069
  throw new Error(`No ${hole.panel} panel on ${profile6}`);
16429
17070
  }
16430
17071
  for (const panel of panels) {
16431
- const length26 = panel === "base" ? baseLength : flangeHeight;
17072
+ const length29 = panel === "base" ? baseLength : flangeHeight;
16432
17073
  const holes = props.holes.filter((hole) => hole.panel === panel).map(holeOutline);
16433
17074
  const bounds = holes.map((outline2) => ({
16434
17075
  minU: Math.min(...outline2.map((p) => p.u)),
@@ -16437,17 +17078,17 @@ function createSheetMetalMesh(input) {
16437
17078
  maxV: Math.max(...outline2.map((p) => p.v))
16438
17079
  }));
16439
17080
  for (const [i, box] of bounds.entries()) {
16440
- if (box.minU <= -length26 / 2 || box.maxU >= length26 / 2 || box.minV <= -width10 / 2 || box.maxV >= width10 / 2)
17081
+ if (box.minU <= -length29 / 2 || box.maxU >= length29 / 2 || box.minV <= -width10 / 2 || box.maxV >= width10 / 2)
16441
17082
  throw new Error(`Hole crosses ${panel} panel edge or bend tangent`);
16442
17083
  for (const previous of bounds.slice(0, i))
16443
17084
  if (box.minU <= previous.maxU && box.maxU >= previous.minU && box.minV <= previous.maxV && box.maxV >= previous.minV)
16444
17085
  throw new Error("Hole bounding boxes must not overlap");
16445
17086
  }
16446
17087
  const outline = [
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 }
17088
+ { u: -length29 / 2, v: -width10 / 2 },
17089
+ { u: length29 / 2, v: -width10 / 2 },
17090
+ { u: length29 / 2, v: width10 / 2 },
17091
+ { u: -length29 / 2, v: width10 / 2 }
16451
17092
  ];
16452
17093
  const loops = [outline, ...holes.map((hole) => [...hole].reverse())];
16453
17094
  const points = loops.flat();
@@ -16537,14 +17178,153 @@ function SheetMetal({ color = "#737e8f", ...props }) {
16537
17178
  }
16538
17179
 
16539
17180
  // lib/models/sheetmetal/register.tsx
16540
- var model78 = defineModelRenderer({
17181
+ var model84 = defineModelRenderer({
16541
17182
  name: "sheetmetal",
16542
17183
  schema: sheetMetalModelDefinitionSchema,
16543
17184
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SheetMetal, { ...props }),
16544
17185
  pads: "none"
16545
17186
  });
16546
- function register78(registry2) {
16547
- registry2.register(model78);
17187
+ function register84(registry2) {
17188
+ registry2.register(model84);
17189
+ }
17190
+
17191
+ // lib/models/slottedchannel/mesh.ts
17192
+ function quarterBend(radius, thickness) {
17193
+ const outer = radius + thickness;
17194
+ const center = outer;
17195
+ const points = [];
17196
+ for (let step = 0; step <= 48; step++) {
17197
+ const angle = Math.PI + step * Math.PI / 96;
17198
+ points.push(
17199
+ step === 0 ? [0, center] : step === 48 ? [center, 0] : [
17200
+ center + outer * Math.cos(angle),
17201
+ center + outer * Math.sin(angle)
17202
+ ]
17203
+ );
17204
+ }
17205
+ if (radius === 0) points.push([center, center]);
17206
+ else
17207
+ for (let step = 0; step <= 48; step++) {
17208
+ const angle = 3 * Math.PI / 2 - step * Math.PI / 96;
17209
+ points.push(
17210
+ step === 0 ? [center, thickness] : step === 48 ? [thickness, center] : [
17211
+ center + radius * Math.cos(angle),
17212
+ center + radius * Math.sin(angle)
17213
+ ]
17214
+ );
17215
+ }
17216
+ return points;
17217
+ }
17218
+ function obround(center, width10, length29) {
17219
+ if (length29 === width10) return circularProfile(0, center, width10 / 2);
17220
+ const r = width10 / 2, straight = (length29 - width10) / 2;
17221
+ const points = [];
17222
+ for (let step = 0; step <= 48; step++) {
17223
+ const angle = step * Math.PI / 48;
17224
+ points.push([r * Math.cos(angle), center + straight + r * Math.sin(angle)]);
17225
+ }
17226
+ for (let step = 0; step <= 48; step++) {
17227
+ const angle = Math.PI + step * Math.PI / 48;
17228
+ points.push([r * Math.cos(angle), center - straight + r * Math.sin(angle)]);
17229
+ }
17230
+ return points;
17231
+ }
17232
+ function createSlottedChannelMesh(input) {
17233
+ const p = slottedChannelModelPropsSchema.parse(input);
17234
+ const {
17235
+ width: w,
17236
+ height: h2,
17237
+ thickness: t,
17238
+ length: l,
17239
+ innerRadius: r,
17240
+ slotCount,
17241
+ slotWidth,
17242
+ slotLength,
17243
+ pitch,
17244
+ endOffset
17245
+ } = p;
17246
+ const tangent = r + t;
17247
+ const holes = Array.from(
17248
+ { length: slotCount },
17249
+ (_, i) => obround(endOffset + i * pitch, slotWidth, slotLength)
17250
+ );
17251
+ const leg = [
17252
+ [tangent, 0],
17253
+ [h2, 0],
17254
+ [h2, l],
17255
+ [tangent, l]
17256
+ ];
17257
+ const bend = quarterBend(r, t);
17258
+ const mesh = joinProfileMeshes([
17259
+ extrudePlanarProfile({
17260
+ outer: [
17261
+ [tangent, 0],
17262
+ [w - tangent, 0],
17263
+ [w - tangent, l],
17264
+ [tangent, l]
17265
+ ],
17266
+ holes: holes.map(
17267
+ (loop) => loop.map(([u, v]) => [u + w / 2, v])
17268
+ ),
17269
+ start: 0,
17270
+ end: t,
17271
+ project: (u, v, d) => [u, d, v],
17272
+ reverse: true,
17273
+ skipWall: (a, b) => a[0] === tangent && b[0] === tangent || a[0] === w - tangent && b[0] === w - tangent
17274
+ }),
17275
+ extrudePlanarProfile({
17276
+ outer: leg,
17277
+ start: 0,
17278
+ end: t,
17279
+ project: (u, v, d) => [d, u, v],
17280
+ skipWall: (a, b) => a[0] === tangent && b[0] === tangent
17281
+ }),
17282
+ extrudePlanarProfile({
17283
+ outer: leg,
17284
+ start: w - t,
17285
+ end: w,
17286
+ project: (u, v, d) => [d, u, v],
17287
+ skipWall: (a, b) => a[0] === tangent && b[0] === tangent
17288
+ }),
17289
+ extrudePlanarProfile({
17290
+ outer: bend,
17291
+ start: 0,
17292
+ end: l,
17293
+ skipWall: (a, b) => a[0] === tangent && b[0] === tangent || a[1] === tangent && b[1] === tangent
17294
+ }),
17295
+ extrudePlanarProfile({
17296
+ outer: bend.map(([u, v]) => [w - u, v]),
17297
+ start: 0,
17298
+ end: l,
17299
+ skipWall: (a, b) => a[0] === w - tangent && b[0] === w - tangent || a[1] === tangent && b[1] === tangent
17300
+ })
17301
+ ]);
17302
+ mesh.positions = mesh.positions.map(
17303
+ (value, index) => value - (index % 3 === 0 ? w / 2 : index % 3 === 1 ? h2 / 2 : 0)
17304
+ );
17305
+ return mesh;
17306
+ }
17307
+
17308
+ // lib/models/slottedchannel/SlottedChannel.tsx
17309
+ function createSlottedChannelGeom(input) {
17310
+ return indexedMeshToGeom3(createSlottedChannelMesh(input));
17311
+ }
17312
+ function SlottedChannel({
17313
+ color = "#8995a3",
17314
+ ...props
17315
+ }) {
17316
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createSlottedChannelGeom(props) }) });
17317
+ }
17318
+
17319
+ // lib/models/slottedchannel/register.tsx
17320
+ var model85 = defineModelRenderer({
17321
+ name: "slottedchannel",
17322
+ schema: slottedChannelModelDefinitionSchema,
17323
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SlottedChannel, { ...props }),
17324
+ pads: "none"
17325
+ });
17326
+ function register85(registry2) {
17327
+ registry2.register(model85);
16548
17328
  }
16549
17329
 
16550
17330
  // lib/models/spacer/mesh.ts
@@ -16567,14 +17347,103 @@ function Spacer({ color = "#a18450", ...props }) {
16567
17347
  }
16568
17348
 
16569
17349
  // lib/models/spacer/register.tsx
16570
- var model79 = defineModelRenderer({
17350
+ var model86 = defineModelRenderer({
16571
17351
  name: "spacer",
16572
17352
  schema: spacerModelDefinitionSchema,
16573
17353
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(Spacer, { ...props }),
16574
17354
  pads: "none"
16575
17355
  });
16576
- function register79(registry2) {
16577
- registry2.register(model79);
17356
+ function register86(registry2) {
17357
+ registry2.register(model86);
17358
+ }
17359
+
17360
+ // lib/models/splitgrommet/geometry.ts
17361
+ import earcut6 from "earcut";
17362
+ function createSplitGrommetMesh(input) {
17363
+ const p = splitGrommetModelPropsSchema.parse(input), d = getSplitGrommetDimensions(p);
17364
+ if (Math.min(
17365
+ d.flangeThickness,
17366
+ d.minimumWallThickness,
17367
+ p.grooveDepth,
17368
+ p.grooveWidth,
17369
+ p.splitWidth
17370
+ ) <= Math.max(...d.size) * 1e-10)
17371
+ throw new Error("splitgrommet dimensions exceed mesh resolution limits");
17372
+ const section = [
17373
+ [p.innerDiameter / 2, d.bottomZ],
17374
+ [p.outerDiameter / 2, d.bottomZ],
17375
+ [p.outerDiameter / 2, d.grooveStartZ],
17376
+ [d.grooveRootDiameter / 2, d.grooveStartZ],
17377
+ [d.grooveRootDiameter / 2, d.grooveEndZ],
17378
+ [p.outerDiameter / 2, d.grooveEndZ],
17379
+ [p.outerDiameter / 2, d.topZ],
17380
+ [p.innerDiameter / 2, d.topZ]
17381
+ ];
17382
+ const segments = 128, count = section.length;
17383
+ const positions = [], indices = [];
17384
+ for (let i = 0; i <= segments; i++)
17385
+ for (const [radius, z] of section) {
17386
+ const alpha = Math.asin(p.splitWidth / (2 * radius));
17387
+ const stops = [
17388
+ alpha,
17389
+ Math.PI / 2,
17390
+ Math.PI,
17391
+ 3 * Math.PI / 2,
17392
+ 2 * Math.PI - alpha
17393
+ ];
17394
+ const arc = Math.min(3, Math.floor(i / 32)), fraction = (i - arc * 32) / 32;
17395
+ const angle = stops[arc] + (stops[arc + 1] - stops[arc]) * fraction;
17396
+ positions.push(
17397
+ i === 0 || i === segments ? Math.sqrt(radius ** 2 - (p.splitWidth / 2) ** 2) : radius * Math.cos(angle),
17398
+ i === 0 ? d.slitMaxY : i === segments ? d.slitMinY : radius * Math.sin(angle),
17399
+ z
17400
+ );
17401
+ }
17402
+ for (let i = 0; i < segments; i++)
17403
+ for (let j = 0; j < count; j++) {
17404
+ const next = (j + 1) % count;
17405
+ const a = i * count + j, b = (i + 1) * count + j, c = (i + 1) * count + next, e = i * count + next;
17406
+ indices.push(a, b, c, a, c, e);
17407
+ }
17408
+ const slitSection = section.flatMap(([radius, z]) => [
17409
+ Math.sqrt(radius ** 2 - (p.splitWidth / 2) ** 2),
17410
+ z
17411
+ ]);
17412
+ const caps = earcut6(slitSection);
17413
+ for (let i = 0; i < caps.length; i += 3) {
17414
+ const a = caps[i], b = caps[i + 1], c = caps[i + 2];
17415
+ indices.push(
17416
+ a,
17417
+ b,
17418
+ c,
17419
+ segments * count + a,
17420
+ segments * count + c,
17421
+ segments * count + b
17422
+ );
17423
+ }
17424
+ return { positions, indices };
17425
+ }
17426
+ function createSplitGrommetGeom(input) {
17427
+ return indexedMeshToGeom3(createSplitGrommetMesh(input));
17428
+ }
17429
+
17430
+ // lib/models/splitgrommet/SplitGrommet.tsx
17431
+ function SplitGrommet({
17432
+ color = "#394553",
17433
+ ...props
17434
+ }) {
17435
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createSplitGrommetGeom(props) }) });
17436
+ }
17437
+
17438
+ // lib/models/splitgrommet/register.tsx
17439
+ var model87 = defineModelRenderer({
17440
+ name: "splitgrommet",
17441
+ schema: splitGrommetModelDefinitionSchema,
17442
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SplitGrommet, { ...props }),
17443
+ pads: "none"
17444
+ });
17445
+ function register87(registry2) {
17446
+ registry2.register(model87);
16578
17447
  }
16579
17448
 
16580
17449
  // lib/models/splitwasher/mesh.ts
@@ -16637,14 +17506,14 @@ function SplitWasher({ color = "#929ba6", ...props }) {
16637
17506
  }
16638
17507
 
16639
17508
  // lib/models/splitwasher/register.tsx
16640
- var model80 = defineModelRenderer({
17509
+ var model88 = defineModelRenderer({
16641
17510
  name: "splitwasher",
16642
17511
  schema: splitWasherModelDefinitionSchema,
16643
17512
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SplitWasher, { ...props }),
16644
17513
  pads: "none"
16645
17514
  });
16646
- function register80(registry2) {
16647
- registry2.register(model80);
17515
+ function register88(registry2) {
17516
+ registry2.register(model88);
16648
17517
  }
16649
17518
 
16650
17519
  // lib/SpurGear.tsx
@@ -16656,14 +17525,14 @@ function SpurGear({ color = "#737e8f", ...props }) {
16656
17525
  }
16657
17526
 
16658
17527
  // lib/models/spurgear/register.tsx
16659
- var model81 = defineModelRenderer({
17528
+ var model89 = defineModelRenderer({
16660
17529
  name: "spurgear",
16661
17530
  schema: spurGearModelDefinitionSchema,
16662
17531
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SpurGear, { ...props }),
16663
17532
  pads: "none"
16664
17533
  });
16665
- function register81(registry2) {
16666
- registry2.register(model81);
17534
+ function register89(registry2) {
17535
+ registry2.register(model89);
16667
17536
  }
16668
17537
 
16669
17538
  // lib/models/threadedrod/mesh.ts
@@ -16753,14 +17622,14 @@ function ThreadedRod({ color = "#737e8f", ...props }) {
16753
17622
  }
16754
17623
 
16755
17624
  // lib/models/threadedrod/register.tsx
16756
- var model82 = defineModelRenderer({
17625
+ var model90 = defineModelRenderer({
16757
17626
  name: "threadedrod",
16758
17627
  schema: threadedRodModelDefinitionSchema,
16759
17628
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ThreadedRod, { ...props }),
16760
17629
  pads: "none"
16761
17630
  });
16762
- function register82(registry2) {
16763
- registry2.register(model82);
17631
+ function register90(registry2) {
17632
+ registry2.register(model90);
16764
17633
  }
16765
17634
 
16766
17635
  // lib/models/torsionspring/mesh.ts
@@ -16849,20 +17718,110 @@ function TorsionSpring({
16849
17718
  }
16850
17719
 
16851
17720
  // lib/models/torsionspring/register.tsx
16852
- var model83 = defineModelRenderer({
17721
+ var model91 = defineModelRenderer({
16853
17722
  name: "torsionspring",
16854
17723
  schema: torsionSpringModelDefinitionSchema,
16855
17724
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TorsionSpring, { ...props }),
16856
17725
  pads: "none"
16857
17726
  });
16858
- function register83(registry2) {
16859
- registry2.register(model83);
17727
+ function register91(registry2) {
17728
+ registry2.register(model91);
17729
+ }
17730
+
17731
+ // lib/models/tslotcoverstrip/geometry.ts
17732
+ import jscad14 from "@jscad/modeling";
17733
+ var {
17734
+ primitives: primitives7,
17735
+ extrusions: extrusions7,
17736
+ booleans: booleans3,
17737
+ geometries: geometries7,
17738
+ modifiers: modifiers7,
17739
+ measurements: measurements7
17740
+ } = jscad14;
17741
+ var generalize8 = modifiers7.generalize;
17742
+ function createTSlotCoverStripGeom(input) {
17743
+ const p = tSlotCoverStripModelPropsSchema.parse(input);
17744
+ const w = p.width / 2;
17745
+ const s = p.stemWidth / 2;
17746
+ const b = p.barbWidth / 2;
17747
+ const tip = -p.stemHeight;
17748
+ const beadTop = tip + p.barbHeight;
17749
+ const outline = primitives7.polygon({
17750
+ points: [
17751
+ [-w, 0],
17752
+ [-s, 0],
17753
+ [-s, beadTop],
17754
+ [-b, beadTop],
17755
+ [-b, tip],
17756
+ [b, tip],
17757
+ [b, beadTop],
17758
+ [s, beadTop],
17759
+ [s, 0],
17760
+ [w, 0],
17761
+ [w, p.thickness],
17762
+ [-w, p.thickness]
17763
+ ]
17764
+ });
17765
+ return extrusions7.extrudeLinear({ height: p.length }, outline);
17766
+ }
17767
+ function createTSlotCoverStripMesh(input) {
17768
+ const geom = generalize8(
17769
+ { snap: false, triangulate: true },
17770
+ createTSlotCoverStripGeom(input)
17771
+ );
17772
+ const epsilon = Math.max(...measurements7.measureDimensions(geom)) * 1e-10;
17773
+ const positions = [];
17774
+ const indices = [];
17775
+ const lookup = /* @__PURE__ */ new Map();
17776
+ const vertex = (v) => {
17777
+ const key = v.map((x) => Math.round(x / epsilon)).join(",");
17778
+ let index = lookup.get(key);
17779
+ if (index === void 0) {
17780
+ index = positions.length / 3;
17781
+ positions.push(...v);
17782
+ lookup.set(key, index);
17783
+ }
17784
+ return index;
17785
+ };
17786
+ for (const poly of geometries7.geom3.toPolygons(geom)) {
17787
+ for (let i = 1; i < poly.vertices.length - 1; i++) {
17788
+ const a = poly.vertices[0], b = poly.vertices[i], c = poly.vertices[i + 1];
17789
+ const u = b.map((x, j) => x - a[j]), v = c.map((x, j) => x - a[j]);
17790
+ const area = Math.hypot(
17791
+ u[1] * v[2] - u[2] * v[1],
17792
+ u[2] * v[0] - u[0] * v[2],
17793
+ u[0] * v[1] - u[1] * v[0]
17794
+ );
17795
+ if (area > epsilon * epsilon)
17796
+ indices.push(vertex(a), vertex(b), vertex(c));
17797
+ }
17798
+ }
17799
+ return { positions, indices };
17800
+ }
17801
+
17802
+ // lib/models/tslotcoverstrip/TSlotCoverStrip.tsx
17803
+ function TSlotCoverStrip({
17804
+ color = "#465564",
17805
+ ...props
17806
+ }) {
17807
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createTSlotCoverStripGeom(props) }) });
17808
+ }
17809
+
17810
+ // lib/models/tslotcoverstrip/register.tsx
17811
+ var model92 = defineModelRenderer({
17812
+ name: "tslotcoverstrip",
17813
+ schema: tSlotCoverStripModelDefinitionSchema,
17814
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TSlotCoverStrip, { ...props }),
17815
+ pads: "none"
17816
+ });
17817
+ function register92(registry2) {
17818
+ registry2.register(model92);
16860
17819
  }
16861
17820
 
16862
17821
  // lib/models/tslotextrusion/mesh.ts
16863
17822
  function createTSlotExtrusionMesh(input = {}) {
16864
17823
  const props = tSlotExtrusionModelPropsSchema.parse(input);
16865
- const { width: width10, height: height10, length: length26, cornerRadius, lipThickness, pocketDepth } = props;
17824
+ const { width: width10, height: height10, length: length29, cornerRadius, lipThickness, pocketDepth } = props;
16866
17825
  const slot = props.slotWidth / 2;
16867
17826
  const pocket = props.pocketWidth / 2;
16868
17827
  const depth = lipThickness + pocketDepth;
@@ -16899,7 +17858,7 @@ function createTSlotExtrusionMesh(input = {}) {
16899
17858
  outer,
16900
17859
  holes: props.boreDiameter > 0 ? [circularProfile(0, 0, props.boreDiameter / 2)] : [],
16901
17860
  start: 0,
16902
- end: length26
17861
+ end: length29
16903
17862
  });
16904
17863
  }
16905
17864
 
@@ -16915,14 +17874,14 @@ function TSlotExtrusion({
16915
17874
  }
16916
17875
 
16917
17876
  // lib/models/tslotextrusion/register.tsx
16918
- var model84 = defineModelRenderer({
17877
+ var model93 = defineModelRenderer({
16919
17878
  name: "tslotextrusion",
16920
17879
  schema: tSlotExtrusionModelDefinitionSchema,
16921
17880
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TSlotExtrusion, { ...props }),
16922
17881
  pads: "none"
16923
17882
  });
16924
- function register84(registry2) {
16925
- registry2.register(model84);
17883
+ function register93(registry2) {
17884
+ registry2.register(model93);
16926
17885
  }
16927
17886
 
16928
17887
  // lib/models/tslotgusset/mesh.ts
@@ -16968,14 +17927,14 @@ function TSlotGusset({ color = "#8995a3", ...props }) {
16968
17927
  }
16969
17928
 
16970
17929
  // lib/models/tslotgusset/register.tsx
16971
- var model85 = defineModelRenderer({
17930
+ var model94 = defineModelRenderer({
16972
17931
  name: "tslotgusset",
16973
17932
  schema: tSlotGussetModelDefinitionSchema,
16974
17933
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TSlotGusset, { ...props }),
16975
17934
  pads: "none"
16976
17935
  });
16977
- function register85(registry2) {
16978
- registry2.register(model85);
17936
+ function register94(registry2) {
17937
+ registry2.register(model94);
16979
17938
  }
16980
17939
 
16981
17940
  // lib/models/tslotinsidecorner/mesh.ts
@@ -17049,18 +18008,18 @@ function TSlotInsideCorner({
17049
18008
  }
17050
18009
 
17051
18010
  // lib/models/tslotinsidecorner/register.tsx
17052
- var model86 = defineModelRenderer({
18011
+ var model95 = defineModelRenderer({
17053
18012
  name: "tslotinsidecorner",
17054
18013
  schema: tSlotInsideCornerModelDefinitionSchema,
17055
18014
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TSlotInsideCorner, { ...props }),
17056
18015
  pads: "none"
17057
18016
  });
17058
- function register86(registry2) {
17059
- registry2.register(model86);
18017
+ function register95(registry2) {
18018
+ registry2.register(model95);
17060
18019
  }
17061
18020
 
17062
18021
  // lib/mechanical/worm-gear-mesh.ts
17063
- import earcut6 from "earcut";
18022
+ import earcut7 from "earcut";
17064
18023
  var createWormGearMesh = (input) => {
17065
18024
  const props = wormGearModelPropsSchema.parse(input);
17066
18025
  const { outsideDiameter, rootDiameter, axialPitch, lead, toothThickness } = getWormGearDimensions(props);
@@ -17213,7 +18172,7 @@ var createWormGearMesh = (input) => {
17213
18172
  positions[vertex * 3],
17214
18173
  positions[vertex * 3 + 1]
17215
18174
  ]);
17216
- const triangles = earcut6(flat, [count], 2);
18175
+ const triangles = earcut7(flat, [count], 2);
17217
18176
  for (let index = 0; index < triangles.length; index += 3) {
17218
18177
  const a = vertices[triangles[index]];
17219
18178
  const b = vertices[triangles[index + 1]];
@@ -17241,23 +18200,96 @@ function WormGear({ color = "#737e8f", ...props }) {
17241
18200
  }
17242
18201
 
17243
18202
  // lib/models/wormgear/register.tsx
17244
- var model87 = defineModelRenderer({
18203
+ var model96 = defineModelRenderer({
17245
18204
  name: "wormgear",
17246
18205
  schema: wormGearModelDefinitionSchema,
17247
18206
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(WormGear, { ...props }),
17248
18207
  pads: "none"
17249
18208
  });
17250
- function register87(registry2) {
17251
- registry2.register(model87);
18209
+ function register96(registry2) {
18210
+ registry2.register(model96);
18211
+ }
18212
+
18213
+ // lib/models/zeebar/mesh.ts
18214
+ function filletedOutline(points, radii) {
18215
+ const outline = [];
18216
+ for (let i = 0; i < points.length; i++) {
18217
+ const a = points[(i + points.length - 1) % points.length], b = points[i], c = points[(i + 1) % points.length], r = radii[i];
18218
+ if (r === 0) {
18219
+ outline.push(b);
18220
+ continue;
18221
+ }
18222
+ const al = Math.hypot(a[0] - b[0], a[1] - b[1]), cl = Math.hypot(c[0] - b[0], c[1] - b[1]);
18223
+ const u = [(a[0] - b[0]) / al, (a[1] - b[1]) / al], v = [(c[0] - b[0]) / cl, (c[1] - b[1]) / cl];
18224
+ const center = [
18225
+ b[0] + r * (u[0] + v[0]),
18226
+ b[1] + r * (u[1] + v[1])
18227
+ ];
18228
+ const start = Math.atan2(
18229
+ b[1] + r * u[1] - center[1],
18230
+ b[0] + r * u[0] - center[0]
18231
+ );
18232
+ const turn = u[1] * v[0] - u[0] * v[1] > 0 ? 1 : -1;
18233
+ for (let step = 0; step <= 48; step++) {
18234
+ const angle = start + turn * step * Math.PI / 96;
18235
+ outline.push(
18236
+ step === 0 ? [b[0] + r * u[0], b[1] + r * u[1]] : step === 48 ? [b[0] + r * v[0], b[1] + r * v[1]] : [
18237
+ center[0] + r * Math.cos(angle),
18238
+ center[1] + r * Math.sin(angle)
18239
+ ]
18240
+ );
18241
+ }
18242
+ }
18243
+ return outline;
18244
+ }
18245
+ function createZeeBarMesh(input) {
18246
+ const p = zeeBarModelPropsSchema.parse(input);
18247
+ const {
18248
+ height: h2,
18249
+ upperWidth: upper,
18250
+ lowerWidth: lower,
18251
+ thickness: t,
18252
+ bendRadius: r,
18253
+ length: l
18254
+ } = p;
18255
+ const w = upper + lower - t, outer = r + t;
18256
+ const outline = filletedOutline(
18257
+ [
18258
+ [0, 0],
18259
+ [lower, 0],
18260
+ [lower, h2 - t],
18261
+ [w, h2 - t],
18262
+ [w, h2],
18263
+ [lower - t, h2],
18264
+ [lower - t, t],
18265
+ [0, t]
18266
+ ],
18267
+ [0, outer, r, 0, 0, outer, r, 0]
18268
+ ).map(([x, y]) => [x - w / 2, y - h2 / 2]);
18269
+ return extrudePlanarProfile({ outer: outline, start: 0, end: l });
18270
+ }
18271
+
18272
+ // lib/models/zeebar/ZeeBar.tsx
18273
+ function createZeeBarGeom(input) {
18274
+ return indexedMeshToGeom3(createZeeBarMesh(input));
18275
+ }
18276
+ function ZeeBar({ color = "#8995a3", ...props }) {
18277
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createZeeBarGeom(props) }) });
18278
+ }
18279
+
18280
+ // lib/models/zeebar/register.tsx
18281
+ var model97 = defineModelRenderer({
18282
+ name: "zeebar",
18283
+ schema: zeeBarModelDefinitionSchema,
18284
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ZeeBar, { ...props }),
18285
+ pads: "none"
18286
+ });
18287
+ function register97(registry2) {
18288
+ registry2.register(model97);
17252
18289
  }
17253
18290
 
17254
18291
  // lib/generated/model-renderers.ts
17255
18292
  function registerAllModelRenderers(registry2) {
17256
- register45(registry2);
17257
- register46(registry2);
17258
- register47(registry2);
17259
- register48(registry2);
17260
- register49(registry2);
17261
18293
  register50(registry2);
17262
18294
  register51(registry2);
17263
18295
  register52(registry2);
@@ -17296,6 +18328,16 @@ function registerAllModelRenderers(registry2) {
17296
18328
  register85(registry2);
17297
18329
  register86(registry2);
17298
18330
  register87(registry2);
18331
+ register88(registry2);
18332
+ register89(registry2);
18333
+ register90(registry2);
18334
+ register91(registry2);
18335
+ register92(registry2);
18336
+ register93(registry2);
18337
+ register94(registry2);
18338
+ register95(registry2);
18339
+ register96(registry2);
18340
+ register97(registry2);
17299
18341
  }
17300
18342
 
17301
18343
  // lib/default-model-registry.ts
@@ -17637,7 +18679,7 @@ import { fp as fp10 } from "@tscircuit/footprinter";
17637
18679
  var ChipBody = ({
17638
18680
  center,
17639
18681
  width: width10,
17640
- length: length26,
18682
+ length: length29,
17641
18683
  height: height10,
17642
18684
  heightAboveSurface: heightAboveSurface2 = 0.15,
17643
18685
  color = "#555",
@@ -17654,24 +18696,24 @@ var ChipBody = ({
17654
18696
  }) => {
17655
18697
  const straightHeight = height10 * straightHeightRatio;
17656
18698
  const taperHeight = height10 - straightHeight;
17657
- const taperInset = Math.min(width10, length26) * taperRatio;
18699
+ const taperInset = Math.min(width10, length29) * taperRatio;
17658
18700
  const faceWidth = Math.max(width10 - taperInset, width10 * faceRatio);
17659
- const faceLength = Math.max(length26 - taperInset, length26 * faceRatio);
17660
- const defaultNotchRadius = Math.min(width10, length26) * 0.12;
18701
+ const faceLength = Math.max(length29 - taperInset, length29 * faceRatio);
18702
+ const defaultNotchRadius = Math.min(width10, length29) * 0.12;
17661
18703
  const actualNotchRadius = notchRadius ?? defaultNotchRadius;
17662
18704
  const defaultNotchPosition = {
17663
18705
  x: 0,
17664
- y: length26 / 2 - actualNotchRadius * 0.25,
18706
+ y: length29 / 2 - actualNotchRadius * 0.25,
17665
18707
  z: height10
17666
18708
  };
17667
18709
  const actualNotchPosition = notchPosition ?? defaultNotchPosition;
17668
18710
  const body = /* @__PURE__ */ jsxs(Union, { children: [
17669
18711
  /* @__PURE__ */ jsxs(Hull, { children: [
17670
18712
  /* @__PURE__ */ jsx(Translate, { z: 5e-3, children: /* @__PURE__ */ jsx(Cuboid, { size: [faceWidth, faceLength, 0.01] }) }),
17671
- /* @__PURE__ */ jsx(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [width10, length26, 0.01] }) })
18713
+ /* @__PURE__ */ jsx(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [width10, length29, 0.01] }) })
17672
18714
  ] }),
17673
18715
  /* @__PURE__ */ jsxs(Hull, { children: [
17674
- /* @__PURE__ */ jsx(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [width10, length26, 0.01] }) }),
18716
+ /* @__PURE__ */ jsx(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [width10, length29, 0.01] }) }),
17675
18717
  /* @__PURE__ */ jsx(Translate, { z: straightHeight + taperHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [faceWidth, faceLength, 0.01] }) })
17676
18718
  ] })
17677
18719
  ] });
@@ -17688,7 +18730,7 @@ var ChipBody = ({
17688
18730
  let finalBody = body;
17689
18731
  if (chamferSize > 0) {
17690
18732
  const xOffset = width10 / 2;
17691
- const yOffset = length26 / 2;
18733
+ const yOffset = length29 / 2;
17692
18734
  finalBody = /* @__PURE__ */ jsxs(Subtract, { children: [
17693
18735
  body,
17694
18736
  chamferCutout(xOffset, yOffset),
@@ -17718,8 +18760,8 @@ function getExpandedStroke(strokeInput, width10) {
17718
18760
  function getNormal(p1, p2) {
17719
18761
  const dx = p2.x - p1.x;
17720
18762
  const dy = p2.y - p1.y;
17721
- const length26 = Math.sqrt(dx * dx + dy * dy);
17722
- return { x: -dy / length26, y: dx / length26 };
18763
+ const length29 = Math.sqrt(dx * dx + dy * dy);
18764
+ return { x: -dy / length29, y: dx / length29 };
17723
18765
  }
17724
18766
  function addPoint(point, normal, factor) {
17725
18767
  const newPoint = {
@@ -19387,11 +20429,11 @@ var FemaleHeaderRow = ({
19387
20429
  // lib/PushButton.tsx
19388
20430
  var PushButton = ({
19389
20431
  width: width10,
19390
- length: length26,
20432
+ length: length29,
19391
20433
  innerDiameter = 1
19392
20434
  }) => {
19393
20435
  const bodyWidth = width10;
19394
- const bodyLength10 = length26;
20436
+ const bodyLength10 = length29;
19395
20437
  const bodyHeight = width10 * 0.7;
19396
20438
  const legWidth = innerDiameter / 2.5;
19397
20439
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
@@ -23325,12 +24367,12 @@ var JstSh = ({ footprint = "jst6_sh" }) => {
23325
24367
  };
23326
24368
 
23327
24369
  // lib/Crystal.tsx
23328
- var getTerminalPoints = ([centerX, centerY], width10, length26, chamfer, isPinOne) => {
24370
+ var getTerminalPoints = ([centerX, centerY], width10, length29, chamfer, isPinOne) => {
23329
24371
  const xDirection = Math.sign(centerX);
23330
24372
  const yDirection = Math.sign(centerY);
23331
24373
  const halfWidth = width10 / 2;
23332
- const halfLength = length26 / 2;
23333
- const innerChamfer = isPinOne ? Math.min(0.32, length26 * 0.36) : 0;
24374
+ const halfLength = length29 / 2;
24375
+ const innerChamfer = isPinOne ? Math.min(0.32, length29 * 0.36) : 0;
23334
24376
  const outerChamfer = Math.min(chamfer, halfWidth, halfLength);
23335
24377
  const points = [
23336
24378
  [-halfWidth, -halfLength],
@@ -23350,13 +24392,13 @@ var getTerminalPoints = ([centerX, centerY], width10, length26, chamfer, isPinOn
23350
24392
  };
23351
24393
  var getRoundedRectProfile = ({
23352
24394
  width: width10,
23353
- length: length26,
24395
+ length: length29,
23354
24396
  radius,
23355
24397
  height: height10,
23356
24398
  z
23357
24399
  }) => {
23358
24400
  const x = width10 / 2 - radius;
23359
- const y = length26 / 2 - radius;
24401
+ const y = length29 / 2 - radius;
23360
24402
  return [
23361
24403
  [-x, -y],
23362
24404
  [x, -y],
@@ -23500,12 +24542,12 @@ var FPC = ({
23500
24542
  const contactRows = Array.from({ length: pinCount }, (_, index) => {
23501
24543
  const isUpperRow = staggered && index % 2 === 1 !== reverse;
23502
24544
  const y = staggered ? isUpperRow ? rowPitch / 2 : -rowPitch / 2 : 0;
23503
- const length26 = isUpperRow ? topPadLength : bottomPadLength;
24545
+ const length29 = isUpperRow ? topPadLength : bottomPadLength;
23504
24546
  return {
23505
24547
  index,
23506
24548
  x: contactStartX + index * pitch,
23507
24549
  y,
23508
- length: length26
24550
+ length: length29
23509
24551
  };
23510
24552
  });
23511
24553
  const contactMaxY = Math.max(
@@ -24057,7 +25099,7 @@ var Led2835 = ({
24057
25099
  };
24058
25100
 
24059
25101
  // lib/RJ45.tsx
24060
- var range2 = (length26) => Array.from({ length: length26 }, (_, index) => index);
25102
+ var range2 = (length29) => Array.from({ length: length29 }, (_, index) => index);
24061
25103
  var RJ45 = ({
24062
25104
  bodyWidth = 16.26,
24063
25105
  bodyDepth = 15.88,
@@ -24877,10 +25919,10 @@ var SOT143 = ({ footprint = "sot143" }) => {
24877
25919
  var Footprinter3d = ({ footprint }) => {
24878
25920
  const modelFn = mp.string(footprint.split("_", 1)[0]).params().fn;
24879
25921
  if (mp.getModelNames().includes(modelFn)) {
24880
- const model88 = mp.string(footprint).json();
24881
- const renderer = modelRendererRegistry.get(model88.fn);
25922
+ const model98 = mp.string(footprint).json();
25923
+ const renderer = modelRendererRegistry.get(model98.fn);
24882
25924
  if (renderer) {
24883
- return renderer.render(model88);
25925
+ return renderer.render(model98);
24884
25926
  }
24885
25927
  }
24886
25928
  let normalizedFootprint = footprint;
@@ -25564,7 +26606,7 @@ var toVec3 = (v) => {
25564
26606
  };
25565
26607
  function renderNode(node, colorCtx, renderCtx) {
25566
26608
  const {
25567
- jscad: { primitives: primitives7, booleans: booleans3, hulls, geometries: geometries7, extrusions: extrusions7, transforms }
26609
+ jscad: { primitives: primitives8, booleans: booleans4, hulls, geometries: geometries8, extrusions: extrusions8, transforms }
25568
26610
  } = renderCtx;
25569
26611
  if (node == null || node === false) return [];
25570
26612
  if (Array.isArray(node))
@@ -25629,9 +26671,9 @@ function renderNode(node, colorCtx, renderCtx) {
25629
26671
  const geoms = entries.map((g) => g.geom);
25630
26672
  if (geoms.length === 0) return [];
25631
26673
  let geom;
25632
- if (type === Union) geom = booleans3.union(geoms);
26674
+ if (type === Union) geom = booleans4.union(geoms);
25633
26675
  else if (type === Subtract)
25634
- geom = booleans3.subtract(geoms[0], geoms.slice(1));
26676
+ geom = booleans4.subtract(geoms[0], geoms.slice(1));
25635
26677
  else geom = hulls.hull(geoms);
25636
26678
  return [
25637
26679
  {
@@ -25646,7 +26688,7 @@ function renderNode(node, colorCtx, renderCtx) {
25646
26688
  }
25647
26689
  if (type === Polygon) {
25648
26690
  const points = props?.points ?? [];
25649
- const g2 = geometries7.geom2.fromPoints(points);
26691
+ const g2 = geometries8.geom2.fromPoints(points);
25650
26692
  return [{ geom: g2, color: colorCtx ?? props?.color }];
25651
26693
  }
25652
26694
  if (type === ExtrudeLinear) {
@@ -25655,9 +26697,9 @@ function renderNode(node, colorCtx, renderCtx) {
25655
26697
  );
25656
26698
  const geoms2 = entries.map((g) => g.geom);
25657
26699
  if (geoms2.length === 0) return [];
25658
- const base2 = geoms2.length > 1 ? booleans3.union(geoms2) : geoms2[0];
26700
+ const base2 = geoms2.length > 1 ? booleans4.union(geoms2) : geoms2[0];
25659
26701
  const height10 = props?.height ?? props?.h ?? 1;
25660
- let g3 = extrusions7.extrudeLinear({ height: height10 }, base2);
26702
+ let g3 = extrusions8.extrudeLinear({ height: height10 }, base2);
25661
26703
  if (g3.polygons) {
25662
26704
  for (const poly of g3.polygons) {
25663
26705
  if (!poly.plane || !poly.vertices || poly.vertices.length < 3) continue;
@@ -25678,32 +26720,32 @@ function renderNode(node, colorCtx, renderCtx) {
25678
26720
  const size = props?.size ?? [1, 1, 1];
25679
26721
  const offset = props?.offset;
25680
26722
  const center = props?.center ?? (offset ? [offset[0], offset[1], offset[2]] : [0, 0, 0]);
25681
- g = primitives7.cuboid({ size, center });
26723
+ g = primitives8.cuboid({ size, center });
25682
26724
  } else if (type === Cube) {
25683
26725
  const size = props?.size ?? 1;
25684
26726
  const offset = props?.offset;
25685
26727
  const center = props?.center ?? (offset ? [offset[0], offset[1], offset[2]] : [0, 0, 0]);
25686
- g = primitives7.cube({ size, center });
26728
+ g = primitives8.cube({ size, center });
25687
26729
  } else if (type === Cylinder) {
25688
26730
  const height10 = props?.height ?? 1;
25689
26731
  const radius = props?.radius ?? 1;
25690
26732
  const center = props?.center ?? [0, 0, 0];
25691
- g = primitives7.cylinder({ height: height10, radius, center });
26733
+ g = primitives8.cylinder({ height: height10, radius, center });
25692
26734
  } else if (type === Sphere) {
25693
26735
  const radius = props?.radius ?? 1;
25694
26736
  const center = props?.center ?? [0, 0, 0];
25695
- g = primitives7.sphere({ radius, center });
26737
+ g = primitives8.sphere({ radius, center });
25696
26738
  } else if (type === RoundedCylinder) {
25697
26739
  const height10 = props?.height ?? 1;
25698
26740
  const radius = props?.radius ?? 1;
25699
26741
  const roundRadius = props?.roundRadius ?? 0.1;
25700
26742
  const center = props?.center ?? [0, 0, 0];
25701
- g = primitives7.roundedCylinder({ height: height10, radius, roundRadius, center });
26743
+ g = primitives8.roundedCylinder({ height: height10, radius, roundRadius, center });
25702
26744
  } else {
25703
26745
  const size = props?.size ?? [1, 1, 1];
25704
26746
  const roundRadius = props?.roundRadius ?? 0.1;
25705
26747
  const center = props?.center ?? [0, 0, 0];
25706
- g = primitives7.roundedCuboid({ size, roundRadius, center });
26748
+ g = primitives8.roundedCuboid({ size, roundRadius, center });
25707
26749
  }
25708
26750
  return [{ geom: g, color: colorCtx ?? props?.color }];
25709
26751
  }
@@ -25713,10 +26755,10 @@ function renderNode(node, colorCtx, renderCtx) {
25713
26755
  }
25714
26756
  return (children ?? []).flatMap((c) => renderNode(c, colorCtx, renderCtx));
25715
26757
  }
25716
- function render(root, jscad14) {
25717
- const geometries7 = renderNode(root, void 0, { jscad: jscad14 });
26758
+ function render(root, jscad15) {
26759
+ const geometries8 = renderNode(root, void 0, { jscad: jscad15 });
25718
26760
  return {
25719
- geometries: geometries7.map(
26761
+ geometries: geometries8.map(
25720
26762
  (entry) => entry.material ? { ...entry, geom: { ...entry.geom, material: entry.material } } : entry
25721
26763
  )
25722
26764
  };
@@ -25806,25 +26848,25 @@ function convertCSGToThreeGeom(csg) {
25806
26848
  }
25807
26849
 
25808
26850
  // lib/vanilla/index.ts
25809
- function getJscadModelForFootprint(footprint, jscad14) {
26851
+ function getJscadModelForFootprint(footprint, jscad15) {
25810
26852
  const vnode = h(Footprinter3d, { footprint });
25811
- return render(vnode, jscad14);
26853
+ return render(vnode, jscad15);
25812
26854
  }
25813
- function getJscadModelForFootprintWithPads(footprint, jscad14) {
26855
+ function getJscadModelForFootprintWithPads(footprint, jscad15) {
25814
26856
  const vnode = h(
25815
26857
  Fragment,
25816
26858
  {},
25817
26859
  h(Footprinter3d, { footprint }),
25818
26860
  h(ExtrudedPads, { footprint })
25819
26861
  );
25820
- return render(vnode, jscad14);
26862
+ return render(vnode, jscad15);
25821
26863
  }
25822
- function createJSCADRenderer(jscad14) {
26864
+ function createJSCADRenderer(jscad15) {
25823
26865
  function createJSCADRoot(container) {
25824
26866
  return {
25825
26867
  render(element) {
25826
- const { geometries: geometries7 } = render(element, jscad14);
25827
- container.splice(0, container.length, ...geometries7);
26868
+ const { geometries: geometries8 } = render(element, jscad15);
26869
+ container.splice(0, container.length, ...geometries8);
25828
26870
  }
25829
26871
  };
25830
26872
  }
@@ -25863,20 +26905,25 @@ export {
25863
26905
  PlainBushing,
25864
26906
  PushFitPlug,
25865
26907
  RectangularBar,
26908
+ RectangularGasket,
25866
26909
  RectangularTube,
25867
26910
  RigidCoupler,
25868
26911
  SetScrew,
25869
26912
  ShaftCollar,
25870
26913
  SheetMetal,
26914
+ SlottedChannel,
25871
26915
  Spacer,
26916
+ SplitGrommet,
25872
26917
  SplitWasher,
25873
26918
  SpurGear,
26919
+ TSlotCoverStrip,
25874
26920
  TSlotExtrusion,
25875
26921
  TSlotGusset,
25876
26922
  TSlotInsideCorner,
25877
26923
  ThreadedRod,
25878
26924
  TorsionSpring,
25879
26925
  WormGear,
26926
+ ZeeBar,
25880
26927
  convertCSGToThreeGeom,
25881
26928
  createAngleBarGeom,
25882
26929
  createAngleBarMesh,
@@ -25935,6 +26982,8 @@ export {
25935
26982
  createPushFitPlugMesh,
25936
26983
  createRectangularBarGeom,
25937
26984
  createRectangularBarMesh,
26985
+ createRectangularGasketGeom,
26986
+ createRectangularGasketMesh,
25938
26987
  createRectangularTubeGeom,
25939
26988
  createRectangularTubeMesh,
25940
26989
  createRigidCouplerGeom,
@@ -25945,12 +26994,18 @@ export {
25945
26994
  createShaftCollarMesh,
25946
26995
  createSheetMetalGeom,
25947
26996
  createSheetMetalMesh,
26997
+ createSlottedChannelGeom,
26998
+ createSlottedChannelMesh,
25948
26999
  createSpacerGeom,
25949
27000
  createSpacerMesh,
27001
+ createSplitGrommetGeom,
27002
+ createSplitGrommetMesh,
25950
27003
  createSplitWasherGeom,
25951
27004
  createSplitWasherMesh,
25952
27005
  createSpurGearGeom,
25953
27006
  createSpurGearMesh,
27007
+ createTSlotCoverStripGeom,
27008
+ createTSlotCoverStripMesh,
25954
27009
  createTSlotExtrusionGeom,
25955
27010
  createTSlotExtrusionMesh,
25956
27011
  createTSlotGussetGeom,
@@ -25963,6 +27018,8 @@ export {
25963
27018
  createTorsionSpringMesh,
25964
27019
  createWormGearGeom,
25965
27020
  createWormGearMesh,
27021
+ createZeeBarGeom,
27022
+ createZeeBarMesh,
25966
27023
  getJscadModelForFootprint,
25967
27024
  getJscadModelForFootprintWithPads,
25968
27025
  h