Compare commits
	
		
			10 Commits
		
	
	
		
			v0.57.0
			...
			nrc-std-kw
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 32572c8ae7 | |||
| e0e707ad85 | |||
| 0913d3ebdc | |||
| c545ad71c6 | |||
| a70718687f | |||
| 85cd29424e | |||
| df1ff68a6d | |||
| 2678d1014e | |||
| cd59691663 | |||
| d7369d8a95 | 
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -15,7 +15,7 @@ std::math::E: number = 2.71828182845904523536028747135266250_ | ||||
| ### Examples | ||||
|  | ||||
| ```js | ||||
| exampleSketch = startSketchOn("XZ") | ||||
| exampleSketch = startSketchOn(XZ) | ||||
|   |> startProfileAt([0, 0], %) | ||||
|   |> angledLine({ | ||||
|     angle = 30, | ||||
|  | ||||
| @ -17,7 +17,7 @@ std::math::PI: number = 3.14159265358979323846264338327950288_ | ||||
| ```js | ||||
| circumference = 70 | ||||
|  | ||||
| exampleSketch = startSketchOn("XZ") | ||||
| exampleSketch = startSketchOn(XZ) | ||||
|  |> circle(center = [0, 0], radius = circumference/ (2 * PI)) | ||||
|  | ||||
| example = extrude(exampleSketch, length = 5) | ||||
|  | ||||
| @ -15,7 +15,7 @@ std::math::TAU: number = 6.28318530717958647692528676655900577_ | ||||
| ### Examples | ||||
|  | ||||
| ```js | ||||
| exampleSketch = startSketchOn("XZ") | ||||
| exampleSketch = startSketchOn(XZ) | ||||
|   |> startProfileAt([0, 0], %) | ||||
|   |> angledLine({ | ||||
|     angle = 50, | ||||
|  | ||||
| @ -22,8 +22,12 @@ layout: manual | ||||
|   * [`string`](kcl/types/string) | ||||
|   * [`tag`](kcl/types/tag) | ||||
| * **std** | ||||
|   * [`Face`](kcl/types/Face) | ||||
|   * [`HALF_TURN`](kcl/consts/std-HALF_TURN) | ||||
|   * [`Helix`](kcl/types/Helix) | ||||
|   * [`Plane`](kcl/types/Plane) | ||||
|   * [`Point2d`](kcl/types/Point2d) | ||||
|   * [`Point3d`](kcl/types/Point3d) | ||||
|   * [`QUARTER_TURN`](kcl/consts/std-QUARTER_TURN) | ||||
|   * [`Sketch`](kcl/types/Sketch) | ||||
|   * [`Solid`](kcl/types/Solid) | ||||
| @ -57,7 +61,6 @@ layout: manual | ||||
|   * [`bezierCurve`](kcl/bezierCurve) | ||||
|   * [`ceil`](kcl/ceil) | ||||
|   * [`chamfer`](kcl/chamfer) | ||||
|   * [`circle`](kcl/circle) | ||||
|   * [`circleThreePoint`](kcl/circleThreePoint) | ||||
|   * [`close`](kcl/close) | ||||
|   * [`cm`](kcl/cm) | ||||
| @ -142,3 +145,5 @@ layout: manual | ||||
|   * [`cos`](kcl/std-math-cos) | ||||
|   * [`sin`](kcl/std-math-sin) | ||||
|   * [`tan`](kcl/std-math-tan) | ||||
| * **std::sketch** | ||||
|   * [`circle`](kcl/std-sketch-circle) | ||||
|  | ||||
| @ -9,7 +9,7 @@ Compute the cosine of a number (in radians). | ||||
|  | ||||
|  | ||||
| ```js | ||||
| cos(num: number(rad)): number(_) | ||||
| cos(@num: number(rad)): number(_) | ||||
| ``` | ||||
|  | ||||
|  | ||||
| @ -27,7 +27,7 @@ cos(num: number(rad)): number(_) | ||||
| ### Examples | ||||
|  | ||||
| ```js | ||||
| exampleSketch = startSketchOn("XZ") | ||||
| exampleSketch = startSketchOn(XZ) | ||||
|   |> startProfileAt([0, 0], %) | ||||
|   |> angledLine({ | ||||
|     angle = 30, | ||||
|  | ||||
| @ -9,7 +9,7 @@ Compute the sine of a number (in radians). | ||||
|  | ||||
|  | ||||
| ```js | ||||
| sin(num: number(rad)): number(_) | ||||
| sin(@num: number(rad)): number(_) | ||||
| ``` | ||||
|  | ||||
|  | ||||
| @ -27,7 +27,7 @@ sin(num: number(rad)): number(_) | ||||
| ### Examples | ||||
|  | ||||
| ```js | ||||
| exampleSketch = startSketchOn("XZ") | ||||
| exampleSketch = startSketchOn(XZ) | ||||
|   |> startProfileAt([0, 0], %) | ||||
|   |> angledLine({ | ||||
|     angle = 50, | ||||
|  | ||||
| @ -9,7 +9,7 @@ Compute the tangent of a number (in radians). | ||||
|  | ||||
|  | ||||
| ```js | ||||
| tan(num: number(rad)): number(_) | ||||
| tan(@num: number(rad)): number(_) | ||||
| ``` | ||||
|  | ||||
|  | ||||
| @ -27,7 +27,7 @@ tan(num: number(rad)): number(_) | ||||
| ### Examples | ||||
|  | ||||
| ```js | ||||
| exampleSketch = startSketchOn("XZ") | ||||
| exampleSketch = startSketchOn(XZ) | ||||
|   |> startProfileAt([0, 0], %) | ||||
|   |> angledLine({ | ||||
|     angle = 50, | ||||
|  | ||||
							
								
								
									
										55
									
								
								docs/kcl/std-sketch-circle.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/kcl/std-sketch-circle.md
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										8076
									
								
								docs/kcl/std.json
									
									
									
									
									
								
							
							
						
						
									
										8076
									
								
								docs/kcl/std.json
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,28 +1,12 @@ | ||||
| --- | ||||
| title: "Face" | ||||
| title: "std::Face" | ||||
| excerpt: "A face." | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
| A face. | ||||
|  | ||||
| **Type:** `object` | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ## Properties | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `id` |[`string`](/docs/kcl/types/string)| The id of the face. | No | | ||||
| | `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No | | ||||
| | `value` |[`string`](/docs/kcl/types/string)| The tag of the face. | No | | ||||
| | `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's X axis be? | No | | ||||
| | `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's Y axis be? | No | | ||||
| | `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No | | ||||
| | `solid` |[`Solid`](/docs/kcl/types/Solid)| The solid the face is on. | No | | ||||
| | `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -1,26 +1,12 @@ | ||||
| --- | ||||
| title: "Helix" | ||||
| title: "std::Helix" | ||||
| excerpt: "A helix." | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
| A helix. | ||||
|  | ||||
| **Type:** `object` | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ## Properties | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `value` |[`string`](/docs/kcl/types/string)| The id of the helix. | No | | ||||
| | `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No | | ||||
| | `revolutions` |[`number`](/docs/kcl/types/number)| Number of revolutions. | No | | ||||
| | `angleStart` |[`number`](/docs/kcl/types/number)| Start angle (in degrees). | No | | ||||
| | `ccw` |`boolean`| Is the helix rotation counter clockwise? | No | | ||||
| | `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -188,7 +188,7 @@ Any KCL value. | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `type` |enum: [`Face`](/docs/kcl/types/Face)|  | No | | ||||
| | `value` |[`Face`](/docs/kcl/types/Face)| A face. | No | | ||||
| | `value` |[`Face`](/docs/kcl/types/Face)|  | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
| @ -236,7 +236,7 @@ Any KCL value. | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `type` |enum: [`Helix`](/docs/kcl/types/Helix)|  | No | | ||||
| | `value` |[`Helix`](/docs/kcl/types/Helix)| A helix. | No | | ||||
| | `value` |[`Helix`](/docs/kcl/types/Helix)|  | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
|  | ||||
							
								
								
									
										17
									
								
								docs/kcl/types/Point2d.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								docs/kcl/types/Point2d.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| --- | ||||
| title: "std::Point2d" | ||||
| excerpt: "A point in two dimensional space." | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
| A point in two dimensional space. | ||||
|  | ||||
| ```kcl | ||||
| type Point2d = [number; 2] | ||||
| ``` | ||||
|  | ||||
| [`Point2d`](/docs/kcl/types/Point2d) is an alias for a two-element array of [number](/docs/kcl/types/number)s. To write a value | ||||
| with type [`Point2d`](/docs/kcl/types/Point2d), use an array, e.g., `[0, 0]` or `[5.0, 3.14]`. | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -1,22 +1,17 @@ | ||||
| --- | ||||
| title: "Point3d" | ||||
| excerpt: "" | ||||
| title: "std::Point3d" | ||||
| excerpt: "A point in three dimensional space." | ||||
| layout: manual | ||||
| --- | ||||
|  | ||||
| A point in three dimensional space. | ||||
|  | ||||
| **Type:** `object` | ||||
| ```kcl | ||||
| type Point3d = [number; 3] | ||||
| ``` | ||||
|  | ||||
| [`Point3d`](/docs/kcl/types/Point3d) is an alias for a three-element array of [number](/docs/kcl/types/number)s. To write a value | ||||
| with type [`Point3d`](/docs/kcl/types/Point3d), use an array, e.g., `[0, 0, 0]` or `[5.0, 3.14, 6.8]`. | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ## Properties | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `x` |[`number`](/docs/kcl/types/number)|  | No | | ||||
| | `y` |[`number`](/docs/kcl/types/number)|  | No | | ||||
| | `z` |[`number`](/docs/kcl/types/number)|  | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -17,7 +17,7 @@ mySketch = startSketchOn('XY') | ||||
|     |> close() | ||||
| ``` | ||||
|  | ||||
| The `mySketch` variable will be an executed `Sketch` object. Executed being past | ||||
| The `mySketch` variable will be an executed [`Sketch`](/docs/kcl/types/Sketch) object. Executed being past | ||||
| tense, because the engine has already executed the commands to create the sketch. | ||||
|  | ||||
| The previous sketch commands will never be executed again, in this case. | ||||
|  | ||||
| @ -18,7 +18,7 @@ myPart = startSketchOn('XY') | ||||
|     |> extrude(length = 6) | ||||
| ``` | ||||
|  | ||||
| The `myPart` variable will be an executed `Solid` object. Executed being past | ||||
| The `myPart` variable will be an executed [`Solid`](/docs/kcl/types/Solid) object. Executed being past | ||||
| tense, because the engine has already executed the commands to create the solid. | ||||
|  | ||||
| The previous solid commands will never be executed again, in this case. | ||||
|  | ||||
| @ -22,7 +22,6 @@ A path to sweep along. | ||||
|  | ||||
|  | ||||
| ---- | ||||
| A helix. | ||||
|  | ||||
| [`Helix`](/docs/kcl/types/Helix) | ||||
|  | ||||
|  | ||||
| @ -20,7 +20,7 @@ statement[@isGroup=Statement] { | ||||
|   ImportStatement { kw<"import"> ImportItems ImportFrom String } | | ||||
|   FunctionDeclaration { kw<"export">? kw<"fn"> VariableDefinition Equals? ParamList Arrow? Body } | | ||||
|   VariableDeclaration { kw<"export">? (kw<"var"> | kw<"let"> | kw<"const">)? VariableDefinition Equals expression } | | ||||
|   TypeDeclaration { kw<"export">? kw<"type"> identifier } | | ||||
|   TypeDeclaration { kw<"export">? kw<"type"> identifier ("=" type)? } | | ||||
|   ReturnStatement { kw<"return"> expression } | | ||||
|   ExpressionStatement { expression } | | ||||
|   Annotation { AnnotationName AnnotationList? } | ||||
| @ -75,11 +75,8 @@ LabeledArgument { ArgumentLabel Equals expression } | ||||
| ArgumentList { "(" commaSep<LabeledArgument | expression> ")" } | ||||
|  | ||||
| type[@isGroup=Type] { | ||||
|   @specialize[@name=PrimitiveType]< | ||||
|     identifier, | ||||
|     "bool" | "number" | "string" | "tag" | "Sketch" | "SketchSurface" | "Solid" | "Plane" | ||||
|   > | | ||||
|   ArrayType { type !member "[" "]" } | | ||||
|   PrimitiveType { identifier } | | ||||
|   ArrayType { "[" type !member (";" Number "+"?)? "]" } | | ||||
|   ObjectType { "{" commaSep<ObjectProperty { PropertyName ":" type }> "}" } | ||||
| } | ||||
|  | ||||
| @ -137,7 +134,7 @@ commaSep1NoTrailingComma<term> { term ("," term)* } | ||||
|   "(" ")" | ||||
|   "{" "}" | ||||
|   "[" "]" | ||||
|   "," "?" ":" "." ".." | ||||
|   "," "?" ":" "." ".." ";" | ||||
| } | ||||
|  | ||||
| @external propSource kclHighlight from "./highlight" | ||||
|  | ||||
| @ -822,7 +822,7 @@ async fn kcl_test_stdlib_kcl_error_circle() { | ||||
|  | ||||
| // Create a function that defines the body width and length of the mounting plate. Tag the corners so they can be passed through the fillet function. | ||||
| fn rectShape = (pos, w, l) => { | ||||
|   rr = startSketchOn('XY') | ||||
|   rr = startSketchOn(XY) | ||||
|   |> startProfileAt([pos[0] - (w / 2), pos[1] - (l / 2)], %) | ||||
|   |> line(endAbsolute = [pos[0] + w / 2, pos[1] - (l / 2)], tag = $edge1) | ||||
|   |> line(endAbsolute = [pos[0] + w / 2, pos[1] + l / 2], tag = $edge2) | ||||
| @ -837,10 +837,10 @@ holeIndex = 6 | ||||
|  | ||||
| // Create the mounting plate extrusion, holes, and fillets | ||||
| part = rectShape([0, 0], 20, 20) | ||||
|   |> hole(circle('XY', [-holeIndex, holeIndex], holeRadius), %) | ||||
|   |> hole(circle('XY', [holeIndex, holeIndex], holeRadius), %) | ||||
|   |> hole(circle('XY', [-holeIndex, -holeIndex], holeRadius), %) | ||||
|   |> hole(circle('XY', [holeIndex, -holeIndex], holeRadius), %) | ||||
|   |> hole(circle('XY', center = [-holeIndex, holeIndex], radius = holeRadius), %) | ||||
|   |> hole(circle('XY', center = [holeIndex, holeIndex], radius = holeRadius), %) | ||||
|   |> hole(circle('XY', center = [-holeIndex, -holeIndex], radius = holeRadius), %) | ||||
|   |> hole(circle('XY', center = [holeIndex, -holeIndex], radius = holeRadius), %) | ||||
|   |> extrude(length = 2) | ||||
|   |> fillet( | ||||
|        radius = 4, | ||||
| @ -860,7 +860,7 @@ part = rectShape([0, 0], 20, 20) | ||||
|     }; | ||||
|     assert_eq!( | ||||
|         err.error.message(), | ||||
|         "This function expected the input argument to be of type SketchOrSurface but it's actually of type string (text)" | ||||
|         "The input argument of std::sketch::circle requires a value with type `Sketch | Plane | Face`, but found string (text)" | ||||
|     ); | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -23,7 +23,9 @@ use crate::{ | ||||
| const TYPES_DIR: &str = "../../docs/kcl/types"; | ||||
| const LANG_TOPICS: [&str; 5] = ["Types", "Modules", "Settings", "Known Issues", "Constants"]; | ||||
| // These types are declared in std. | ||||
| const DECLARED_TYPES: [&str; 7] = ["number", "string", "tag", "bool", "Sketch", "Solid", "Plane"]; | ||||
| const DECLARED_TYPES: [&str; 11] = [ | ||||
|     "number", "string", "tag", "bool", "Sketch", "Solid", "Plane", "Helix", "Face", "Point2d", "Point3d", | ||||
| ]; | ||||
|  | ||||
| fn init_handlebars() -> Result<handlebars::Handlebars<'static>> { | ||||
|     let mut hbs = handlebars::Handlebars::new(); | ||||
| @ -457,6 +459,7 @@ fn generate_type_from_kcl(ty: &TyData, file_name: String, example_name: String) | ||||
|  | ||||
|     let data = json!({ | ||||
|         "name": ty.qual_name(), | ||||
|         "definition": ty.alias.as_ref().map(|t| format!("type {} = {t}", ty.name)), | ||||
|         "summary": ty.summary, | ||||
|         "description": ty.description, | ||||
|         "deprecated": ty.properties.deprecated, | ||||
| @ -464,6 +467,10 @@ fn generate_type_from_kcl(ty: &TyData, file_name: String, example_name: String) | ||||
|     }); | ||||
|  | ||||
|     let output = hbs.render("kclType", &data)?; | ||||
|     let output = cleanup_type_links( | ||||
|         &output, | ||||
|         ty.referenced_types.iter().filter(|t| !DECLARED_TYPES.contains(&&***t)), | ||||
|     ); | ||||
|     expectorate::assert_contents(format!("../../docs/kcl/{}.md", file_name), &output); | ||||
|  | ||||
|     Ok(()) | ||||
| @ -511,6 +518,13 @@ fn generate_function_from_kcl(function: &FnData, file_name: String) -> Result<() | ||||
|     }); | ||||
|  | ||||
|     let output = hbs.render("function", &data)?; | ||||
|     let output = cleanup_type_links( | ||||
|         &output, | ||||
|         function | ||||
|             .referenced_types | ||||
|             .iter() | ||||
|             .filter(|t| !DECLARED_TYPES.contains(&&***t)), | ||||
|     ); | ||||
|     expectorate::assert_contents(format!("../../docs/kcl/{}.md", file_name), &output); | ||||
|  | ||||
|     Ok(()) | ||||
| @ -674,6 +688,12 @@ fn cleanup_type_links<'a>(output: &str, types: impl Iterator<Item = &'a String>) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // TODO handle union types generically rather than special casing them. | ||||
|     cleaned_output = cleaned_output.replace( | ||||
|         "`Sketch | Plane | Face`", | ||||
|         "[`Sketch`](/docs/kcl/types/Sketch) `|` [`Plane`](/docs/kcl/types/Face) `|` [`Plane`](/docs/kcl/types/Face)", | ||||
|     ); | ||||
|  | ||||
|     cleanup_static_links(&cleaned_output) | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| use std::str::FromStr; | ||||
| use std::{collections::HashSet, str::FromStr}; | ||||
|  | ||||
| use regex::Regex; | ||||
| use tower_lsp::lsp_types::{ | ||||
|     CompletionItem, CompletionItemKind, CompletionItemLabelDetails, Documentation, InsertTextFormat, MarkupContent, | ||||
|     MarkupKind, ParameterInformation, ParameterLabel, SignatureHelp, SignatureInformation, | ||||
| @ -8,7 +9,7 @@ use tower_lsp::lsp_types::{ | ||||
| use crate::{ | ||||
|     execution::annotations, | ||||
|     parsing::{ | ||||
|         ast::types::{Annotation, Node, NonCodeNode, VariableKind}, | ||||
|         ast::types::{Annotation, Node, PrimitiveType, Type, VariableKind}, | ||||
|         token::NumericSuffix, | ||||
|     }, | ||||
|     ModuleId, | ||||
| @ -58,7 +59,6 @@ impl CollectionVisitor { | ||||
|                         format!("std::{}::", self.name) | ||||
|                     }; | ||||
|                     let mut dd = match var.kind { | ||||
|                         // TODO metadata for args | ||||
|                         VariableKind::Fn => DocData::Fn(FnData::from_ast(var, qual_name)), | ||||
|                         VariableKind::Const => DocData::Const(ConstData::from_ast(var, qual_name)), | ||||
|                     }; | ||||
| @ -282,7 +282,7 @@ impl ConstData { | ||||
|             documentation: self.short_docs().map(|s| { | ||||
|                 Documentation::MarkupContent(MarkupContent { | ||||
|                     kind: MarkupKind::Markdown, | ||||
|                     value: s, | ||||
|                     value: remove_md_links(&s), | ||||
|                 }) | ||||
|             }), | ||||
|             deprecated: Some(self.properties.deprecated), | ||||
| @ -321,6 +321,8 @@ pub struct FnData { | ||||
|     /// Code examples. | ||||
|     /// These are tested and we know they compile and execute. | ||||
|     pub examples: Vec<(String, ExampleProperties)>, | ||||
|     #[allow(dead_code)] | ||||
|     pub referenced_types: Vec<String>, | ||||
| } | ||||
|  | ||||
| impl FnData { | ||||
| @ -331,11 +333,22 @@ impl FnData { | ||||
|         }; | ||||
|         let name = var.declaration.id.name.clone(); | ||||
|         qual_name.push_str(&name); | ||||
|  | ||||
|         let mut referenced_types = HashSet::new(); | ||||
|         if let Some(t) = &expr.return_type { | ||||
|             collect_type_names(&mut referenced_types, t); | ||||
|         } | ||||
|         for p in &expr.params { | ||||
|             if let Some(t) = &p.type_ { | ||||
|                 collect_type_names(&mut referenced_types, t); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         FnData { | ||||
|             name, | ||||
|             qual_name, | ||||
|             args: expr.params.iter().map(ArgData::from_ast).collect(), | ||||
|             return_type: expr.return_type.as_ref().map(|t| t.recast(&Default::default(), 0)), | ||||
|             return_type: expr.return_type.as_ref().map(|t| t.to_string()), | ||||
|             properties: Properties { | ||||
|                 exported: !var.visibility.is_default(), | ||||
|                 deprecated: false, | ||||
| @ -345,6 +358,7 @@ impl FnData { | ||||
|             summary: None, | ||||
|             description: None, | ||||
|             examples: Vec::new(), | ||||
|             referenced_types: referenced_types.into_iter().collect(), | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -393,7 +407,7 @@ impl FnData { | ||||
|             documentation: self.short_docs().map(|s| { | ||||
|                 Documentation::MarkupContent(MarkupContent { | ||||
|                     kind: MarkupKind::Markdown, | ||||
|                     value: s, | ||||
|                     value: remove_md_links(&s), | ||||
|                 }) | ||||
|             }), | ||||
|             deprecated: Some(self.properties.deprecated), | ||||
| @ -413,7 +427,7 @@ impl FnData { | ||||
|     } | ||||
|  | ||||
|     #[allow(clippy::literal_string_with_formatting_args)] | ||||
|     fn to_autocomplete_snippet(&self) -> String { | ||||
|     pub(super) fn to_autocomplete_snippet(&self) -> String { | ||||
|         if self.name == "loft" { | ||||
|             return "loft([${0:sketch000}, ${1:sketch001}])${}".to_owned(); | ||||
|         } else if self.name == "hole" { | ||||
| @ -479,12 +493,12 @@ pub struct ArgData { | ||||
|     /// If the argument is required. | ||||
|     pub kind: ArgKind, | ||||
|     /// Additional information that could be used instead of the type's description. | ||||
|     /// This is helpful if the type is really basic, like "u32" -- that won't tell the user much about | ||||
|     /// This is helpful if the type is really basic, like "number" -- that won't tell the user much about | ||||
|     /// how this argument is meant to be used. | ||||
|     pub docs: Option<String>, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| #[derive(Debug, Clone, Copy, PartialEq)] | ||||
| pub enum ArgKind { | ||||
|     Special, | ||||
|     // Parameter is whether the arg is optional. | ||||
| @ -494,38 +508,47 @@ pub enum ArgKind { | ||||
|  | ||||
| impl ArgData { | ||||
|     fn from_ast(arg: &crate::parsing::ast::types::Parameter) -> Self { | ||||
|         ArgData { | ||||
|         let mut result = ArgData { | ||||
|             name: arg.identifier.name.clone(), | ||||
|             ty: arg.type_.as_ref().map(|t| t.recast(&Default::default(), 0)), | ||||
|             // Doc comments are not yet supported on parameters. | ||||
|             ty: arg.type_.as_ref().map(|t| t.to_string()), | ||||
|             docs: None, | ||||
|             kind: if arg.labeled { | ||||
|                 ArgKind::Labelled(arg.optional()) | ||||
|             } else { | ||||
|                 ArgKind::Special | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
|         }; | ||||
|  | ||||
|     fn _with_meta(&mut self, _meta: &[Node<NonCodeNode>]) { | ||||
|         // TODO use comments for docs (we can't currently get the comments for an argument) | ||||
|         result.with_comments(&arg.identifier.pre_comments); | ||||
|         result | ||||
|     } | ||||
|  | ||||
|     pub fn get_autocomplete_snippet(&self, index: usize) -> Option<(usize, String)> { | ||||
|         match &self.ty { | ||||
|             Some(s) | ||||
|                 if [ | ||||
|                     "Sketch", | ||||
|                     "SketchSet", | ||||
|                     "Solid", | ||||
|                     "SolidSet", | ||||
|                     "SketchSurface", | ||||
|                     "SketchOrSurface", | ||||
|                 ] | ||||
|                 .contains(&&**s) => | ||||
|             { | ||||
|                 Some((index, format!("${{{}:{}}}", index, "%"))) | ||||
|         let label = if self.kind == ArgKind::Special { | ||||
|             String::new() | ||||
|         } else { | ||||
|             format!("{} = ", self.name) | ||||
|         }; | ||||
|         match self.ty.as_deref() { | ||||
|             Some(s) if ["Sketch", "Solid", "Plane | Face", "Sketch | Plane | Face"].contains(&s) => { | ||||
|                 Some((index, format!("{label}${{{}:{}}}", index, "%"))) | ||||
|             } | ||||
|             Some("number") if self.kind.required() => Some((index, format!(r#"{label}${{{}:3.14}}"#, index))), | ||||
|             Some("Point2d") if self.kind.required() => Some(( | ||||
|                 index + 1, | ||||
|                 format!(r#"{label}[${{{}:3.14}}, ${{{}:3.14}}]"#, index, index + 1), | ||||
|             )), | ||||
|             Some("Point3d") if self.kind.required() => Some(( | ||||
|                 index + 2, | ||||
|                 format!( | ||||
|                     r#"{label}[${{{}:3.14}}, ${{{}:3.14}}, ${{{}:3.14}}]"#, | ||||
|                     index, | ||||
|                     index + 1, | ||||
|                     index + 2 | ||||
|                 ), | ||||
|             )), | ||||
|             Some("string") if self.kind.required() => Some((index, format!(r#"{label}${{{}:"string"}}"#, index))), | ||||
|             Some("bool") if self.kind.required() => Some((index, format!(r#"{label}${{{}:false}}"#, index))), | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| @ -560,6 +583,7 @@ pub struct TyData { | ||||
|     /// The fully qualified name. | ||||
|     pub qual_name: String, | ||||
|     pub properties: Properties, | ||||
|     pub alias: Option<String>, | ||||
|  | ||||
|     /// The summary of the function. | ||||
|     pub summary: Option<String>, | ||||
| @ -568,12 +592,19 @@ pub struct TyData { | ||||
|     /// Code examples. | ||||
|     /// These are tested and we know they compile and execute. | ||||
|     pub examples: Vec<(String, ExampleProperties)>, | ||||
|     #[allow(dead_code)] | ||||
|     pub referenced_types: Vec<String>, | ||||
| } | ||||
|  | ||||
| impl TyData { | ||||
|     fn from_ast(ty: &crate::parsing::ast::types::TypeDeclaration, mut qual_name: String) -> Self { | ||||
|         let name = ty.name.name.clone(); | ||||
|         qual_name.push_str(&name); | ||||
|         let mut referenced_types = HashSet::new(); | ||||
|         if let Some(t) = &ty.alias { | ||||
|             collect_type_names(&mut referenced_types, t); | ||||
|         } | ||||
|  | ||||
|         TyData { | ||||
|             name, | ||||
|             qual_name, | ||||
| @ -583,9 +614,11 @@ impl TyData { | ||||
|                 doc_hidden: false, | ||||
|                 impl_kind: annotations::Impl::Kcl, | ||||
|             }, | ||||
|             alias: ty.alias.as_ref().map(|t| t.to_string()), | ||||
|             summary: None, | ||||
|             description: None, | ||||
|             examples: Vec::new(), | ||||
|             referenced_types: referenced_types.into_iter().collect(), | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -609,13 +642,16 @@ impl TyData { | ||||
|     fn to_completion_item(&self) -> CompletionItem { | ||||
|         CompletionItem { | ||||
|             label: self.name.clone(), | ||||
|             label_details: None, | ||||
|             label_details: self.alias.as_ref().map(|t| CompletionItemLabelDetails { | ||||
|                 detail: Some(format!("type {} = {t}", self.name)), | ||||
|                 description: None, | ||||
|             }), | ||||
|             kind: Some(CompletionItemKind::FUNCTION), | ||||
|             detail: Some(self.qual_name().to_owned()), | ||||
|             documentation: self.short_docs().map(|s| { | ||||
|                 Documentation::MarkupContent(MarkupContent { | ||||
|                     kind: MarkupKind::Markdown, | ||||
|                     value: s, | ||||
|                     value: remove_md_links(&s), | ||||
|                 }) | ||||
|             }), | ||||
|             deprecated: Some(self.properties.deprecated), | ||||
| @ -635,6 +671,11 @@ impl TyData { | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn remove_md_links(s: &str) -> String { | ||||
|     let re = Regex::new(r"\[([^\]]*)\]\([^\)]*\)").unwrap(); | ||||
|     re.replace_all(s, "$1").to_string() | ||||
| } | ||||
|  | ||||
| trait ApplyMeta { | ||||
|     fn apply_docs( | ||||
|         &mut self, | ||||
| @ -841,6 +882,66 @@ impl ApplyMeta for TyData { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ApplyMeta for ArgData { | ||||
|     fn apply_docs( | ||||
|         &mut self, | ||||
|         summary: Option<String>, | ||||
|         description: Option<String>, | ||||
|         _examples: Vec<(String, ExampleProperties)>, | ||||
|     ) { | ||||
|         let Some(mut docs) = summary else { | ||||
|             return; | ||||
|         }; | ||||
|         if let Some(desc) = description { | ||||
|             docs.push_str("\n\n"); | ||||
|             docs.push_str(&desc); | ||||
|         } | ||||
|  | ||||
|         self.docs = Some(docs); | ||||
|     } | ||||
|  | ||||
|     fn deprecated(&mut self, _deprecated: bool) { | ||||
|         unreachable!(); | ||||
|     } | ||||
|  | ||||
|     fn doc_hidden(&mut self, _doc_hidden: bool) { | ||||
|         unreachable!(); | ||||
|     } | ||||
|  | ||||
|     fn impl_kind(&mut self, _impl_kind: annotations::Impl) { | ||||
|         unreachable!(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn collect_type_names(acc: &mut HashSet<String>, ty: &Type) { | ||||
|     match ty { | ||||
|         Type::Primitive(primitive_type) => { | ||||
|             acc.insert(collect_type_names_from_primitive(primitive_type)); | ||||
|         } | ||||
|         Type::Array { ty, .. } => { | ||||
|             acc.insert(collect_type_names_from_primitive(ty)); | ||||
|         } | ||||
|         Type::Union { tys } => tys.iter().for_each(|t| { | ||||
|             acc.insert(collect_type_names_from_primitive(t)); | ||||
|         }), | ||||
|         Type::Object { properties } => properties.iter().for_each(|p| { | ||||
|             if let Some(t) = &p.type_ { | ||||
|                 collect_type_names(acc, t) | ||||
|             } | ||||
|         }), | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn collect_type_names_from_primitive(ty: &PrimitiveType) -> String { | ||||
|     match ty { | ||||
|         PrimitiveType::String => "string".to_owned(), | ||||
|         PrimitiveType::Number(_) => "number".to_owned(), | ||||
|         PrimitiveType::Boolean => "bool".to_owned(), | ||||
|         PrimitiveType::Tag => "tag".to_owned(), | ||||
|         PrimitiveType::Named(id) => id.name.clone(), | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
| mod test { | ||||
|     use super::*; | ||||
| @ -863,6 +964,24 @@ mod test { | ||||
|         panic!("didn't find PI"); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn test_remove_md_links() { | ||||
|         assert_eq!( | ||||
|             remove_md_links("sdf dsf sd fj sdk fasdfs. asad[sdfs] dfsdf(dsfs, dsf)"), | ||||
|             "sdf dsf sd fj sdk fasdfs. asad[sdfs] dfsdf(dsfs, dsf)".to_owned() | ||||
|         ); | ||||
|         assert_eq!(remove_md_links("[]()"), "".to_owned()); | ||||
|         assert_eq!(remove_md_links("[foo](bar)"), "foo".to_owned()); | ||||
|         assert_eq!( | ||||
|             remove_md_links("asdasda dsa[foo](http://www.bar/baz/qux.md). asdasdasdas asdas"), | ||||
|             "asdasda dsafoo. asdasdasdas asdas".to_owned() | ||||
|         ); | ||||
|         assert_eq!( | ||||
|             remove_md_links("a [foo](bar) b [2](bar) c [_](bar)"), | ||||
|             "a foo b 2 c _".to_owned() | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     #[tokio::test(flavor = "multi_thread", worker_threads = 5)] | ||||
|     async fn test_examples() -> miette::Result<()> { | ||||
|         let std = walk_prelude(); | ||||
|  | ||||
| @ -18,7 +18,7 @@ use tower_lsp::lsp_types::{ | ||||
| }; | ||||
|  | ||||
| use crate::{ | ||||
|     execution::{kcl_value::NumericType, Sketch}, | ||||
|     execution::{types::NumericType, Sketch}, | ||||
|     std::Primitive, | ||||
| }; | ||||
|  | ||||
| @ -926,6 +926,8 @@ fn get_autocomplete_string_from_schema(schema: &schemars::schema::Schema) -> Res | ||||
| mod tests { | ||||
|     use pretty_assertions::assert_eq; | ||||
|  | ||||
|     use crate::docs::kcl_doc::{self, DocData}; | ||||
|  | ||||
|     use super::StdLibFn; | ||||
|  | ||||
|     #[test] | ||||
| @ -1006,8 +1008,11 @@ mod tests { | ||||
|     #[test] | ||||
|     #[allow(clippy::literal_string_with_formatting_args)] | ||||
|     fn get_autocomplete_snippet_circle() { | ||||
|         let circle_fn: Box<dyn StdLibFn> = Box::new(crate::std::shapes::Circle); | ||||
|         let snippet = circle_fn.to_autocomplete_snippet().unwrap(); | ||||
|         let data = kcl_doc::walk_prelude(); | ||||
|         let DocData::Fn(circle_fn) = data.into_iter().find(|d| d.name() == "circle").unwrap() else { | ||||
|             panic!(); | ||||
|         }; | ||||
|         let snippet = circle_fn.to_autocomplete_snippet(); | ||||
|         assert_eq!( | ||||
|             snippet, | ||||
|             r#"circle(${0:%}, center = [${1:3.14}, ${2:3.14}], radius = ${3:3.14})${}"# | ||||
|  | ||||
							
								
								
									
										6
									
								
								rust/kcl-lib/src/docs/templates/kclType.hbs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								rust/kcl-lib/src/docs/templates/kclType.hbs
									
									
									
									
										vendored
									
									
								
							| @ -10,6 +10,12 @@ layout: manual | ||||
| {{/if}} | ||||
| {{{summary}}} | ||||
|  | ||||
| {{#if definition}} | ||||
| ```kcl | ||||
| {{{definition}}} | ||||
| ``` | ||||
|  | ||||
| {{/if}} | ||||
| {{{description}}} | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -6,7 +6,7 @@ use kittycad_modeling_cmds::coord::{System, KITTYCAD, OPENGL, VULKAN}; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::KclErrorDetails, | ||||
|     execution::kcl_value::{UnitAngle, UnitLen}, | ||||
|     execution::types::{UnitAngle, UnitLen}, | ||||
|     parsing::ast::types::{Annotation, Expr, Node, ObjectProperty}, | ||||
|     KclError, SourceRange, | ||||
| }; | ||||
|  | ||||
| @ -2,7 +2,7 @@ use indexmap::IndexMap; | ||||
| use schemars::JsonSchema; | ||||
| use serde::{Deserialize, Serialize}; | ||||
|  | ||||
| use super::{kcl_value::NumericType, ArtifactId, KclValue}; | ||||
| use super::{types::NumericType, ArtifactId, KclValue}; | ||||
| use crate::{docs::StdLibFn, std::get_stdlib_fn, SourceRange}; | ||||
|  | ||||
| /// A CAD modeling operation for display in the feature tree, AKA operations | ||||
|  | ||||
| @ -8,9 +8,10 @@ use crate::{ | ||||
|     execution::{ | ||||
|         annotations, | ||||
|         cad_op::{OpArg, OpKclValue, Operation}, | ||||
|         kcl_value::{FunctionSource, NumericType, RuntimeType}, | ||||
|         kcl_value::FunctionSource, | ||||
|         memory, | ||||
|         state::ModuleState, | ||||
|         types::{NumericType, RuntimeType}, | ||||
|         BodyType, EnvironmentRef, ExecState, ExecutorContext, KclValue, Metadata, PlaneType, TagEngineInfo, | ||||
|         TagIdentifier, | ||||
|     }, | ||||
| @ -29,6 +30,8 @@ use crate::{ | ||||
|     CompilationError, | ||||
| }; | ||||
|  | ||||
| use super::kcl_value::TypeDef; | ||||
|  | ||||
| enum StatementKind<'a> { | ||||
|     Declaration { name: &'a str }, | ||||
|     Expression, | ||||
| @ -304,8 +307,9 @@ impl ExecutorContext { | ||||
|                                     })); | ||||
|                                 } | ||||
|                             }; | ||||
|                             let (t, props) = crate::std::std_ty(std_path, &ty.name.name); | ||||
|                             let value = KclValue::Type { | ||||
|                                 value: Some(crate::std::std_ty(std_path, &ty.name.name)), | ||||
|                                 value: TypeDef::RustRepr(t, props), | ||||
|                                 meta: vec![metadata], | ||||
|                             }; | ||||
|                             exec_state | ||||
| @ -324,12 +328,40 @@ impl ExecutorContext { | ||||
|                         } | ||||
|                         // Do nothing for primitive types, they get special treatment and their declarations are just for documentation. | ||||
|                         annotations::Impl::Primitive => {} | ||||
|                         annotations::Impl::Kcl => { | ||||
|                         annotations::Impl::Kcl => match &ty.alias { | ||||
|                             Some(alias) => { | ||||
|                                 let value = KclValue::Type { | ||||
|                                     value: TypeDef::Alias( | ||||
|                                         RuntimeType::from_parsed( | ||||
|                                             alias.inner.clone(), | ||||
|                                             exec_state, | ||||
|                                             metadata.source_range, | ||||
|                                         ) | ||||
|                                         .map_err(|e| KclError::Semantic(e.into()))?, | ||||
|                                     ), | ||||
|                                     meta: vec![metadata], | ||||
|                                 }; | ||||
|                                 exec_state | ||||
|                                     .mut_stack() | ||||
|                                     .add( | ||||
|                                         format!("{}{}", memory::TYPE_PREFIX, ty.name.name), | ||||
|                                         value, | ||||
|                                         metadata.source_range, | ||||
|                                     ) | ||||
|                                     .map_err(|_| { | ||||
|                                         KclError::Semantic(KclErrorDetails { | ||||
|                                             message: format!("Redefinition of type {}.", ty.name.name), | ||||
|                                             source_ranges: vec![metadata.source_range], | ||||
|                                         }) | ||||
|                                     })?; | ||||
|                             } | ||||
|                             None => { | ||||
|                                 return Err(KclError::Semantic(KclErrorDetails { | ||||
|                                     message: "User-defined types are not yet supported.".to_owned(), | ||||
|                                     source_ranges: vec![metadata.source_range], | ||||
|                             })); | ||||
|                                 })) | ||||
|                             } | ||||
|                         }, | ||||
|                     } | ||||
|  | ||||
|                     last_expr = None; | ||||
| @ -578,7 +610,11 @@ impl ExecutorContext { | ||||
|                     if let Some(std_path) = &exec_state.mod_local.settings.std_path { | ||||
|                         let (func, props) = crate::std::std_fn(std_path, statement_kind.expect_name()); | ||||
|                         KclValue::Function { | ||||
|                             value: FunctionSource::Std { func, props }, | ||||
|                             value: FunctionSource::Std { | ||||
|                                 func, | ||||
|                                 props, | ||||
|                                 ast: function_expression.clone(), | ||||
|                             }, | ||||
|                             meta: vec![metadata.to_owned()], | ||||
|                         } | ||||
|                     } else { | ||||
| @ -646,30 +682,28 @@ impl ExecutorContext { | ||||
|                 let result = self | ||||
|                     .execute_expr(&expr.expr, exec_state, metadata, &[], statement_kind) | ||||
|                     .await?; | ||||
|                 coerce(&result, &expr.ty, exec_state).ok_or_else(|| { | ||||
|                     KclError::Semantic(KclErrorDetails { | ||||
|                         message: format!( | ||||
|                             "could not coerce {} value to type {}", | ||||
|                             result.human_friendly_type(), | ||||
|                             expr.ty | ||||
|                         ), | ||||
|                         source_ranges: vec![expr.into()], | ||||
|                     }) | ||||
|                 })? | ||||
|                 coerce(&result, &expr.ty, exec_state, expr.into())? | ||||
|             } | ||||
|         }; | ||||
|         Ok(item) | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn coerce(value: &KclValue, ty: &Node<Type>, exec_state: &mut ExecState) -> Option<KclValue> { | ||||
| fn coerce( | ||||
|     value: &KclValue, | ||||
|     ty: &Node<Type>, | ||||
|     exec_state: &mut ExecState, | ||||
|     source_range: SourceRange, | ||||
| ) -> Result<KclValue, KclError> { | ||||
|     let ty = RuntimeType::from_parsed(ty.inner.clone(), exec_state, value.into()) | ||||
|         .map_err(|e| { | ||||
|             exec_state.err(e); | ||||
|         }) | ||||
|         .ok()??; | ||||
|         .map_err(|e| KclError::Semantic(e.into()))?; | ||||
|  | ||||
|     value.coerce(&ty, exec_state) | ||||
|     value.coerce(&ty, exec_state).ok_or_else(|| { | ||||
|         KclError::Semantic(KclErrorDetails { | ||||
|             message: format!("could not coerce {} value to type {}", value.human_friendly_type(), ty), | ||||
|             source_ranges: vec![source_range], | ||||
|         }) | ||||
|     }) | ||||
| } | ||||
|  | ||||
| impl BinaryPart { | ||||
| @ -1088,10 +1122,35 @@ impl Node<CallExpressionKw> { | ||||
|                     None | ||||
|                 }; | ||||
|  | ||||
|                 let formals = func.args(false); | ||||
|                 #[allow(clippy::iter_over_hash_type)] | ||||
|                 for (label, arg) in &args.kw_args.labeled { | ||||
|                     match formals.iter().find(|p| &p.name == label) { | ||||
|                         Some(p) => { | ||||
|                             if !p.label_required { | ||||
|                                 exec_state.err(CompilationError::err( | ||||
|                                     arg.source_range, | ||||
|                                     format!( | ||||
|                                         "The function `{fn_name}` expects an unlabeled first parameter (`{label}`), but it is labelled in the call" | ||||
|                                     ), | ||||
|                                 )); | ||||
|                             } | ||||
|                         } | ||||
|                         None => { | ||||
|                             exec_state.err(CompilationError::err( | ||||
|                                 arg.source_range, | ||||
|                                 format!("`{label}` is not an argument of `{fn_name}`"), | ||||
|                             )); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 // Attempt to call the function. | ||||
|                 let mut return_value = { | ||||
|                     // Don't early-return in this block. | ||||
|                     exec_state.mut_stack().push_new_env_for_rust_call(); | ||||
|                     let result = func.std_lib_fn()(exec_state, args).await; | ||||
|                     exec_state.mut_stack().pop_env(); | ||||
|  | ||||
|                     if let Some(mut op) = op { | ||||
|                         op.set_std_lib_call_is_error(result.is_err()); | ||||
| @ -1110,10 +1169,9 @@ impl Node<CallExpressionKw> { | ||||
|                 Ok(return_value) | ||||
|             } | ||||
|             FunctionKind::UserDefined => { | ||||
|                 let source_range = SourceRange::from(self); | ||||
|                 // Clone the function so that we can use a mutable reference to | ||||
|                 // exec_state. | ||||
|                 let func = exec_state.stack().get(fn_name, source_range)?.clone(); | ||||
|                 let func = exec_state.stack().get(fn_name, callsite)?.clone(); | ||||
|  | ||||
|                 // Track call operation. | ||||
|                 let op_labeled_args = args | ||||
| @ -1134,17 +1192,21 @@ impl Node<CallExpressionKw> { | ||||
|                     source_range: callsite, | ||||
|                 }); | ||||
|  | ||||
|                 let return_value = func | ||||
|                     .call_fn_kw(args, exec_state, ctx.clone(), callsite) | ||||
|                     .await | ||||
|                     .map_err(|e| { | ||||
|                 let Some(fn_src) = func.as_fn() else { | ||||
|                     return Err(KclError::Semantic(KclErrorDetails { | ||||
|                         message: "cannot call this because it isn't a function".to_string(), | ||||
|                         source_ranges: vec![callsite], | ||||
|                     })); | ||||
|                 }; | ||||
|  | ||||
|                 let return_value = fn_src.call_kw(exec_state, ctx, args, callsite).await.map_err(|e| { | ||||
|                     // Add the call expression to the source ranges. | ||||
|                     // TODO currently ignored by the frontend | ||||
|                         e.add_source_ranges(vec![source_range]) | ||||
|                     e.add_source_ranges(vec![callsite]) | ||||
|                 })?; | ||||
|  | ||||
|                 let result = return_value.ok_or_else(move || { | ||||
|                     let mut source_ranges: Vec<SourceRange> = vec![source_range]; | ||||
|                     let mut source_ranges: Vec<SourceRange> = vec![callsite]; | ||||
|                     // We want to send the source range of the original function. | ||||
|                     if let KclValue::Function { meta, .. } = func { | ||||
|                         source_ranges = meta.iter().map(|m| m.source_range).collect(); | ||||
| @ -1261,10 +1323,13 @@ impl Node<CallExpression> { | ||||
|                     source_range: callsite, | ||||
|                 }); | ||||
|  | ||||
|                 let return_value = func | ||||
|                     .call_fn(fn_args, exec_state, ctx.clone(), source_range) | ||||
|                     .await | ||||
|                     .map_err(|e| { | ||||
|                 let Some(fn_src) = func.as_fn() else { | ||||
|                     return Err(KclError::Semantic(KclErrorDetails { | ||||
|                         message: "cannot call this because it isn't a function".to_string(), | ||||
|                         source_ranges: vec![source_range], | ||||
|                     })); | ||||
|                 }; | ||||
|                 let return_value = fn_src.call(exec_state, ctx, fn_args, source_range).await.map_err(|e| { | ||||
|                     // Add the call expression to the source ranges. | ||||
|                     // TODO currently ignored by the frontend | ||||
|                     e.add_source_ranges(vec![source_range]) | ||||
| @ -1754,6 +1819,28 @@ fn assign_args_to_params_kw( | ||||
|     mut args: crate::std::args::KwArgs, | ||||
|     exec_state: &mut ExecState, | ||||
| ) -> Result<(), KclError> { | ||||
|     #[allow(clippy::iter_over_hash_type)] | ||||
|     for (label, arg) in &args.labeled { | ||||
|         match function_expression.params.iter().find(|p| &p.identifier.name == label) { | ||||
|             Some(p) => { | ||||
|                 if !p.labeled { | ||||
|                     exec_state.err(CompilationError::err( | ||||
|                         arg.source_range, | ||||
|                         format!( | ||||
|                             "This function expects an unlabeled first parameter (`{label}`), but it is labelled in the call" | ||||
|                         ), | ||||
|                     )); | ||||
|                 } | ||||
|             } | ||||
|             None => { | ||||
|                 exec_state.err(CompilationError::err( | ||||
|                     arg.source_range, | ||||
|                     format!("`{label}` is not an argument of this function"), | ||||
|                 )); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Add the arguments to the memory.  A new call frame should have already | ||||
|     // been created. | ||||
|     let source_ranges = vec![function_expression.into()]; | ||||
| @ -1802,10 +1889,11 @@ fn assign_args_to_params_kw( | ||||
|             )?; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| pub(crate) async fn call_user_defined_function( | ||||
| async fn call_user_defined_function( | ||||
|     args: Vec<Arg>, | ||||
|     memory: EnvironmentRef, | ||||
|     function_expression: NodeRef<'_, FunctionExpression>, | ||||
| @ -1838,7 +1926,7 @@ pub(crate) async fn call_user_defined_function( | ||||
|     result | ||||
| } | ||||
|  | ||||
| pub(crate) async fn call_user_defined_function_kw( | ||||
| async fn call_user_defined_function_kw( | ||||
|     args: crate::std::args::KwArgs, | ||||
|     memory: EnvironmentRef, | ||||
|     function_expression: NodeRef<'_, FunctionExpression>, | ||||
| @ -1876,35 +1964,139 @@ impl FunctionSource { | ||||
|         &self, | ||||
|         exec_state: &mut ExecState, | ||||
|         ctx: &ExecutorContext, | ||||
|         args: Vec<Arg>, | ||||
|         source_range: SourceRange, | ||||
|         mut args: Vec<Arg>, | ||||
|         callsite: SourceRange, | ||||
|     ) -> Result<Option<KclValue>, KclError> { | ||||
|         match self { | ||||
|             FunctionSource::Std { func, props } => { | ||||
|             FunctionSource::Std { props, .. } => { | ||||
|                 if args.len() <= 1 { | ||||
|                     let args = crate::std::Args::new_kw( | ||||
|                         KwArgs { | ||||
|                             unlabeled: args.pop(), | ||||
|                             labeled: HashMap::new(), | ||||
|                         }, | ||||
|                         callsite, | ||||
|                         ctx.clone(), | ||||
|                         exec_state.mod_local.pipe_value.clone().map(|v| Arg::new(v, callsite)), | ||||
|                     ); | ||||
|                     self.call_kw(exec_state, ctx, args, callsite).await | ||||
|                 } else { | ||||
|                     Err(KclError::Semantic(KclErrorDetails { | ||||
|                         message: format!("{} requires its arguments to be labelled", props.name), | ||||
|                         source_ranges: vec![callsite], | ||||
|                     })) | ||||
|                 } | ||||
|             } | ||||
|             FunctionSource::User { ast, memory, .. } => { | ||||
|                 call_user_defined_function(args, *memory, ast, exec_state, ctx).await | ||||
|             } | ||||
|             FunctionSource::None => unreachable!(), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub async fn call_kw( | ||||
|         &self, | ||||
|         exec_state: &mut ExecState, | ||||
|         ctx: &ExecutorContext, | ||||
|         mut args: crate::std::Args, | ||||
|         callsite: SourceRange, | ||||
|     ) -> Result<Option<KclValue>, KclError> { | ||||
|         match self { | ||||
|             FunctionSource::Std { func, ast, props } => { | ||||
|                 if props.deprecated { | ||||
|                     exec_state.warn(CompilationError::err( | ||||
|                         source_range, | ||||
|                         callsite, | ||||
|                         format!( | ||||
|                             "`{}` is deprecated, see the docs for a recommended replacement", | ||||
|                             props.name | ||||
|                         ), | ||||
|                     )); | ||||
|                 } | ||||
|                 let args = crate::std::Args::new( | ||||
|                     args, | ||||
|                     source_range, | ||||
|                     ctx.clone(), | ||||
|                     exec_state | ||||
|                         .mod_local | ||||
|                         .pipe_value | ||||
|                         .clone() | ||||
|                         .map(|v| Arg::new(v, source_range)), | ||||
|                 ); | ||||
|  | ||||
|                 func(exec_state, args).await.map(Some) | ||||
|                 #[allow(clippy::iter_over_hash_type)] | ||||
|                 for (label, arg) in &mut args.kw_args.labeled { | ||||
|                     match ast.params.iter().find(|p| &p.identifier.name == label) { | ||||
|                         Some(p) => { | ||||
|                             if !p.labeled { | ||||
|                                 exec_state.err(CompilationError::err( | ||||
|                                     arg.source_range, | ||||
|                                     format!( | ||||
|                                         "The function `{}` expects an unlabeled first parameter (`{label}`), but it is labelled in the call", | ||||
|                                         props.name | ||||
|                                     ), | ||||
|                                 )); | ||||
|                             } | ||||
|  | ||||
|                             if let Some(ty) = &p.type_ { | ||||
|                                 arg.value = arg | ||||
|                                     .value | ||||
|                                     .coerce( | ||||
|                                         &RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range) | ||||
|                                             .unwrap(), | ||||
|                                         exec_state, | ||||
|                                     ) | ||||
|                                     .ok_or_else(|| { | ||||
|                                         KclError::Semantic(KclErrorDetails { | ||||
|                                             message: format!( | ||||
|                                                 "{label} requires a value with type `{}`, but found {}", | ||||
|                                                 ty.inner, | ||||
|                                                 arg.value.human_friendly_type() | ||||
|                                             ), | ||||
|                                             source_ranges: vec![callsite], | ||||
|                                         }) | ||||
|                                     })?; | ||||
|                             } | ||||
|                         } | ||||
|                         None => { | ||||
|                             exec_state.err(CompilationError::err( | ||||
|                                 arg.source_range, | ||||
|                                 format!("`{label}` is not an argument of `{}`", props.name), | ||||
|                             )); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if let Some(arg) = &mut args.kw_args.unlabeled { | ||||
|                     if let Some(p) = ast.params.iter().find(|p| !p.labeled) { | ||||
|                         if let Some(ty) = &p.type_ { | ||||
|                             arg.value = arg | ||||
|                                 .value | ||||
|                                 .coerce( | ||||
|                                     &RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range).unwrap(), | ||||
|                                     exec_state, | ||||
|                                 ) | ||||
|                                 .ok_or_else(|| { | ||||
|                                     KclError::Semantic(KclErrorDetails { | ||||
|                                         message: format!( | ||||
|                                             "The input argument of {} requires a value with type `{}`, but found {}", | ||||
|                                             props.name, | ||||
|                                             ty.inner, | ||||
|                                             arg.value.human_friendly_type() | ||||
|                                         ), | ||||
|                                         source_ranges: vec![callsite], | ||||
|                                     }) | ||||
|                                 })?; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 // Attempt to call the function. | ||||
|                 exec_state.mut_stack().push_new_env_for_rust_call(); | ||||
|                 let mut result = { | ||||
|                     // Don't early-return in this block. | ||||
|                     let result = func(exec_state, args).await; | ||||
|                     exec_state.mut_stack().pop_env(); | ||||
|  | ||||
|                     // TODO support recording op into the feature tree | ||||
|                     result | ||||
|                 }?; | ||||
|  | ||||
|                 update_memory_for_tags_of_geometry(&mut result, exec_state)?; | ||||
|  | ||||
|                 Ok(Some(result)) | ||||
|             } | ||||
|             FunctionSource::User { ast, memory, .. } => { | ||||
|                 call_user_defined_function(args, *memory, ast, exec_state, ctx).await | ||||
|                 call_user_defined_function_kw(args.kw_args, *memory, ast, exec_state, ctx).await | ||||
|             } | ||||
|             FunctionSource::None => unreachable!(), | ||||
|         } | ||||
|  | ||||
| @ -104,7 +104,7 @@ impl From<SolidOrSketchOrImportedGeometry> for crate::execution::KclValue { | ||||
|                             .into_iter() | ||||
|                             .map(|s| crate::execution::KclValue::Solid { value: Box::new(s) }) | ||||
|                             .collect(), | ||||
|                         ty: crate::execution::PrimitiveType::Solid, | ||||
|                         ty: crate::execution::types::RuntimeType::solid(), | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| @ -119,7 +119,7 @@ impl From<SolidOrSketchOrImportedGeometry> for crate::execution::KclValue { | ||||
|                             .into_iter() | ||||
|                             .map(|s| crate::execution::KclValue::Sketch { value: Box::new(s) }) | ||||
|                             .collect(), | ||||
|                         ty: crate::execution::PrimitiveType::Sketch, | ||||
|                         ty: crate::execution::types::RuntimeType::sketch(), | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @ -17,7 +17,7 @@ use uuid::Uuid; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{annotations, kcl_value::UnitLen, ExecState, ExecutorContext, ImportedGeometry}, | ||||
|     execution::{annotations, types::UnitLen, ExecState, ExecutorContext, ImportedGeometry}, | ||||
|     fs::FileSystem, | ||||
|     parsing::ast::types::{Annotation, Node}, | ||||
|     source_range::SourceRange, | ||||
|  | ||||
| @ -1,30 +1,21 @@ | ||||
| use std::{collections::HashMap, fmt}; | ||||
| use std::collections::HashMap; | ||||
|  | ||||
| use anyhow::Result; | ||||
| use schemars::JsonSchema; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use serde::Serialize; | ||||
|  | ||||
| use super::{ | ||||
|     memory::{self, EnvironmentRef}, | ||||
|     MetaSettings, Point3d, | ||||
| }; | ||||
| use super::{memory::EnvironmentRef, MetaSettings}; | ||||
| use crate::{ | ||||
|     errors::KclErrorDetails, | ||||
|     execution::{ | ||||
|         ExecState, ExecutorContext, Face, Helix, ImportedGeometry, Metadata, Plane, Sketch, Solid, TagIdentifier, | ||||
|         types::{NumericType, PrimitiveType, RuntimeType}, | ||||
|         Face, Helix, ImportedGeometry, Metadata, Plane, Sketch, Solid, TagIdentifier, | ||||
|     }, | ||||
|     parsing::{ | ||||
|         ast::types::{ | ||||
|             DefaultParamVal, FunctionExpression, KclNone, Literal, LiteralValue, Node, | ||||
|             PrimitiveType as AstPrimitiveType, TagDeclarator, TagNode, Type, | ||||
|     parsing::ast::types::{ | ||||
|         DefaultParamVal, FunctionExpression, KclNone, Literal, LiteralValue, Node, TagDeclarator, TagNode, | ||||
|     }, | ||||
|         token::NumericSuffix, | ||||
|     }, | ||||
|     std::{ | ||||
|         args::{Arg, FromKclValue}, | ||||
|         StdFnProps, | ||||
|     }, | ||||
|     CompilationError, KclError, ModuleId, SourceRange, | ||||
|     std::StdFnProps, | ||||
|     KclError, ModuleId, SourceRange, | ||||
| }; | ||||
|  | ||||
| pub type KclObjectFields = HashMap<String, KclValue>; | ||||
| @ -65,7 +56,7 @@ pub enum KclValue { | ||||
|         value: Vec<KclValue>, | ||||
|         // The type of values, not the array type. | ||||
|         #[serde(skip)] | ||||
|         ty: PrimitiveType, | ||||
|         ty: RuntimeType, | ||||
|     }, | ||||
|     Object { | ||||
|         value: KclObjectFields, | ||||
| @ -105,7 +96,7 @@ pub enum KclValue { | ||||
|     #[ts(skip)] | ||||
|     Type { | ||||
|         #[serde(skip)] | ||||
|         value: Option<(PrimitiveType, StdFnProps)>, | ||||
|         value: TypeDef, | ||||
|         #[serde(skip)] | ||||
|         meta: Vec<Metadata>, | ||||
|     }, | ||||
| @ -122,6 +113,7 @@ pub enum FunctionSource { | ||||
|     None, | ||||
|     Std { | ||||
|         func: crate::std::StdFn, | ||||
|         ast: crate::parsing::ast::types::BoxNode<FunctionExpression>, | ||||
|         props: StdFnProps, | ||||
|     }, | ||||
|     User { | ||||
| @ -142,6 +134,12 @@ impl JsonSchema for FunctionSource { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, PartialEq)] | ||||
| pub enum TypeDef { | ||||
|     RustRepr(PrimitiveType, StdFnProps), | ||||
|     Alias(RuntimeType), | ||||
| } | ||||
|  | ||||
| impl From<Vec<Sketch>> for KclValue { | ||||
|     fn from(mut eg: Vec<Sketch>) -> Self { | ||||
|         if eg.len() == 1 { | ||||
| @ -154,7 +152,7 @@ impl From<Vec<Sketch>> for KclValue { | ||||
|                     .into_iter() | ||||
|                     .map(|s| KclValue::Sketch { value: Box::new(s) }) | ||||
|                     .collect(), | ||||
|                 ty: crate::execution::PrimitiveType::Sketch, | ||||
|                 ty: RuntimeType::Primitive(PrimitiveType::Sketch), | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @ -169,7 +167,7 @@ impl From<Vec<Solid>> for KclValue { | ||||
|         } else { | ||||
|             KclValue::HomArray { | ||||
|                 value: eg.into_iter().map(|s| KclValue::Solid { value: Box::new(s) }).collect(), | ||||
|                 ty: crate::execution::PrimitiveType::Solid, | ||||
|                 ty: RuntimeType::Primitive(PrimitiveType::Solid), | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @ -553,347 +551,13 @@ impl KclValue { | ||||
|         Ok(*b) | ||||
|     } | ||||
|  | ||||
|     /// True if `self` has a type which is a subtype of `ty` without coercion. | ||||
|     pub fn has_type(&self, ty: &RuntimeType) -> bool { | ||||
|         let Some(self_ty) = self.principal_type() else { | ||||
|             return false; | ||||
|         }; | ||||
|  | ||||
|         self_ty.subtype(ty) | ||||
|     } | ||||
|  | ||||
|     /// Coerce `self` to a new value which has `ty` as it's closest supertype. | ||||
|     /// | ||||
|     /// If the result is Some, then: | ||||
|     ///   - result.principal_type().unwrap().subtype(ty) | ||||
|     /// | ||||
|     /// If self.principal_type() == ty then result == self | ||||
|     pub fn coerce(&self, ty: &RuntimeType, exec_state: &mut ExecState) -> Option<KclValue> { | ||||
|         match ty { | ||||
|             RuntimeType::Primitive(ty) => self.coerce_to_primitive_type(ty, exec_state), | ||||
|             RuntimeType::Array(ty, len) => self.coerce_to_array_type(ty, *len, exec_state), | ||||
|             RuntimeType::Tuple(tys) => self.coerce_to_tuple_type(tys, exec_state), | ||||
|             RuntimeType::Union(tys) => self.coerce_to_union_type(tys, exec_state), | ||||
|             RuntimeType::Object(tys) => self.coerce_to_object_type(tys, exec_state), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn coerce_to_primitive_type(&self, ty: &PrimitiveType, exec_state: &mut ExecState) -> Option<KclValue> { | ||||
|         let value = match self { | ||||
|             KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } if value.len() == 1 => &value[0], | ||||
|             _ => self, | ||||
|         }; | ||||
|         match ty { | ||||
|             // TODO numeric type coercions | ||||
|             PrimitiveType::Number(_ty) => match value { | ||||
|                 KclValue::Number { .. } => Some(value.clone()), | ||||
|                 _ => None, | ||||
|             }, | ||||
|             PrimitiveType::String => match value { | ||||
|                 KclValue::String { .. } => Some(value.clone()), | ||||
|                 _ => None, | ||||
|             }, | ||||
|             PrimitiveType::Boolean => match value { | ||||
|                 KclValue::Bool { .. } => Some(value.clone()), | ||||
|                 _ => None, | ||||
|             }, | ||||
|             PrimitiveType::Sketch => match value { | ||||
|                 KclValue::Sketch { .. } => Some(value.clone()), | ||||
|                 _ => None, | ||||
|             }, | ||||
|             PrimitiveType::Solid => match value { | ||||
|                 KclValue::Solid { .. } => Some(value.clone()), | ||||
|                 _ => None, | ||||
|             }, | ||||
|             PrimitiveType::Plane => match value { | ||||
|                 KclValue::Plane { .. } => Some(value.clone()), | ||||
|                 KclValue::Object { value, meta } => { | ||||
|                     let origin = value.get("origin").and_then(Point3d::from_kcl_val)?; | ||||
|                     let x_axis = value.get("xAxis").and_then(Point3d::from_kcl_val)?; | ||||
|                     let y_axis = value.get("yAxis").and_then(Point3d::from_kcl_val)?; | ||||
|                     let z_axis = value.get("zAxis").and_then(Point3d::from_kcl_val)?; | ||||
|  | ||||
|                     let id = exec_state.mod_local.id_generator.next_uuid(); | ||||
|                     let plane = Plane { | ||||
|                         id, | ||||
|                         artifact_id: id.into(), | ||||
|                         origin, | ||||
|                         x_axis, | ||||
|                         y_axis, | ||||
|                         z_axis, | ||||
|                         value: super::PlaneType::Uninit, | ||||
|                         // TODO use length unit from origin | ||||
|                         units: exec_state.length_unit(), | ||||
|                         meta: meta.clone(), | ||||
|                     }; | ||||
|  | ||||
|                     Some(KclValue::Plane { value: Box::new(plane) }) | ||||
|                 } | ||||
|                 _ => None, | ||||
|             }, | ||||
|             PrimitiveType::ImportedGeometry => match value { | ||||
|                 KclValue::ImportedGeometry { .. } => Some(value.clone()), | ||||
|                 _ => None, | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn coerce_to_array_type(&self, ty: &PrimitiveType, len: ArrayLen, exec_state: &mut ExecState) -> Option<KclValue> { | ||||
|     pub fn as_fn(&self) -> Option<&FunctionSource> { | ||||
|         match self { | ||||
|             KclValue::HomArray { value, ty: aty } => { | ||||
|                 // TODO could check types of values individually | ||||
|                 if aty != ty { | ||||
|                     return None; | ||||
|                 } | ||||
|  | ||||
|                 let value = match len { | ||||
|                     ArrayLen::None => value.clone(), | ||||
|                     ArrayLen::NonEmpty => { | ||||
|                         if value.is_empty() { | ||||
|                             return None; | ||||
|                         } | ||||
|  | ||||
|                         value.clone() | ||||
|                     } | ||||
|                     ArrayLen::Known(n) => { | ||||
|                         if n != value.len() { | ||||
|                             return None; | ||||
|                         } | ||||
|  | ||||
|                         value[..n].to_vec() | ||||
|                     } | ||||
|                 }; | ||||
|  | ||||
|                 Some(KclValue::HomArray { value, ty: ty.clone() }) | ||||
|             } | ||||
|             KclValue::MixedArray { value, .. } => { | ||||
|                 let value = match len { | ||||
|                     ArrayLen::None => value.clone(), | ||||
|                     ArrayLen::NonEmpty => { | ||||
|                         if value.is_empty() { | ||||
|                             return None; | ||||
|                         } | ||||
|  | ||||
|                         value.clone() | ||||
|                     } | ||||
|                     ArrayLen::Known(n) => { | ||||
|                         if n != value.len() { | ||||
|                             return None; | ||||
|                         } | ||||
|  | ||||
|                         value[..n].to_vec() | ||||
|                     } | ||||
|                 }; | ||||
|  | ||||
|                 let rt = RuntimeType::Primitive(ty.clone()); | ||||
|                 let value = value | ||||
|                     .iter() | ||||
|                     .map(|v| v.coerce(&rt, exec_state)) | ||||
|                     .collect::<Option<Vec<_>>>()?; | ||||
|  | ||||
|                 Some(KclValue::HomArray { value, ty: ty.clone() }) | ||||
|             } | ||||
|             KclValue::KclNone { .. } if len.satisfied(0) => Some(KclValue::HomArray { | ||||
|                 value: Vec::new(), | ||||
|                 ty: ty.clone(), | ||||
|             }), | ||||
|             value if len.satisfied(1) => { | ||||
|                 if value.has_type(&RuntimeType::Primitive(ty.clone())) { | ||||
|                     Some(KclValue::HomArray { | ||||
|                         value: vec![value.clone()], | ||||
|                         ty: ty.clone(), | ||||
|                     }) | ||||
|                 } else { | ||||
|                     None | ||||
|                 } | ||||
|             } | ||||
|             KclValue::Function { value, .. } => Some(value), | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn coerce_to_tuple_type(&self, tys: &[PrimitiveType], exec_state: &mut ExecState) -> Option<KclValue> { | ||||
|         match self { | ||||
|             KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } => { | ||||
|                 if value.len() < tys.len() { | ||||
|                     return None; | ||||
|                 } | ||||
|                 let mut result = Vec::new(); | ||||
|                 for (i, t) in tys.iter().enumerate() { | ||||
|                     result.push(value[i].coerce_to_primitive_type(t, exec_state)?); | ||||
|                 } | ||||
|  | ||||
|                 Some(KclValue::MixedArray { | ||||
|                     value: result, | ||||
|                     meta: Vec::new(), | ||||
|                 }) | ||||
|             } | ||||
|             KclValue::KclNone { meta, .. } if tys.is_empty() => Some(KclValue::MixedArray { | ||||
|                 value: Vec::new(), | ||||
|                 meta: meta.clone(), | ||||
|             }), | ||||
|             value if tys.len() == 1 => { | ||||
|                 if value.has_type(&RuntimeType::Primitive(tys[0].clone())) { | ||||
|                     Some(KclValue::MixedArray { | ||||
|                         value: vec![value.clone()], | ||||
|                         meta: Vec::new(), | ||||
|                     }) | ||||
|                 } else { | ||||
|                     None | ||||
|                 } | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn coerce_to_union_type(&self, tys: &[RuntimeType], exec_state: &mut ExecState) -> Option<KclValue> { | ||||
|         for t in tys { | ||||
|             if let Some(v) = self.coerce(t, exec_state) { | ||||
|                 return Some(v); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         None | ||||
|     } | ||||
|  | ||||
|     fn coerce_to_object_type(&self, tys: &[(String, RuntimeType)], _exec_state: &mut ExecState) -> Option<KclValue> { | ||||
|         match self { | ||||
|             KclValue::Object { value, .. } => { | ||||
|                 for (s, t) in tys { | ||||
|                     // TODO coerce fields | ||||
|                     if !value.get(s)?.has_type(t) { | ||||
|                         return None; | ||||
|                     } | ||||
|                 } | ||||
|                 // TODO remove non-required fields | ||||
|                 Some(self.clone()) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn principal_type(&self) -> Option<RuntimeType> { | ||||
|         match self { | ||||
|             KclValue::Bool { .. } => Some(RuntimeType::Primitive(PrimitiveType::Boolean)), | ||||
|             KclValue::Number { ty, .. } => Some(RuntimeType::Primitive(PrimitiveType::Number(ty.clone()))), | ||||
|             KclValue::String { .. } => Some(RuntimeType::Primitive(PrimitiveType::String)), | ||||
|             KclValue::Object { value, .. } => { | ||||
|                 let properties = value | ||||
|                     .iter() | ||||
|                     .map(|(k, v)| v.principal_type().map(|t| (k.clone(), t))) | ||||
|                     .collect::<Option<Vec<_>>>()?; | ||||
|                 Some(RuntimeType::Object(properties)) | ||||
|             } | ||||
|             KclValue::Plane { .. } => Some(RuntimeType::Primitive(PrimitiveType::Plane)), | ||||
|             KclValue::Sketch { .. } => Some(RuntimeType::Primitive(PrimitiveType::Sketch)), | ||||
|             KclValue::Solid { .. } => Some(RuntimeType::Primitive(PrimitiveType::Solid)), | ||||
|             KclValue::ImportedGeometry(..) => Some(RuntimeType::Primitive(PrimitiveType::ImportedGeometry)), | ||||
|             KclValue::MixedArray { value, .. } => Some(RuntimeType::Tuple( | ||||
|                 value | ||||
|                     .iter() | ||||
|                     .map(|v| v.principal_type().and_then(RuntimeType::primitive)) | ||||
|                     .collect::<Option<Vec<_>>>()?, | ||||
|             )), | ||||
|             KclValue::HomArray { ty, value, .. } => Some(RuntimeType::Array(ty.clone(), ArrayLen::Known(value.len()))), | ||||
|             KclValue::Face { .. } => None, | ||||
|             KclValue::Helix { .. } | ||||
|             | KclValue::Function { .. } | ||||
|             | KclValue::Module { .. } | ||||
|             | KclValue::TagIdentifier(_) | ||||
|             | KclValue::TagDeclarator(_) | ||||
|             | KclValue::KclNone { .. } | ||||
|             | KclValue::Type { .. } | ||||
|             | KclValue::Uuid { .. } => None, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// If this memory item is a function, call it with the given arguments, return its val as Ok. | ||||
|     /// If it's not a function, return Err. | ||||
|     pub async fn call_fn( | ||||
|         &self, | ||||
|         args: Vec<Arg>, | ||||
|         exec_state: &mut ExecState, | ||||
|         ctx: ExecutorContext, | ||||
|         source_range: SourceRange, | ||||
|     ) -> Result<Option<KclValue>, KclError> { | ||||
|         match self { | ||||
|             KclValue::Function { | ||||
|                 value: FunctionSource::Std { func, props }, | ||||
|                 .. | ||||
|             } => { | ||||
|                 if props.deprecated { | ||||
|                     exec_state.warn(CompilationError::err( | ||||
|                         source_range, | ||||
|                         format!( | ||||
|                             "`{}` is deprecated, see the docs for a recommended replacement", | ||||
|                             props.name | ||||
|                         ), | ||||
|                     )); | ||||
|                 } | ||||
|                 exec_state.mut_stack().push_new_env_for_rust_call(); | ||||
|                 let args = crate::std::Args::new( | ||||
|                     args, | ||||
|                     source_range, | ||||
|                     ctx.clone(), | ||||
|                     exec_state | ||||
|                         .mod_local | ||||
|                         .pipe_value | ||||
|                         .clone() | ||||
|                         .map(|v| Arg::new(v, source_range)), | ||||
|                 ); | ||||
|                 let result = func(exec_state, args).await.map(Some); | ||||
|                 exec_state.mut_stack().pop_env(); | ||||
|                 result | ||||
|             } | ||||
|             KclValue::Function { | ||||
|                 value: FunctionSource::User { ast, memory, .. }, | ||||
|                 .. | ||||
|             } => crate::execution::exec_ast::call_user_defined_function(args, *memory, ast, exec_state, &ctx).await, | ||||
|             _ => Err(KclError::Semantic(KclErrorDetails { | ||||
|                 message: "cannot call this because it isn't a function".to_string(), | ||||
|                 source_ranges: vec![source_range], | ||||
|             })), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// If this is a function, call it by applying keyword arguments. | ||||
|     /// If it's not a function, returns an error. | ||||
|     pub async fn call_fn_kw( | ||||
|         &self, | ||||
|         args: crate::std::Args, | ||||
|         exec_state: &mut ExecState, | ||||
|         ctx: ExecutorContext, | ||||
|         callsite: SourceRange, | ||||
|     ) -> Result<Option<KclValue>, KclError> { | ||||
|         match self { | ||||
|             KclValue::Function { | ||||
|                 value: FunctionSource::Std { func: _, props }, | ||||
|                 .. | ||||
|             } => { | ||||
|                 if props.deprecated { | ||||
|                     exec_state.warn(CompilationError::err( | ||||
|                         callsite, | ||||
|                         format!( | ||||
|                             "`{}` is deprecated, see the docs for a recommended replacement", | ||||
|                             props.name | ||||
|                         ), | ||||
|                     )); | ||||
|                 } | ||||
|                 todo!("Implement KCL stdlib fns with keyword args"); | ||||
|             } | ||||
|             KclValue::Function { | ||||
|                 value: FunctionSource::User { ast, memory, .. }, | ||||
|                 .. | ||||
|             } => { | ||||
|                 crate::execution::exec_ast::call_user_defined_function_kw(args.kw_args, *memory, ast, exec_state, &ctx) | ||||
|                     .await | ||||
|             } | ||||
|             _ => Err(KclError::Semantic(KclErrorDetails { | ||||
|                 message: "cannot call this because it isn't a function".to_string(), | ||||
|                 source_ranges: vec![callsite], | ||||
|             })), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn value_str(&self) -> Option<String> { | ||||
|         match self { | ||||
|             KclValue::Bool { value, .. } => Some(format!("{value}")), | ||||
| @ -919,447 +583,3 @@ impl KclValue { | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, PartialEq)] | ||||
| pub enum RuntimeType { | ||||
|     Primitive(PrimitiveType), | ||||
|     Array(PrimitiveType, ArrayLen), | ||||
|     Union(Vec<RuntimeType>), | ||||
|     Tuple(Vec<PrimitiveType>), | ||||
|     Object(Vec<(String, RuntimeType)>), | ||||
| } | ||||
|  | ||||
| impl RuntimeType { | ||||
|     pub fn from_parsed( | ||||
|         value: Type, | ||||
|         exec_state: &mut ExecState, | ||||
|         source_range: SourceRange, | ||||
|     ) -> Result<Option<Self>, CompilationError> { | ||||
|         Ok(match value { | ||||
|             Type::Primitive(pt) => { | ||||
|                 PrimitiveType::from_parsed(pt, exec_state, source_range)?.map(RuntimeType::Primitive) | ||||
|             } | ||||
|             Type::Array(pt) => { | ||||
|                 PrimitiveType::from_parsed(pt, exec_state, source_range)?.map(|t| RuntimeType::Array(t, ArrayLen::None)) | ||||
|             } | ||||
|             Type::Object { properties } => properties | ||||
|                 .into_iter() | ||||
|                 .map(|p| { | ||||
|                     let pt = match p.type_ { | ||||
|                         Some(t) => t, | ||||
|                         None => return Ok(None), | ||||
|                     }; | ||||
|                     Ok(RuntimeType::from_parsed(pt.inner, exec_state, source_range)? | ||||
|                         .map(|ty| (p.identifier.inner.name, ty))) | ||||
|                 }) | ||||
|                 .collect::<Result<Option<Vec<_>>, CompilationError>>()? | ||||
|                 .map(RuntimeType::Object), | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     pub fn human_friendly_type(&self) -> String { | ||||
|         match self { | ||||
|             RuntimeType::Primitive(ty) => ty.to_string(), | ||||
|             RuntimeType::Array(ty, ArrayLen::None) => format!("an array of {}", ty.display_multiple()), | ||||
|             RuntimeType::Array(ty, ArrayLen::NonEmpty) => format!("one or more {}", ty.display_multiple()), | ||||
|             RuntimeType::Array(ty, ArrayLen::Known(n)) => format!("an array of {n} {}", ty.display_multiple()), | ||||
|             RuntimeType::Union(tys) => tys | ||||
|                 .iter() | ||||
|                 .map(Self::human_friendly_type) | ||||
|                 .collect::<Vec<_>>() | ||||
|                 .join(" or "), | ||||
|             RuntimeType::Tuple(tys) => format!( | ||||
|                 "an array with values of types ({})", | ||||
|                 tys.iter().map(PrimitiveType::to_string).collect::<Vec<_>>().join(", ") | ||||
|             ), | ||||
|             RuntimeType::Object(_) => format!("an object with fields {}", self), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Subtype with no coercion, including refining numeric types. | ||||
|     fn subtype(&self, sup: &RuntimeType) -> bool { | ||||
|         use RuntimeType::*; | ||||
|  | ||||
|         match (self, sup) { | ||||
|             (Primitive(t1), Primitive(t2)) => t1 == t2, | ||||
|             // TODO arrays could be covariant | ||||
|             (Array(t1, l1), Array(t2, l2)) => t1 == t2 && l1.subtype(*l2), | ||||
|             (Tuple(t1), Tuple(t2)) => t1 == t2, | ||||
|             (Tuple(t1), Array(t2, l2)) => (l2.satisfied(t1.len())) && t1.iter().all(|t| t == t2), | ||||
|             (Union(ts1), Union(ts2)) => ts1.iter().all(|t| ts2.contains(t)), | ||||
|             (t1, Union(ts2)) => ts2.contains(t1), | ||||
|             // TODO record subtyping - subtype can be larger, fields can be covariant. | ||||
|             (Object(t1), Object(t2)) => t1 == t2, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn primitive(self) -> Option<PrimitiveType> { | ||||
|         match self { | ||||
|             RuntimeType::Primitive(t) => Some(t), | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl fmt::Display for RuntimeType { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||
|         match self { | ||||
|             RuntimeType::Primitive(t) => t.fmt(f), | ||||
|             RuntimeType::Array(t, l) => match l { | ||||
|                 ArrayLen::None => write!(f, "[{t}]"), | ||||
|                 ArrayLen::NonEmpty => write!(f, "[{t}; 1+]"), | ||||
|                 ArrayLen::Known(n) => write!(f, "[{t}; {n}]"), | ||||
|             }, | ||||
|             RuntimeType::Tuple(ts) => write!( | ||||
|                 f, | ||||
|                 "[{}]", | ||||
|                 ts.iter().map(|t| t.to_string()).collect::<Vec<_>>().join(", ") | ||||
|             ), | ||||
|             RuntimeType::Union(ts) => write!( | ||||
|                 f, | ||||
|                 "{}", | ||||
|                 ts.iter().map(|t| t.to_string()).collect::<Vec<_>>().join(" | ") | ||||
|             ), | ||||
|             RuntimeType::Object(items) => write!( | ||||
|                 f, | ||||
|                 "{{ {} }}", | ||||
|                 items | ||||
|                     .iter() | ||||
|                     .map(|(n, t)| format!("{n}: {t}")) | ||||
|                     .collect::<Vec<_>>() | ||||
|                     .join(", ") | ||||
|             ), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Copy, PartialEq)] | ||||
| pub enum ArrayLen { | ||||
|     None, | ||||
|     NonEmpty, | ||||
|     Known(usize), | ||||
| } | ||||
|  | ||||
| impl ArrayLen { | ||||
|     pub fn subtype(self, other: ArrayLen) -> bool { | ||||
|         match (self, other) { | ||||
|             (_, ArrayLen::None) => true, | ||||
|             (ArrayLen::NonEmpty, ArrayLen::NonEmpty) => true, | ||||
|             (ArrayLen::Known(size), ArrayLen::NonEmpty) if size > 0 => true, | ||||
|             (ArrayLen::Known(s1), ArrayLen::Known(s2)) if s1 == s2 => true, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// True if the length constraint is satisfied by the supplied length. | ||||
|     fn satisfied(self, len: usize) -> bool { | ||||
|         match self { | ||||
|             ArrayLen::None => true, | ||||
|             ArrayLen::NonEmpty => len > 0, | ||||
|             ArrayLen::Known(s) => len == s, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, PartialEq)] | ||||
| pub enum PrimitiveType { | ||||
|     Number(NumericType), | ||||
|     String, | ||||
|     Boolean, | ||||
|     Sketch, | ||||
|     Solid, | ||||
|     Plane, | ||||
|     ImportedGeometry, | ||||
| } | ||||
|  | ||||
| impl PrimitiveType { | ||||
|     fn from_parsed( | ||||
|         value: AstPrimitiveType, | ||||
|         exec_state: &mut ExecState, | ||||
|         source_range: SourceRange, | ||||
|     ) -> Result<Option<Self>, CompilationError> { | ||||
|         Ok(match value { | ||||
|             AstPrimitiveType::String => Some(PrimitiveType::String), | ||||
|             AstPrimitiveType::Boolean => Some(PrimitiveType::Boolean), | ||||
|             AstPrimitiveType::Number(suffix) => Some(PrimitiveType::Number(NumericType::from_parsed( | ||||
|                 suffix, | ||||
|                 &exec_state.mod_local.settings, | ||||
|             ))), | ||||
|             AstPrimitiveType::Named(name) => { | ||||
|                 let ty_val = exec_state | ||||
|                     .stack() | ||||
|                     .get(&format!("{}{}", memory::TYPE_PREFIX, name.name), source_range) | ||||
|                     .map_err(|_| CompilationError::err(source_range, format!("Unknown type: {}", name.name)))?; | ||||
|  | ||||
|                 let (ty, _) = match ty_val { | ||||
|                     KclValue::Type { value: Some(ty), .. } => ty, | ||||
|                     _ => unreachable!(), | ||||
|                 }; | ||||
|  | ||||
|                 Some(ty.clone()) | ||||
|             } | ||||
|             _ => None, | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     fn display_multiple(&self) -> String { | ||||
|         match self { | ||||
|             PrimitiveType::Number(NumericType::Known(unit)) => format!("numbers({unit})"), | ||||
|             PrimitiveType::Number(_) => "numbers".to_owned(), | ||||
|             PrimitiveType::String => "strings".to_owned(), | ||||
|             PrimitiveType::Boolean => "bools".to_owned(), | ||||
|             PrimitiveType::Sketch => "Sketches".to_owned(), | ||||
|             PrimitiveType::Solid => "Solids".to_owned(), | ||||
|             PrimitiveType::Plane => "Planes".to_owned(), | ||||
|             PrimitiveType::ImportedGeometry => "imported geometries".to_owned(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl fmt::Display for PrimitiveType { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||
|         match self { | ||||
|             PrimitiveType::Number(NumericType::Known(unit)) => write!(f, "number({unit})"), | ||||
|             PrimitiveType::Number(_) => write!(f, "number"), | ||||
|             PrimitiveType::String => write!(f, "string"), | ||||
|             PrimitiveType::Boolean => write!(f, "bool"), | ||||
|             PrimitiveType::Sketch => write!(f, "Sketch"), | ||||
|             PrimitiveType::Solid => write!(f, "Solid"), | ||||
|             PrimitiveType::Plane => write!(f, "Plane"), | ||||
|             PrimitiveType::ImportedGeometry => write!(f, "imported geometry"), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] | ||||
| #[ts(export)] | ||||
| #[serde(tag = "type")] | ||||
| pub enum NumericType { | ||||
|     // Specified by the user (directly or indirectly) | ||||
|     Known(UnitType), | ||||
|     // Unspecified, using defaults | ||||
|     Default { len: UnitLen, angle: UnitAngle }, | ||||
|     // Exceeded the ability of the type system to track. | ||||
|     Unknown, | ||||
|     // Type info has been explicitly cast away. | ||||
|     Any, | ||||
| } | ||||
|  | ||||
| impl NumericType { | ||||
|     pub fn count() -> Self { | ||||
|         NumericType::Known(UnitType::Count) | ||||
|     } | ||||
|  | ||||
|     /// Combine two types when we expect them to be equal. | ||||
|     pub fn combine_eq(self, other: &NumericType) -> NumericType { | ||||
|         if &self == other { | ||||
|             self | ||||
|         } else { | ||||
|             NumericType::Unknown | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Combine n types when we expect them to be equal. | ||||
|     /// | ||||
|     /// Precondition: tys.len() > 0 | ||||
|     pub fn combine_n_eq(tys: &[NumericType]) -> NumericType { | ||||
|         let ty0 = tys[0].clone(); | ||||
|         for t in &tys[1..] { | ||||
|             if t != &ty0 { | ||||
|                 return NumericType::Unknown; | ||||
|             } | ||||
|         } | ||||
|         ty0 | ||||
|     } | ||||
|  | ||||
|     /// Combine two types in addition-like operations. | ||||
|     pub fn combine_add(a: NumericType, b: NumericType) -> NumericType { | ||||
|         if a == b { | ||||
|             return a; | ||||
|         } | ||||
|         NumericType::Unknown | ||||
|     } | ||||
|  | ||||
|     /// Combine two types in multiplication-like operations. | ||||
|     pub fn combine_mul(a: NumericType, b: NumericType) -> NumericType { | ||||
|         if a == NumericType::count() { | ||||
|             return b; | ||||
|         } | ||||
|         if b == NumericType::count() { | ||||
|             return a; | ||||
|         } | ||||
|         NumericType::Unknown | ||||
|     } | ||||
|  | ||||
|     /// Combine two types in division-like operations. | ||||
|     pub fn combine_div(a: NumericType, b: NumericType) -> NumericType { | ||||
|         if b == NumericType::count() { | ||||
|             return a; | ||||
|         } | ||||
|         NumericType::Unknown | ||||
|     } | ||||
|  | ||||
|     pub fn from_parsed(suffix: NumericSuffix, settings: &super::MetaSettings) -> Self { | ||||
|         match suffix { | ||||
|             NumericSuffix::None => NumericType::Default { | ||||
|                 len: settings.default_length_units, | ||||
|                 angle: settings.default_angle_units, | ||||
|             }, | ||||
|             NumericSuffix::Count => NumericType::Known(UnitType::Count), | ||||
|             NumericSuffix::Mm => NumericType::Known(UnitType::Length(UnitLen::Mm)), | ||||
|             NumericSuffix::Cm => NumericType::Known(UnitType::Length(UnitLen::Cm)), | ||||
|             NumericSuffix::M => NumericType::Known(UnitType::Length(UnitLen::M)), | ||||
|             NumericSuffix::Inch => NumericType::Known(UnitType::Length(UnitLen::Inches)), | ||||
|             NumericSuffix::Ft => NumericType::Known(UnitType::Length(UnitLen::Feet)), | ||||
|             NumericSuffix::Yd => NumericType::Known(UnitType::Length(UnitLen::Yards)), | ||||
|             NumericSuffix::Deg => NumericType::Known(UnitType::Angle(UnitAngle::Degrees)), | ||||
|             NumericSuffix::Rad => NumericType::Known(UnitType::Angle(UnitAngle::Radians)), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl From<UnitLen> for NumericType { | ||||
|     fn from(value: UnitLen) -> Self { | ||||
|         NumericType::Known(UnitType::Length(value)) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl From<UnitAngle> for NumericType { | ||||
|     fn from(value: UnitAngle) -> Self { | ||||
|         NumericType::Known(UnitType::Angle(value)) | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, ts_rs::TS, JsonSchema)] | ||||
| #[ts(export)] | ||||
| #[serde(tag = "type")] | ||||
| pub enum UnitType { | ||||
|     Count, | ||||
|     Length(UnitLen), | ||||
|     Angle(UnitAngle), | ||||
| } | ||||
|  | ||||
| impl std::fmt::Display for UnitType { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         match self { | ||||
|             UnitType::Count => write!(f, "_"), | ||||
|             UnitType::Length(l) => l.fmt(f), | ||||
|             UnitType::Angle(a) => a.fmt(f), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| // TODO called UnitLen so as not to clash with UnitLength in settings) | ||||
| /// A unit of length. | ||||
| #[derive(Debug, Default, Clone, Copy, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq)] | ||||
| #[ts(export)] | ||||
| #[serde(tag = "type")] | ||||
| pub enum UnitLen { | ||||
|     #[default] | ||||
|     Mm, | ||||
|     Cm, | ||||
|     M, | ||||
|     Inches, | ||||
|     Feet, | ||||
|     Yards, | ||||
| } | ||||
|  | ||||
| impl std::fmt::Display for UnitLen { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         match self { | ||||
|             UnitLen::Mm => write!(f, "mm"), | ||||
|             UnitLen::Cm => write!(f, "cm"), | ||||
|             UnitLen::M => write!(f, "m"), | ||||
|             UnitLen::Inches => write!(f, "in"), | ||||
|             UnitLen::Feet => write!(f, "ft"), | ||||
|             UnitLen::Yards => write!(f, "yd"), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl TryFrom<NumericSuffix> for UnitLen { | ||||
|     type Error = (); | ||||
|  | ||||
|     fn try_from(suffix: NumericSuffix) -> std::result::Result<Self, Self::Error> { | ||||
|         match suffix { | ||||
|             NumericSuffix::Mm => Ok(Self::Mm), | ||||
|             NumericSuffix::Cm => Ok(Self::Cm), | ||||
|             NumericSuffix::M => Ok(Self::M), | ||||
|             NumericSuffix::Inch => Ok(Self::Inches), | ||||
|             NumericSuffix::Ft => Ok(Self::Feet), | ||||
|             NumericSuffix::Yd => Ok(Self::Yards), | ||||
|             _ => Err(()), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl From<crate::UnitLength> for UnitLen { | ||||
|     fn from(unit: crate::UnitLength) -> Self { | ||||
|         match unit { | ||||
|             crate::UnitLength::Cm => UnitLen::Cm, | ||||
|             crate::UnitLength::Ft => UnitLen::Feet, | ||||
|             crate::UnitLength::In => UnitLen::Inches, | ||||
|             crate::UnitLength::M => UnitLen::M, | ||||
|             crate::UnitLength::Mm => UnitLen::Mm, | ||||
|             crate::UnitLength::Yd => UnitLen::Yards, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl From<UnitLen> for crate::UnitLength { | ||||
|     fn from(unit: UnitLen) -> Self { | ||||
|         match unit { | ||||
|             UnitLen::Cm => crate::UnitLength::Cm, | ||||
|             UnitLen::Feet => crate::UnitLength::Ft, | ||||
|             UnitLen::Inches => crate::UnitLength::In, | ||||
|             UnitLen::M => crate::UnitLength::M, | ||||
|             UnitLen::Mm => crate::UnitLength::Mm, | ||||
|             UnitLen::Yards => crate::UnitLength::Yd, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl From<UnitLen> for kittycad_modeling_cmds::units::UnitLength { | ||||
|     fn from(unit: UnitLen) -> Self { | ||||
|         match unit { | ||||
|             UnitLen::Cm => kittycad_modeling_cmds::units::UnitLength::Centimeters, | ||||
|             UnitLen::Feet => kittycad_modeling_cmds::units::UnitLength::Feet, | ||||
|             UnitLen::Inches => kittycad_modeling_cmds::units::UnitLength::Inches, | ||||
|             UnitLen::M => kittycad_modeling_cmds::units::UnitLength::Meters, | ||||
|             UnitLen::Mm => kittycad_modeling_cmds::units::UnitLength::Millimeters, | ||||
|             UnitLen::Yards => kittycad_modeling_cmds::units::UnitLength::Yards, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// A unit of angle. | ||||
| #[derive(Debug, Default, Clone, Copy, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq)] | ||||
| #[ts(export)] | ||||
| #[serde(tag = "type")] | ||||
| pub enum UnitAngle { | ||||
|     #[default] | ||||
|     Degrees, | ||||
|     Radians, | ||||
| } | ||||
|  | ||||
| impl std::fmt::Display for UnitAngle { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         match self { | ||||
|             UnitAngle::Degrees => write!(f, "deg"), | ||||
|             UnitAngle::Radians => write!(f, "rad"), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl TryFrom<NumericSuffix> for UnitAngle { | ||||
|     type Error = (); | ||||
|  | ||||
|     fn try_from(suffix: NumericSuffix) -> std::result::Result<Self, Self::Error> { | ||||
|         match suffix { | ||||
|             NumericSuffix::Deg => Ok(Self::Degrees), | ||||
|             NumericSuffix::Rad => Ok(Self::Radians), | ||||
|             _ => Err(()), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1055,7 +1055,7 @@ mod env { | ||||
| #[cfg(test)] | ||||
| mod test { | ||||
|     use super::*; | ||||
|     use crate::execution::kcl_value::{FunctionSource, NumericType}; | ||||
|     use crate::execution::{kcl_value::FunctionSource, types::NumericType}; | ||||
|  | ||||
|     fn sr() -> SourceRange { | ||||
|         SourceRange::default() | ||||
|  | ||||
| @ -15,7 +15,7 @@ pub(crate) use import::{ | ||||
|     import_foreign, send_to_engine as send_import_to_engine, PreImportedGeometry, ZOO_COORD_SYSTEM, | ||||
| }; | ||||
| use indexmap::IndexMap; | ||||
| pub use kcl_value::{KclObjectFields, KclValue, PrimitiveType, UnitAngle, UnitLen}; | ||||
| pub use kcl_value::{KclObjectFields, KclValue}; | ||||
| use kcmc::{ | ||||
|     each_cmd as mcmd, | ||||
|     ok_response::{output::TakeSnapshot, OkModelingCmdResponse}, | ||||
| @ -34,6 +34,7 @@ use crate::{ | ||||
|     execution::{ | ||||
|         artifact::build_artifact_graph, | ||||
|         cache::{CacheInformation, CacheResult}, | ||||
|         types::{UnitAngle, UnitLen}, | ||||
|     }, | ||||
|     fs::FileManager, | ||||
|     modules::{ModuleId, ModulePath}, | ||||
| @ -55,6 +56,7 @@ mod import; | ||||
| pub(crate) mod kcl_value; | ||||
| mod memory; | ||||
| mod state; | ||||
| pub(crate) mod types; | ||||
|  | ||||
| /// Outcome of executing a program.  This is used in TS. | ||||
| #[derive(Debug, Clone, Serialize, ts_rs::TS)] | ||||
| @ -1397,6 +1399,22 @@ const answer = returnX()"#; | ||||
|         assert!(errs.is_empty()); | ||||
|     } | ||||
|  | ||||
|     #[tokio::test(flavor = "multi_thread")] | ||||
|     async fn type_aliases() { | ||||
|         let text = r#"type MyTy = [number; 2] | ||||
| fn foo(x: MyTy) { | ||||
|     return x[0] | ||||
| } | ||||
|  | ||||
| foo([0, 1]) | ||||
|  | ||||
| type Other = MyTy | Helix | ||||
| "#; | ||||
|         let result = parse_execute(text).await.unwrap(); | ||||
|         let errs = result.exec_state.errors(); | ||||
|         assert!(errs.is_empty()); | ||||
|     } | ||||
|  | ||||
|     #[tokio::test(flavor = "multi_thread")] | ||||
|     async fn test_cannot_shebang_in_fn() { | ||||
|         let ast = r#" | ||||
|  | ||||
| @ -12,10 +12,9 @@ use crate::{ | ||||
|     execution::{ | ||||
|         annotations, | ||||
|         id_generator::IdGenerator, | ||||
|         kcl_value, | ||||
|         memory::{ProgramMemory, Stack}, | ||||
|         Artifact, ArtifactCommand, ArtifactGraph, ArtifactId, EnvironmentRef, ExecOutcome, ExecutorSettings, KclValue, | ||||
|         Operation, UnitAngle, UnitLen, | ||||
|         types, Artifact, ArtifactCommand, ArtifactGraph, ArtifactId, EnvironmentRef, ExecOutcome, ExecutorSettings, | ||||
|         KclValue, Operation, UnitAngle, UnitLen, | ||||
|     }, | ||||
|     modules::{ModuleId, ModuleInfo, ModuleLoader, ModulePath, ModuleRepr, ModuleSource}, | ||||
|     parsing::ast::types::Annotation, | ||||
| @ -310,8 +309,8 @@ impl ModuleState { | ||||
| #[ts(export)] | ||||
| #[serde(rename_all = "camelCase")] | ||||
| pub struct MetaSettings { | ||||
|     pub default_length_units: kcl_value::UnitLen, | ||||
|     pub default_angle_units: kcl_value::UnitAngle, | ||||
|     pub default_length_units: types::UnitLen, | ||||
|     pub default_angle_units: types::UnitAngle, | ||||
|     pub std_path: Option<String>, | ||||
| } | ||||
|  | ||||
| @ -326,12 +325,12 @@ impl MetaSettings { | ||||
|             match &*p.inner.key.name { | ||||
|                 annotations::SETTINGS_UNIT_LENGTH => { | ||||
|                     let value = annotations::expect_ident(&p.inner.value)?; | ||||
|                     let value = kcl_value::UnitLen::from_str(value, annotation.as_source_range())?; | ||||
|                     let value = types::UnitLen::from_str(value, annotation.as_source_range())?; | ||||
|                     self.default_length_units = value; | ||||
|                 } | ||||
|                 annotations::SETTINGS_UNIT_ANGLE => { | ||||
|                     let value = annotations::expect_ident(&p.inner.value)?; | ||||
|                     let value = kcl_value::UnitAngle::from_str(value, annotation.as_source_range())?; | ||||
|                     let value = types::UnitAngle::from_str(value, annotation.as_source_range())?; | ||||
|                     self.default_angle_units = value; | ||||
|                 } | ||||
|                 name => { | ||||
|  | ||||
							
								
								
									
										1254
									
								
								rust/kcl-lib/src/execution/types.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1254
									
								
								rust/kcl-lib/src/execution/types.rs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -344,8 +344,8 @@ impl Node<Type> { | ||||
|         let range = self.as_source_range(); | ||||
|         if range.contains(pos) { | ||||
|             match &self.inner { | ||||
|                 Type::Array(t) | Type::Primitive(t) => { | ||||
|                     let mut name = t.to_string(); | ||||
|                 Type::Array { ty, .. } | Type::Primitive(ty) => { | ||||
|                     let mut name = ty.to_string(); | ||||
|                     if name.ends_with(')') { | ||||
|                         name.truncate(name.find('(').unwrap()); | ||||
|                     } | ||||
| @ -379,7 +379,7 @@ impl FunctionExpression { | ||||
|         if let Some(value) = self.body.get_expr_for_position(pos) { | ||||
|             let mut vars = opts.vars.clone().unwrap_or_default(); | ||||
|             for arg in &self.params { | ||||
|                 let ty = arg.type_.as_ref().map(|ty| ty.recast(&FormatOptions::default(), 0)); | ||||
|                 let ty = arg.type_.as_ref().map(|ty| ty.to_string()); | ||||
|                 vars.insert(arg.identifier.inner.name.clone(), ty); | ||||
|             } | ||||
|             return value.get_hover_value_for_position( | ||||
|  | ||||
| @ -1900,7 +1900,7 @@ async fn test_kcl_lsp_diagnostic_has_errors() { | ||||
|             assert_eq!(diagnostics.full_document_diagnostic_report.items.len(), 1); | ||||
|             assert_eq!( | ||||
|                 diagnostics.full_document_diagnostic_report.items[0].message, | ||||
|                 "lexical: found unknown token ';'" | ||||
|                 "Unexpected token: ;" | ||||
|             ); | ||||
|         } else { | ||||
|             panic!("Expected full diagnostics"); | ||||
|  | ||||
| @ -87,6 +87,7 @@ pub(crate) fn read_std(mod_name: &str) -> Option<&'static str> { | ||||
|     match mod_name { | ||||
|         "prelude" => Some(include_str!("../std/prelude.kcl")), | ||||
|         "math" => Some(include_str!("../std/math.kcl")), | ||||
|         "sketch" => Some(include_str!("../std/sketch.kcl")), | ||||
|         _ => None, | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -194,9 +194,21 @@ impl Type { | ||||
|                 hasher.update(b"FnArgType::Primitive"); | ||||
|                 hasher.update(prim.compute_digest()) | ||||
|             } | ||||
|             Type::Array(prim) => { | ||||
|             Type::Array { ty, len } => { | ||||
|                 hasher.update(b"FnArgType::Array"); | ||||
|                 hasher.update(prim.compute_digest()) | ||||
|                 hasher.update(ty.compute_digest()); | ||||
|                 match len { | ||||
|                     crate::execution::types::ArrayLen::None => {} | ||||
|                     crate::execution::types::ArrayLen::NonEmpty => hasher.update(usize::MAX.to_ne_bytes()), | ||||
|                     crate::execution::types::ArrayLen::Known(n) => hasher.update(n.to_ne_bytes()), | ||||
|                 } | ||||
|             } | ||||
|             Type::Union { tys } => { | ||||
|                 hasher.update(b"FnArgType::Union"); | ||||
|                 hasher.update(tys.len().to_ne_bytes()); | ||||
|                 for t in tys.iter_mut() { | ||||
|                     hasher.update(t.compute_digest()); | ||||
|                 } | ||||
|             } | ||||
|             Type::Object { properties } => { | ||||
|                 hasher.update(b"FnArgType::Object"); | ||||
| @ -300,6 +312,9 @@ impl TypeDeclaration { | ||||
|                 hasher.update(a.compute_digest()); | ||||
|             } | ||||
|         } | ||||
|         if let Some(alias) = &mut slf.alias { | ||||
|             hasher.update(alias.compute_digest()); | ||||
|         } | ||||
|     }); | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -25,7 +25,7 @@ pub use crate::parsing::ast::types::{ | ||||
| use crate::{ | ||||
|     docs::StdLibFn, | ||||
|     errors::KclError, | ||||
|     execution::{annotations, KclValue, Metadata, TagIdentifier}, | ||||
|     execution::{annotations, types::ArrayLen, KclValue, Metadata, TagIdentifier}, | ||||
|     parsing::{ast::digest::Digest, token::NumericSuffix, PIPE_OPERATOR}, | ||||
|     source_range::SourceRange, | ||||
|     ModuleId, | ||||
| @ -150,7 +150,7 @@ impl<T> Node<T> { | ||||
|         self.start <= pos && pos <= self.end | ||||
|     } | ||||
|  | ||||
|     pub fn map<U>(self, f: fn(T) -> U) -> Node<U> { | ||||
|     pub fn map<U>(self, f: impl Fn(T) -> U) -> Node<U> { | ||||
|         Node { | ||||
|             inner: f(self.inner), | ||||
|             start: self.start, | ||||
| @ -1895,6 +1895,7 @@ pub struct TypeDeclaration { | ||||
|     pub args: Option<NodeList<Identifier>>, | ||||
|     #[serde(default, skip_serializing_if = "ItemVisibility::is_default")] | ||||
|     pub visibility: ItemVisibility, | ||||
|     pub alias: Option<Node<Type>>, | ||||
|  | ||||
|     #[serde(default, skip_serializing_if = "Option::is_none")] | ||||
|     #[ts(optional)] | ||||
| @ -3024,7 +3025,14 @@ pub enum Type { | ||||
|     /// A primitive type. | ||||
|     Primitive(PrimitiveType), | ||||
|     // An array of a primitive type. | ||||
|     Array(PrimitiveType), | ||||
|     Array { | ||||
|         ty: PrimitiveType, | ||||
|         len: ArrayLen, | ||||
|     }, | ||||
|     // Union/enum types | ||||
|     Union { | ||||
|         tys: NodeList<PrimitiveType>, | ||||
|     }, | ||||
|     // An object type. | ||||
|     Object { | ||||
|         properties: Vec<Parameter>, | ||||
| @ -3035,7 +3043,22 @@ impl fmt::Display for Type { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||
|         match self { | ||||
|             Type::Primitive(primitive_type) => primitive_type.fmt(f), | ||||
|             Type::Array(primitive_type) => write!(f, "[{primitive_type}]"), | ||||
|             Type::Array { ty, len } => { | ||||
|                 write!(f, "[{ty}")?; | ||||
|                 match len { | ||||
|                     ArrayLen::None => {} | ||||
|                     ArrayLen::NonEmpty => write!(f, "; 1+")?, | ||||
|                     ArrayLen::Known(n) => write!(f, "; {n}")?, | ||||
|                 } | ||||
|                 write!(f, "]") | ||||
|             } | ||||
|             Type::Union { tys } => { | ||||
|                 write!( | ||||
|                     f, | ||||
|                     "{}", | ||||
|                     tys.iter().map(|t| t.to_string()).collect::<Vec<_>>().join(" | ") | ||||
|                 ) | ||||
|             } | ||||
|             Type::Object { properties } => { | ||||
|                 write!(f, "{{")?; | ||||
|                 let mut first = true; | ||||
| @ -3624,11 +3647,17 @@ const cylinder = startSketchOn('-XZ') | ||||
|         assert_eq!(params.len(), 3); | ||||
|         assert_eq!( | ||||
|             params[0].type_.as_ref().unwrap().inner, | ||||
|             Type::Array(PrimitiveType::Number(NumericSuffix::None)) | ||||
|             Type::Array { | ||||
|                 ty: PrimitiveType::Number(NumericSuffix::None), | ||||
|                 len: ArrayLen::None | ||||
|             } | ||||
|         ); | ||||
|         assert_eq!( | ||||
|             params[1].type_.as_ref().unwrap().inner, | ||||
|             Type::Array(PrimitiveType::String) | ||||
|             Type::Array { | ||||
|                 ty: PrimitiveType::String, | ||||
|                 len: ArrayLen::None | ||||
|             } | ||||
|         ); | ||||
|         assert_eq!( | ||||
|             params[2].type_.as_ref().unwrap().inner, | ||||
| @ -3656,7 +3685,10 @@ const cylinder = startSketchOn('-XZ') | ||||
|         assert_eq!(params.len(), 3); | ||||
|         assert_eq!( | ||||
|             params[0].type_.as_ref().unwrap().inner, | ||||
|             Type::Array(PrimitiveType::Number(NumericSuffix::None)) | ||||
|             Type::Array { | ||||
|                 ty: PrimitiveType::Number(NumericSuffix::None), | ||||
|                 len: ArrayLen::None | ||||
|             } | ||||
|         ); | ||||
|         assert_eq!( | ||||
|             params[1].type_.as_ref().unwrap().inner, | ||||
| @ -3692,7 +3724,15 @@ const cylinder = startSketchOn('-XZ') | ||||
|                             56, | ||||
|                             module_id, | ||||
|                         ), | ||||
|                         type_: Some(Node::new(Type::Array(PrimitiveType::String), 59, 65, module_id)), | ||||
|                         type_: Some(Node::new( | ||||
|                             Type::Array { | ||||
|                                 ty: PrimitiveType::String, | ||||
|                                 len: ArrayLen::None | ||||
|                             }, | ||||
|                             59, | ||||
|                             65, | ||||
|                             module_id | ||||
|                         )), | ||||
|                         default_value: None, | ||||
|                         labeled: true, | ||||
|                         digest: None | ||||
| @ -3773,7 +3813,15 @@ const cylinder = startSketchOn('-XZ') | ||||
|                             34, | ||||
|                             module_id, | ||||
|                         ), | ||||
|                         type_: Some(Node::new(Type::Array(PrimitiveType::String), 37, 43, module_id)), | ||||
|                         type_: Some(Node::new( | ||||
|                             Type::Array { | ||||
|                                 ty: PrimitiveType::String, | ||||
|                                 len: ArrayLen::None | ||||
|                             }, | ||||
|                             37, | ||||
|                             43, | ||||
|                             module_id | ||||
|                         )), | ||||
|                         default_value: None, | ||||
|                         labeled: true, | ||||
|                         digest: None | ||||
| @ -3946,7 +3994,7 @@ startSketchOn('XY')"#; | ||||
|  | ||||
|         assert_eq!( | ||||
|             meta_settings.default_length_units, | ||||
|             crate::execution::kcl_value::UnitLen::Inches | ||||
|             crate::execution::types::UnitLen::Inches | ||||
|         ); | ||||
|     } | ||||
|  | ||||
| @ -3962,13 +4010,13 @@ startSketchOn('XY')"#; | ||||
|  | ||||
|         assert_eq!( | ||||
|             meta_settings.default_length_units, | ||||
|             crate::execution::kcl_value::UnitLen::Inches | ||||
|             crate::execution::types::UnitLen::Inches | ||||
|         ); | ||||
|  | ||||
|         // Edit the ast. | ||||
|         let new_program = program | ||||
|             .change_meta_settings(crate::execution::MetaSettings { | ||||
|                 default_length_units: crate::execution::kcl_value::UnitLen::Mm, | ||||
|                 default_length_units: crate::execution::types::UnitLen::Mm, | ||||
|                 ..Default::default() | ||||
|             }) | ||||
|             .unwrap(); | ||||
| @ -3977,10 +4025,7 @@ startSketchOn('XY')"#; | ||||
|         assert!(result.is_some()); | ||||
|         let meta_settings = result.unwrap(); | ||||
|  | ||||
|         assert_eq!( | ||||
|             meta_settings.default_length_units, | ||||
|             crate::execution::kcl_value::UnitLen::Mm | ||||
|         ); | ||||
|         assert_eq!(meta_settings.default_length_units, crate::execution::types::UnitLen::Mm); | ||||
|  | ||||
|         let formatted = new_program.recast(&Default::default(), 0); | ||||
|  | ||||
| @ -4003,7 +4048,7 @@ startSketchOn('XY') | ||||
|         // Edit the ast. | ||||
|         let new_program = program | ||||
|             .change_meta_settings(crate::execution::MetaSettings { | ||||
|                 default_length_units: crate::execution::kcl_value::UnitLen::Mm, | ||||
|                 default_length_units: crate::execution::types::UnitLen::Mm, | ||||
|                 ..Default::default() | ||||
|             }) | ||||
|             .unwrap(); | ||||
| @ -4012,10 +4057,7 @@ startSketchOn('XY') | ||||
|         assert!(result.is_some()); | ||||
|         let meta_settings = result.unwrap(); | ||||
|  | ||||
|         assert_eq!( | ||||
|             meta_settings.default_length_units, | ||||
|             crate::execution::kcl_value::UnitLen::Mm | ||||
|         ); | ||||
|         assert_eq!(meta_settings.default_length_units, crate::execution::types::UnitLen::Mm); | ||||
|  | ||||
|         let formatted = new_program.recast(&Default::default(), 0); | ||||
|  | ||||
|  | ||||
| @ -19,6 +19,7 @@ use super::{ | ||||
| use crate::{ | ||||
|     docs::StdLibFn, | ||||
|     errors::{CompilationError, Severity, Tag}, | ||||
|     execution::types::ArrayLen, | ||||
|     parsing::{ | ||||
|         ast::types::{ | ||||
|             Annotation, ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryOperator, BinaryPart, BodyItem, | ||||
| @ -2215,7 +2216,7 @@ fn ty_decl(i: &mut TokenSlice) -> PResult<BoxNode<TypeDeclaration>> { | ||||
|     let name = identifier(i)?; | ||||
|     let mut end = name.end; | ||||
|  | ||||
|     let args = if peek(open_paren).parse_next(i).is_ok() { | ||||
|     let args = if peek((opt(whitespace), open_paren)).parse_next(i).is_ok() { | ||||
|         ignore_whitespace(i); | ||||
|         open_paren(i)?; | ||||
|         ignore_whitespace(i); | ||||
| @ -2228,11 +2229,28 @@ fn ty_decl(i: &mut TokenSlice) -> PResult<BoxNode<TypeDeclaration>> { | ||||
|         None | ||||
|     }; | ||||
|  | ||||
|     let alias = if peek((opt(whitespace), equals)).parse_next(i).is_ok() { | ||||
|         ignore_whitespace(i); | ||||
|         equals(i)?; | ||||
|         ignore_whitespace(i); | ||||
|         let ty = argument_type(i)?; | ||||
|  | ||||
|         ParseContext::warn(CompilationError::err( | ||||
|             ty.as_source_range(), | ||||
|             "Type aliases are experimental, likely to change in the future, and likely to not work properly.", | ||||
|         )); | ||||
|  | ||||
|         Some(ty) | ||||
|     } else { | ||||
|         None | ||||
|     }; | ||||
|  | ||||
|     let module_id = name.module_id; | ||||
|     let result = Node::boxed( | ||||
|         TypeDeclaration { | ||||
|             name, | ||||
|             args, | ||||
|             alias, | ||||
|             visibility, | ||||
|             digest: None, | ||||
|         }, | ||||
| @ -2336,21 +2354,7 @@ impl TryFrom<Token> for Node<TagDeclarator> { | ||||
|                 format!("Cannot assign a tag to a reserved keyword: {}", token.value.as_str()), | ||||
|             )), | ||||
|  | ||||
|             TokenType::Bang | ||||
|             | TokenType::At | ||||
|             | TokenType::Hash | ||||
|             | TokenType::Colon | ||||
|             | TokenType::Period | ||||
|             | TokenType::Operator | ||||
|             | TokenType::DoublePeriod | ||||
|             | TokenType::QuestionMark | ||||
|             | TokenType::BlockComment | ||||
|             | TokenType::Function | ||||
|             | TokenType::String | ||||
|             | TokenType::Dollar | ||||
|             | TokenType::Keyword | ||||
|             | TokenType::Unknown | ||||
|             | TokenType::LineComment => Err(CompilationError::fatal( | ||||
|             _ => Err(CompilationError::fatal( | ||||
|                 token.as_source_range(), | ||||
|                 // this is `start with` because if most of these cases are in the middle, it ends | ||||
|                 // up hitting a different error path(e.g. including a bang) or being valid(e.g. including a comment) since it will get broken up into | ||||
| @ -2617,6 +2621,14 @@ fn colon(i: &mut TokenSlice) -> PResult<Token> { | ||||
|     TokenType::Colon.parse_from(i) | ||||
| } | ||||
|  | ||||
| fn semi_colon(i: &mut TokenSlice) -> PResult<Token> { | ||||
|     TokenType::SemiColon.parse_from(i) | ||||
| } | ||||
|  | ||||
| fn plus(i: &mut TokenSlice) -> PResult<Token> { | ||||
|     one_of((TokenType::Operator, "+")).parse_next(i) | ||||
| } | ||||
|  | ||||
| fn equals(i: &mut TokenSlice) -> PResult<Token> { | ||||
|     one_of((TokenType::Operator, "=")) | ||||
|         .context(expected("the equals operator, =")) | ||||
| @ -2659,6 +2671,12 @@ fn comma_sep(i: &mut TokenSlice) -> PResult<()> { | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| /// Parse a `|`, optionally followed by some whitespace. | ||||
| fn pipe_sep(i: &mut TokenSlice) -> PResult<()> { | ||||
|     (opt(whitespace), one_of((TokenType::Operator, "|")), opt(whitespace)).parse_next(i)?; | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| /// Arguments are passed into a function. | ||||
| fn arguments(i: &mut TokenSlice) -> PResult<Vec<Expr>> { | ||||
|     separated(0.., expression, comma_sep) | ||||
| @ -2685,7 +2703,15 @@ fn argument_type(i: &mut TokenSlice) -> PResult<Node<Type>> { | ||||
|     let type_ = alt(( | ||||
|         // Object types | ||||
|         // TODO it is buggy to treat object fields like parameters since the parameters parser assumes a terminating `)`. | ||||
|         (open_brace, parameters, close_brace).map(|(open, params, close)| { | ||||
|         (open_brace, parameters, close_brace).try_map(|(open, params, close)| { | ||||
|             for p in ¶ms { | ||||
|                 if p.type_.is_none() { | ||||
|                     return Err(CompilationError::fatal( | ||||
|                         p.identifier.as_source_range(), | ||||
|                         "Missing type for field in record type", | ||||
|                     )); | ||||
|                 } | ||||
|             } | ||||
|             Ok(Node::new( | ||||
|                 Type::Object { properties: params }, | ||||
|                 open.start, | ||||
| @ -2694,12 +2720,21 @@ fn argument_type(i: &mut TokenSlice) -> PResult<Node<Type>> { | ||||
|             )) | ||||
|         }), | ||||
|         // Array types | ||||
|         (open_bracket, primitive_type, close_bracket).map(|(_, t, _)| Ok(t.map(Type::Array))), | ||||
|         // Primitive types | ||||
|         primitive_type.map(|t| Ok(t.map(Type::Primitive))), | ||||
|         array_type, | ||||
|         // Primitive or union types | ||||
|         separated(1.., primitive_type, pipe_sep).map(|mut tys: Vec<_>| { | ||||
|             if tys.len() == 1 { | ||||
|                 tys.pop().unwrap().map(Type::Primitive) | ||||
|             } else { | ||||
|                 let start = tys[0].start; | ||||
|                 let module_id = tys[0].module_id; | ||||
|                 let end = tys.last().unwrap().end; | ||||
|                 Node::new(Type::Union { tys }, start, end, module_id) | ||||
|             } | ||||
|         }), | ||||
|     )) | ||||
|     .parse_next(i)? | ||||
|     .map_err(|e: CompilationError| ErrMode::Backtrack(ContextError::from(e)))?; | ||||
|     .parse_next(i)?; | ||||
|  | ||||
|     Ok(type_) | ||||
| } | ||||
|  | ||||
| @ -2721,19 +2756,93 @@ fn primitive_type(i: &mut TokenSlice) -> PResult<Node<PrimitiveType>> { | ||||
|     Ok(result) | ||||
| } | ||||
|  | ||||
| fn array_type(i: &mut TokenSlice) -> PResult<Node<Type>> { | ||||
|     fn opt_whitespace(i: &mut TokenSlice) -> PResult<()> { | ||||
|         ignore_whitespace(i); | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     open_bracket(i)?; | ||||
|     let ty = primitive_type(i)?; | ||||
|     let len = opt(( | ||||
|         semi_colon, | ||||
|         opt_whitespace, | ||||
|         any.try_map(|token: Token| match token.token_type { | ||||
|             TokenType::Number => { | ||||
|                 let value = token.uint_value().ok_or_else(|| { | ||||
|                     CompilationError::fatal( | ||||
|                         token.as_source_range(), | ||||
|                         format!("Expected unsigned integer literal, found: {}", token.value), | ||||
|                     ) | ||||
|                 })?; | ||||
|  | ||||
|                 Ok(value as usize) | ||||
|             } | ||||
|             _ => Err(CompilationError::fatal(token.as_source_range(), "invalid array length")), | ||||
|         }), | ||||
|         opt(plus), | ||||
|     )) | ||||
|     .parse_next(i)?; | ||||
|     close_bracket(i)?; | ||||
|  | ||||
|     let len = if let Some((tok, _, n, plus)) = len { | ||||
|         if plus.is_some() { | ||||
|             if n != 1 { | ||||
|                 return Err(ErrMode::Cut(ContextError::from(CompilationError::fatal( | ||||
|                     tok.as_source_range(), | ||||
|                     "Non-empty arrays are specified using `1+`, for a fixed-size array use just an integer", | ||||
|                 )))); | ||||
|             } else { | ||||
|                 ArrayLen::NonEmpty | ||||
|             } | ||||
|         } else { | ||||
|             ArrayLen::Known(n) | ||||
|         } | ||||
|     } else { | ||||
|         ArrayLen::None | ||||
|     }; | ||||
|  | ||||
|     Ok(ty.map(|ty| Type::Array { ty, len })) | ||||
| } | ||||
|  | ||||
| fn uom_for_type(i: &mut TokenSlice) -> PResult<NumericSuffix> { | ||||
|     any.try_map(|t: Token| t.value.parse()).parse_next(i) | ||||
| } | ||||
|  | ||||
| fn comment(i: &mut TokenSlice) -> PResult<Node<String>> { | ||||
|     any.verify_map(|token: Token| { | ||||
|         let value = match token.token_type { | ||||
|             TokenType::LineComment => token.value, | ||||
|             TokenType::BlockComment => token.value, | ||||
|             _ => return None, | ||||
|         }; | ||||
|         Some(Node::new(value, token.start, token.end, token.module_id)) | ||||
|     }) | ||||
|     .context(expected("Comment")) | ||||
|     .parse_next(i) | ||||
| } | ||||
|  | ||||
| fn comments(i: &mut TokenSlice) -> PResult<Node<Vec<String>>> { | ||||
|     let comments: Vec<Node<String>> = repeat(1.., (comment, opt(whitespace)).map(|(c, _)| c)).parse_next(i)?; | ||||
|     let start = comments[0].start; | ||||
|     let module_id = comments[0].module_id; | ||||
|     let end = comments.last().unwrap().end; | ||||
|     let inner = comments.into_iter().map(|n| n.inner).collect(); | ||||
|     Ok(Node::new(inner, start, end, module_id)) | ||||
| } | ||||
|  | ||||
| struct ParamDescription { | ||||
|     labeled: bool, | ||||
|     arg_name: Token, | ||||
|     type_: std::option::Option<Node<Type>>, | ||||
|     default_value: Option<DefaultParamVal>, | ||||
|     comments: Option<Node<Vec<String>>>, | ||||
| } | ||||
|  | ||||
| fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> { | ||||
|     let (found_at_sign, arg_name, question_mark, _, type_, _ws, default_literal) = ( | ||||
|     let (_, comments, found_at_sign, arg_name, question_mark, _, type_, _ws, default_literal) = ( | ||||
|         opt(whitespace), | ||||
|         opt(comments), | ||||
|         opt(at_sign), | ||||
|         any.verify(|token: &Token| !matches!(token.token_type, TokenType::Brace) || token.value != ")"), | ||||
|         opt(question_mark), | ||||
| @ -2743,6 +2852,7 @@ fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> { | ||||
|         opt((equals, opt(whitespace), literal).map(|(_, _, literal)| literal)), | ||||
|     ) | ||||
|         .parse_next(i)?; | ||||
|  | ||||
|     Ok(ParamDescription { | ||||
|         labeled: found_at_sign.is_none(), | ||||
|         arg_name, | ||||
| @ -2757,6 +2867,7 @@ fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> { | ||||
|                 return Err(ErrMode::Backtrack(ContextError::from(e))); | ||||
|             } | ||||
|         }, | ||||
|         comments, | ||||
|     }) | ||||
| } | ||||
|  | ||||
| @ -2766,6 +2877,7 @@ fn parameters(i: &mut TokenSlice) -> PResult<Vec<Parameter>> { | ||||
|     let candidates: Vec<_> = separated(0.., parameter, comma_sep) | ||||
|         .context(expected("function parameters")) | ||||
|         .parse_next(i)?; | ||||
|     opt(comma_sep).parse_next(i)?; | ||||
|  | ||||
|     // Make sure all those tokens are valid parameters. | ||||
|     let params: Vec<Parameter> = candidates | ||||
| @ -2776,8 +2888,13 @@ fn parameters(i: &mut TokenSlice) -> PResult<Vec<Parameter>> { | ||||
|                  arg_name, | ||||
|                  type_, | ||||
|                  default_value, | ||||
|                  comments, | ||||
|              }| { | ||||
|                 let identifier = Node::<Identifier>::try_from(arg_name)?; | ||||
|                 let mut identifier = Node::<Identifier>::try_from(arg_name)?; | ||||
|                 if let Some(comments) = comments { | ||||
|                     identifier.comment_start = comments.start; | ||||
|                     identifier.pre_comments = comments.inner; | ||||
|                 } | ||||
|  | ||||
|                 Ok(Parameter { | ||||
|                     identifier, | ||||
|  | ||||
| @ -52,7 +52,7 @@ expression: actual | ||||
|                 "commentStart": 8, | ||||
|                 "end": 9, | ||||
|                 "name": "x", | ||||
|                 "start": 8, | ||||
|                 "start": 7, | ||||
|                 "type": "Identifier" | ||||
|               }, | ||||
|               "labeled": false | ||||
|  | ||||
| @ -367,6 +367,8 @@ pub enum TokenType { | ||||
|     QuestionMark, | ||||
|     /// The @ symbol. | ||||
|     At, | ||||
|     /// `;` | ||||
|     SemiColon, | ||||
| } | ||||
|  | ||||
| /// Most KCL tokens correspond to LSP semantic tokens (but not all). | ||||
| @ -396,6 +398,7 @@ impl TryFrom<TokenType> for SemanticTokenType { | ||||
|             | TokenType::Hash | ||||
|             | TokenType::Dollar | ||||
|             | TokenType::At | ||||
|             | TokenType::SemiColon | ||||
|             | TokenType::Unknown => { | ||||
|                 anyhow::bail!("unsupported token type: {:?}", token_type) | ||||
|             } | ||||
| @ -488,6 +491,18 @@ impl Token { | ||||
|         value.parse().ok() | ||||
|     } | ||||
|  | ||||
|     pub fn uint_value(&self) -> Option<u32> { | ||||
|         if self.token_type != TokenType::Number { | ||||
|             return None; | ||||
|         } | ||||
|         let value = &self.value; | ||||
|         let value = value | ||||
|             .split_once(|c: char| c == '_' || c.is_ascii_alphabetic()) | ||||
|             .map(|(s, _)| s) | ||||
|             .unwrap_or(value); | ||||
|         value.parse().ok() | ||||
|     } | ||||
|  | ||||
|     pub fn numeric_suffix(&self) -> NumericSuffix { | ||||
|         if self.token_type != TokenType::Number { | ||||
|             return NumericSuffix::None; | ||||
|  | ||||
| @ -88,6 +88,7 @@ pub(super) fn token(i: &mut Input<'_>) -> PResult<Token> { | ||||
|         '@' => at, | ||||
|         '0'..='9' => number, | ||||
|         ':' => colon, | ||||
|         ';' => semi_colon, | ||||
|         '.' => alt((number, double_period, period)), | ||||
|         '#' => hash, | ||||
|         '$' => dollar, | ||||
| @ -282,6 +283,16 @@ fn colon(i: &mut Input<'_>) -> PResult<Token> { | ||||
|     )) | ||||
| } | ||||
|  | ||||
| fn semi_colon(i: &mut Input<'_>) -> PResult<Token> { | ||||
|     let (value, range) = ';'.with_span().parse_next(i)?; | ||||
|     Ok(Token::from_range( | ||||
|         range, | ||||
|         i.state.module_id, | ||||
|         TokenType::SemiColon, | ||||
|         value.to_string(), | ||||
|     )) | ||||
| } | ||||
|  | ||||
| fn period(i: &mut Input<'_>) -> PResult<Token> { | ||||
|     let (value, range) = '.'.with_span().parse_next(i)?; | ||||
|     Ok(Token::from_range( | ||||
| @ -689,7 +700,7 @@ const things = "things" | ||||
|     #[test] | ||||
|     fn test_unrecognized_token() { | ||||
|         let module_id = ModuleId::from_usize(1); | ||||
|         let actual = lex("12 ; 8", module_id).unwrap(); | ||||
|         let actual = lex("12 ~ 8", module_id).unwrap(); | ||||
|  | ||||
|         use TokenType::*; | ||||
|         assert_tokens(&[(Number, 0, 2), (Unknown, 3, 4), (Number, 5, 6)], actual.as_slice()); | ||||
|  | ||||
| @ -12,10 +12,7 @@ use validator::Validate; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         kcl_value::{ArrayLen, RuntimeType}, | ||||
|         ExecState, KclValue, PrimitiveType, Solid, | ||||
|     }, | ||||
|     execution::{types::RuntimeType, ExecState, KclValue, Solid}, | ||||
|     std::Args, | ||||
| }; | ||||
|  | ||||
| @ -42,11 +39,7 @@ struct AppearanceData { | ||||
|  | ||||
| /// Set the appearance of a solid. This only works on solids, not sketches or individual paths. | ||||
| pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let solids = args.get_unlabeled_kw_arg_typed( | ||||
|         "solids", | ||||
|         &RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?; | ||||
|  | ||||
|     let color: String = args.get_kw_arg("color")?; | ||||
|     let metalness: Option<f64> = args.get_kw_arg_opt("metalness")?; | ||||
|  | ||||
| @ -12,9 +12,10 @@ use serde::{Deserialize, Serialize}; | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         kcl_value::{ArrayLen, FunctionSource, NumericType, RuntimeType}, | ||||
|         ExecState, ExecutorContext, ExtrudeSurface, Helix, KclObjectFields, KclValue, Metadata, PrimitiveType, Sketch, | ||||
|         SketchSurface, Solid, TagIdentifier, | ||||
|         kcl_value::FunctionSource, | ||||
|         types::{NumericType, PrimitiveType, RuntimeType}, | ||||
|         ExecState, ExecutorContext, ExtrudeSurface, Helix, KclObjectFields, KclValue, Metadata, Sketch, SketchSurface, | ||||
|         Solid, TagIdentifier, | ||||
|     }, | ||||
|     parsing::ast::types::TagNode, | ||||
|     source_range::SourceRange, | ||||
| @ -188,8 +189,10 @@ impl Args { | ||||
|                 ty.human_friendly_type(), | ||||
|             ); | ||||
|             let suggestion = match (ty, actual_type_name) { | ||||
|                 (RuntimeType::Primitive(PrimitiveType::Solid), "Sketch") | ||||
|                 | (RuntimeType::Array(PrimitiveType::Solid, _), "Sketch") => Some( | ||||
|                 (RuntimeType::Primitive(PrimitiveType::Solid), "Sketch") => Some( | ||||
|                     "You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`", | ||||
|                 ), | ||||
|                 (RuntimeType::Array(t, _), "Sketch") if **t == RuntimeType::Primitive(PrimitiveType::Solid) => Some( | ||||
|                     "You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`", | ||||
|                 ), | ||||
|                 _ => None, | ||||
| @ -309,8 +312,10 @@ impl Args { | ||||
|                 ty.human_friendly_type(), | ||||
|             ); | ||||
|             let suggestion = match (ty, actual_type_name) { | ||||
|                 (RuntimeType::Primitive(PrimitiveType::Solid), "Sketch") | ||||
|                 | (RuntimeType::Array(PrimitiveType::Solid, _), "Sketch") => Some( | ||||
|                 (RuntimeType::Primitive(PrimitiveType::Solid), "Sketch") => Some( | ||||
|                     "You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`", | ||||
|                 ), | ||||
|                 (RuntimeType::Array(ty, _), "Sketch") if **ty == RuntimeType::Primitive(PrimitiveType::Solid) => Some( | ||||
|                     "You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`", | ||||
|                 ), | ||||
|                 _ => None, | ||||
| @ -597,7 +602,7 @@ impl Args { | ||||
|         }; | ||||
|         let sarg = arg0 | ||||
|             .value | ||||
|             .coerce(&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::None), exec_state) | ||||
|             .coerce(&RuntimeType::sketches(), exec_state) | ||||
|             .ok_or(KclError::Type(KclErrorDetails { | ||||
|                 message: format!( | ||||
|                     "Expected an array of sketches, found {}", | ||||
| @ -685,7 +690,7 @@ impl Args { | ||||
|         }; | ||||
|         let sarg = arg1 | ||||
|             .value | ||||
|             .coerce(&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::None), exec_state) | ||||
|             .coerce(&RuntimeType::sketches(), exec_state) | ||||
|             .ok_or(KclError::Type(KclErrorDetails { | ||||
|                 message: format!( | ||||
|                     "Expected one or more sketches for second argument, found {}", | ||||
| @ -995,9 +1000,8 @@ where | ||||
|  | ||||
| impl<'a> FromKclValue<'a> for [f64; 2] { | ||||
|     fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { | ||||
|         let KclValue::MixedArray { value, meta: _ } = arg else { | ||||
|             return None; | ||||
|         }; | ||||
|         match arg { | ||||
|             KclValue::MixedArray { value, meta: _ } | KclValue::HomArray { value, .. } => { | ||||
|                 if value.len() != 2 { | ||||
|                     return None; | ||||
|                 } | ||||
| @ -1006,13 +1010,15 @@ impl<'a> FromKclValue<'a> for [f64; 2] { | ||||
|                 let array = [v0.as_f64()?, v1.as_f64()?]; | ||||
|                 Some(array) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'a> FromKclValue<'a> for [usize; 3] { | ||||
|     fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { | ||||
|         let KclValue::MixedArray { value, meta: _ } = arg else { | ||||
|             return None; | ||||
|         }; | ||||
|         match arg { | ||||
|             KclValue::MixedArray { value, meta: _ } | KclValue::HomArray { value, .. } => { | ||||
|                 if value.len() != 3 { | ||||
|                     return None; | ||||
|                 } | ||||
| @ -1022,13 +1028,15 @@ impl<'a> FromKclValue<'a> for [usize; 3] { | ||||
|                 let array = [v0.as_usize()?, v1.as_usize()?, v2.as_usize()?]; | ||||
|                 Some(array) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'a> FromKclValue<'a> for [f64; 3] { | ||||
|     fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { | ||||
|         let KclValue::MixedArray { value, meta: _ } = arg else { | ||||
|             return None; | ||||
|         }; | ||||
|         match arg { | ||||
|             KclValue::MixedArray { value, meta: _ } | KclValue::HomArray { value, .. } => { | ||||
|                 if value.len() != 3 { | ||||
|                     return None; | ||||
|                 } | ||||
| @ -1038,6 +1046,9 @@ impl<'a> FromKclValue<'a> for [f64; 3] { | ||||
|                 let array = [v0.as_f64()?, v1.as_f64()?, v2.as_f64()?]; | ||||
|                 Some(array) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'a> FromKclValue<'a> for TagNode { | ||||
|  | ||||
| @ -8,8 +8,8 @@ use kittycad_modeling_cmds as kcmc; | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         kcl_value::RuntimeType, ChamferSurface, EdgeCut, ExecState, ExtrudeSurface, GeoMeta, KclValue, PrimitiveType, | ||||
|         Solid, | ||||
|         types::{PrimitiveType, RuntimeType}, | ||||
|         ChamferSurface, EdgeCut, ExecState, ExtrudeSurface, GeoMeta, KclValue, Solid, | ||||
|     }, | ||||
|     parsing::ast::types::TagNode, | ||||
|     std::{fillet::EdgeReference, Args}, | ||||
|  | ||||
| @ -5,20 +5,14 @@ use kcl_derive_docs::stdlib; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         kcl_value::{ArrayLen, RuntimeType}, | ||||
|         ExecState, KclValue, PrimitiveType, Solid, | ||||
|     }, | ||||
|     execution::{types::RuntimeType, ExecState, KclValue, Solid}, | ||||
|     std::Args, | ||||
| }; | ||||
|  | ||||
| /// Union two or more solids into a single solid. | ||||
| pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed( | ||||
|         "objects", | ||||
|         &RuntimeType::Union(vec![RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty)]), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let solids: Vec<Solid> = | ||||
|         args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::Union(vec![RuntimeType::solids()]), exec_state)?; | ||||
|  | ||||
|     if solids.len() < 2 { | ||||
|         return Err(KclError::UndefinedValue(KclErrorDetails { | ||||
| @ -74,11 +68,7 @@ async fn inner_union(solids: Vec<Solid>, exec_state: &mut ExecState, args: Args) | ||||
| /// Intersect returns the shared volume between multiple solids, preserving only | ||||
| /// overlapping regions. | ||||
| pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed( | ||||
|         "objects", | ||||
|         &RuntimeType::Union(vec![RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty)]), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?; | ||||
|  | ||||
|     if solids.len() < 2 { | ||||
|         return Err(KclError::UndefinedValue(KclErrorDetails { | ||||
| @ -139,16 +129,8 @@ async fn inner_intersect(solids: Vec<Solid>, exec_state: &mut ExecState, args: A | ||||
|  | ||||
| /// Subtract removes tool solids from base solids, leaving the remaining material. | ||||
| pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed( | ||||
|         "objects", | ||||
|         &RuntimeType::Union(vec![RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty)]), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let tools: Vec<Solid> = args.get_kw_arg_typed( | ||||
|         "tools", | ||||
|         &RuntimeType::Union(vec![RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty)]), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?; | ||||
|     let tools: Vec<Solid> = args.get_kw_arg_typed("tools", &RuntimeType::solids(), exec_state)?; | ||||
|  | ||||
|     let solids = inner_subtract(solids, tools, exec_state, args).await?; | ||||
|     Ok(solids.into()) | ||||
|  | ||||
| @ -19,8 +19,8 @@ use uuid::Uuid; | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         kcl_value::{ArrayLen, RuntimeType}, | ||||
|         ArtifactId, ExecState, ExtrudeSurface, GeoMeta, KclValue, Path, PrimitiveType, Sketch, SketchSurface, Solid, | ||||
|         types::RuntimeType, ArtifactId, ExecState, ExtrudeSurface, GeoMeta, KclValue, Path, Sketch, SketchSurface, | ||||
|         Solid, | ||||
|     }, | ||||
|     parsing::ast::types::TagNode, | ||||
|     std::Args, | ||||
| @ -28,11 +28,7 @@ use crate::{ | ||||
|  | ||||
| /// Extrudes by a given amount. | ||||
| pub async fn extrude(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed( | ||||
|         "sketches", | ||||
|         &RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?; | ||||
|     let length = args.get_kw_arg("length")?; | ||||
|     let tag_start = args.get_kw_arg_opt("tagStart")?; | ||||
|     let tag_end = args.get_kw_arg_opt("tagEnd")?; | ||||
|  | ||||
| @ -11,8 +11,8 @@ use serde::{Deserialize, Serialize}; | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         kcl_value::RuntimeType, EdgeCut, ExecState, ExtrudeSurface, FilletSurface, GeoMeta, KclValue, PrimitiveType, | ||||
|         Solid, TagIdentifier, | ||||
|         types::{PrimitiveType, RuntimeType}, | ||||
|         EdgeCut, ExecState, ExtrudeSurface, FilletSurface, GeoMeta, KclValue, Solid, TagIdentifier, | ||||
|     }, | ||||
|     parsing::ast::types::TagNode, | ||||
|     settings::types::UnitLength, | ||||
|  | ||||
| @ -9,10 +9,7 @@ use kittycad_modeling_cmds as kcmc; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         kcl_value::{ArrayLen, RuntimeType}, | ||||
|         ExecState, KclValue, PrimitiveType, Sketch, Solid, | ||||
|     }, | ||||
|     execution::{types::RuntimeType, ExecState, KclValue, Sketch, Solid}, | ||||
|     parsing::ast::types::TagNode, | ||||
|     std::{extrude::do_post_extrude, fillet::default_tolerance, Args}, | ||||
| }; | ||||
| @ -21,11 +18,7 @@ const DEFAULT_V_DEGREE: u32 = 2; | ||||
|  | ||||
| /// Create a 3D surface or solid by interpolating between two or more sketches. | ||||
| pub async fn loft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed( | ||||
|         "sketches", | ||||
|         &RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?; | ||||
|     let v_degree: NonZeroU32 = args | ||||
|         .get_kw_arg_opt("vDegree")? | ||||
|         .unwrap_or(NonZeroU32::new(DEFAULT_V_DEGREE).unwrap()); | ||||
|  | ||||
| @ -47,19 +47,19 @@ fn inner_rem(num: f64, divisor: f64) -> f64 { | ||||
|  | ||||
| /// Compute the cosine of a number (in radians). | ||||
| pub async fn cos(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let num = args.get_number()?; | ||||
|     let num: f64 = args.get_unlabeled_kw_arg("input")?; | ||||
|     Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.cos()))) | ||||
| } | ||||
|  | ||||
| /// Compute the sine of a number (in radians). | ||||
| pub async fn sin(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let num = args.get_number()?; | ||||
|     let num: f64 = args.get_unlabeled_kw_arg("input")?; | ||||
|     Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.sin()))) | ||||
| } | ||||
|  | ||||
| /// Compute the tangent of a number (in radians). | ||||
| pub async fn tan(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let num = args.get_number()?; | ||||
|     let num: f64 = args.get_unlabeled_kw_arg("input")?; | ||||
|     Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.tan()))) | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -42,7 +42,7 @@ use serde::{Deserialize, Serialize}; | ||||
| use crate::{ | ||||
|     docs::StdLibFn, | ||||
|     errors::KclError, | ||||
|     execution::{ExecState, KclValue}, | ||||
|     execution::{types::PrimitiveType, ExecState, KclValue}, | ||||
| }; | ||||
|  | ||||
| pub type StdFn = fn( | ||||
| @ -71,7 +71,6 @@ lazy_static! { | ||||
|         Box::new(crate::std::segment::TangentToEnd), | ||||
|         Box::new(crate::std::segment::AngleToMatchLengthX), | ||||
|         Box::new(crate::std::segment::AngleToMatchLengthY), | ||||
|         Box::new(crate::std::shapes::Circle), | ||||
|         Box::new(crate::std::shapes::CircleThreePoint), | ||||
|         Box::new(crate::std::shapes::Polygon), | ||||
|         Box::new(crate::std::sketch::Line), | ||||
| @ -203,24 +202,21 @@ pub(crate) fn std_fn(path: &str, fn_name: &str) -> (crate::std::StdFn, StdFnProp | ||||
|             |e, a| Box::pin(crate::std::math::tan(e, a)), | ||||
|             StdFnProps::default("std::math::tan"), | ||||
|         ), | ||||
|         ("sketch", "circle") => ( | ||||
|             |e, a| Box::pin(crate::std::shapes::circle(e, a)), | ||||
|             StdFnProps::default("std::sketch::circle"), | ||||
|         ), | ||||
|         _ => unreachable!(), | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub(crate) fn std_ty(path: &str, fn_name: &str) -> (crate::execution::PrimitiveType, StdFnProps) { | ||||
| pub(crate) fn std_ty(path: &str, fn_name: &str) -> (PrimitiveType, StdFnProps) { | ||||
|     match (path, fn_name) { | ||||
|         ("prelude", "Sketch") => ( | ||||
|             crate::execution::PrimitiveType::Sketch, | ||||
|             StdFnProps::default("std::Sketch"), | ||||
|         ), | ||||
|         ("prelude", "Solid") => ( | ||||
|             crate::execution::PrimitiveType::Solid, | ||||
|             StdFnProps::default("std::Solid"), | ||||
|         ), | ||||
|         ("prelude", "Plane") => ( | ||||
|             crate::execution::PrimitiveType::Plane, | ||||
|             StdFnProps::default("std::Plane"), | ||||
|         ), | ||||
|         ("prelude", "Sketch") => (PrimitiveType::Sketch, StdFnProps::default("std::Sketch")), | ||||
|         ("prelude", "Solid") => (PrimitiveType::Solid, StdFnProps::default("std::Solid")), | ||||
|         ("prelude", "Plane") => (PrimitiveType::Plane, StdFnProps::default("std::Plane")), | ||||
|         ("prelude", "Face") => (PrimitiveType::Face, StdFnProps::default("std::Face")), | ||||
|         ("prelude", "Helix") => (PrimitiveType::Helix, StdFnProps::default("std::Helix")), | ||||
|         _ => unreachable!(), | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -20,8 +20,9 @@ use super::args::Arg; | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         kcl_value::{ArrayLen, FunctionSource, NumericType, RuntimeType}, | ||||
|         ExecState, Geometries, Geometry, KclObjectFields, KclValue, Point2d, Point3d, PrimitiveType, Sketch, Solid, | ||||
|         kcl_value::FunctionSource, | ||||
|         types::{NumericType, RuntimeType}, | ||||
|         ExecState, Geometries, Geometry, KclObjectFields, KclValue, Point2d, Point3d, Sketch, Solid, | ||||
|     }, | ||||
|     std::Args, | ||||
|     ExecutorContext, SourceRange, | ||||
| @ -47,11 +48,7 @@ pub struct LinearPattern3dData { | ||||
|  | ||||
| /// Repeat some 3D solid, changing each repetition slightly. | ||||
| pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let solids = args.get_unlabeled_kw_arg_typed( | ||||
|         "solids", | ||||
|         &RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?; | ||||
|     let instances: u32 = args.get_kw_arg("instances")?; | ||||
|     let transform: &FunctionSource = args.get_kw_arg("transform")?; | ||||
|     let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?; | ||||
| @ -62,11 +59,7 @@ pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result | ||||
|  | ||||
| /// Repeat some 2D sketch, changing each repetition slightly. | ||||
| pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed( | ||||
|         "sketches", | ||||
|         &RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?; | ||||
|     let instances: u32 = args.get_kw_arg("instances")?; | ||||
|     let transform: &FunctionSource = args.get_kw_arg("transform")?; | ||||
|     let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?; | ||||
| @ -664,7 +657,7 @@ impl GeometryTrait for Solid { | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
|     use crate::execution::kcl_value::NumericType; | ||||
|     use crate::execution::types::NumericType; | ||||
|  | ||||
|     #[test] | ||||
|     fn test_array_to_point3d() { | ||||
| @ -696,11 +689,7 @@ mod tests { | ||||
|  | ||||
| /// A linear pattern on a 2D sketch. | ||||
| pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed( | ||||
|         "sketches", | ||||
|         &RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?; | ||||
|     let instances: u32 = args.get_kw_arg("instances")?; | ||||
|     let distance: f64 = args.get_kw_arg("distance")?; | ||||
|     let axis: [f64; 2] = args.get_kw_arg("axis")?; | ||||
| @ -779,11 +768,7 @@ async fn inner_pattern_linear_2d( | ||||
|  | ||||
| /// A linear pattern on a 3D model. | ||||
| pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let solids = args.get_unlabeled_kw_arg_typed( | ||||
|         "solids", | ||||
|         &RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?; | ||||
|     let instances: u32 = args.get_kw_arg("instances")?; | ||||
|     let distance: f64 = args.get_kw_arg("distance")?; | ||||
|     let axis: [f64; 3] = args.get_kw_arg("axis")?; | ||||
| @ -1028,11 +1013,7 @@ impl CircularPattern { | ||||
|  | ||||
| /// A circular pattern on a 2D sketch. | ||||
| pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed( | ||||
|         "sketches", | ||||
|         &RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?; | ||||
|     let instances: u32 = args.get_kw_arg("instances")?; | ||||
|     let center: [f64; 2] = args.get_kw_arg("center")?; | ||||
|     let arc_degrees: f64 = args.get_kw_arg("arcDegrees")?; | ||||
| @ -1136,11 +1117,7 @@ async fn inner_pattern_circular_2d( | ||||
|  | ||||
| /// A circular pattern on a 3D model. | ||||
| pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let solids = args.get_unlabeled_kw_arg_typed( | ||||
|         "solids", | ||||
|         &RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?; | ||||
|     // The number of total instances. Must be greater than or equal to 1. | ||||
|     // This includes the original entity. For example, if instances is 2, | ||||
|     // there will be two copies -- the original, and one new copy. | ||||
|  | ||||
| @ -7,21 +7,14 @@ use kittycad_modeling_cmds::{self as kcmc}; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         kcl_value::{ArrayLen, RuntimeType}, | ||||
|         ExecState, KclValue, PrimitiveType, Sketch, Solid, | ||||
|     }, | ||||
|     execution::{types::RuntimeType, ExecState, KclValue, Sketch, Solid}, | ||||
|     parsing::ast::types::TagNode, | ||||
|     std::{axis_or_reference::Axis2dOrEdgeReference, extrude::do_post_extrude, fillet::default_tolerance, Args}, | ||||
| }; | ||||
|  | ||||
| /// Revolve a sketch or set of sketches around an axis. | ||||
| pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed( | ||||
|         "sketches", | ||||
|         &RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?; | ||||
|     let axis: Axis2dOrEdgeReference = args.get_kw_arg("axis")?; | ||||
|     let angle = args.get_kw_arg_opt("angle")?; | ||||
|     let tolerance = args.get_kw_arg_opt("tolerance")?; | ||||
|  | ||||
| @ -6,7 +6,10 @@ use kittycad_modeling_cmds::shared::Angle; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{kcl_value::RuntimeType, ExecState, KclValue, Point2d, PrimitiveType, Sketch, TagIdentifier}, | ||||
|     execution::{ | ||||
|         types::{PrimitiveType, RuntimeType}, | ||||
|         ExecState, KclValue, Point2d, Sketch, TagIdentifier, | ||||
|     }, | ||||
|     std::{utils::between, Args}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| @ -46,38 +46,17 @@ pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|     }) | ||||
| } | ||||
|  | ||||
| /// Construct a 2-dimensional circle, of the specified radius, centered at | ||||
| /// the provided (x, y) origin point. | ||||
| /// | ||||
| /// ```no_run | ||||
| /// exampleSketch = startSketchOn("-XZ") | ||||
| ///   |> circle( center = [0, 0], radius = 10 ) | ||||
| /// | ||||
| /// example = extrude(exampleSketch, length = 5) | ||||
| /// ``` | ||||
| /// | ||||
| /// ```no_run | ||||
| /// exampleSketch = startSketchOn("XZ") | ||||
| ///   |> startProfileAt([-15, 0], %) | ||||
| ///   |> line(end = [30, 0]) | ||||
| ///   |> line(end = [0, 30]) | ||||
| ///   |> line(end = [-30, 0]) | ||||
| ///   |> close() | ||||
| ///   |> hole(circle( center = [0, 15], radius = 5), %) | ||||
| /// | ||||
| /// example = extrude(exampleSketch, length = 5) | ||||
| /// ``` | ||||
| #[stdlib { | ||||
|     name = "circle", | ||||
|     keywords = true, | ||||
|     unlabeled_first = true, | ||||
|     args = { | ||||
|         sketch_or_surface = {docs = "Plane or surface to sketch on."}, | ||||
|         center = {docs = "The center of the circle."}, | ||||
|         radius = {docs = "The radius of the circle."}, | ||||
|         tag = { docs = "Create a new tag which refers to this circle"}, | ||||
|     } | ||||
| }] | ||||
| // #[stdlib { | ||||
| //     name = "circle", | ||||
| //     keywords = true, | ||||
| //     unlabeled_first = true, | ||||
| //     args = { | ||||
| //         sketch_or_surface = {docs = "Plane or surface to sketch on."}, | ||||
| //         center = {docs = "The center of the circle."}, | ||||
| //         radius = {docs = "The radius of the circle."}, | ||||
| //         tag = { docs = "Create a new tag which refers to this circle"}, | ||||
| //     } | ||||
| // }] | ||||
| async fn inner_circle( | ||||
|     sketch_or_surface: SketchOrSurface, | ||||
|     center: [f64; 2], | ||||
| @ -174,7 +153,7 @@ pub async fn circle_three_point(exec_state: &mut ExecState, args: Args) -> Resul | ||||
| #[stdlib { | ||||
|     name = "circleThreePoint", | ||||
|     keywords = true, | ||||
|     unlabeled_first = true, | ||||
|     unlabeled_first = false, | ||||
|     args = { | ||||
|         p1 = {docs = "1st point to derive the circle."}, | ||||
|         p2 = {docs = "2nd point to derive the circle."}, | ||||
|  | ||||
| @ -7,20 +7,13 @@ use kittycad_modeling_cmds as kcmc; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         kcl_value::{ArrayLen, RuntimeType}, | ||||
|         ExecState, KclValue, PrimitiveType, Solid, | ||||
|     }, | ||||
|     execution::{types::RuntimeType, ExecState, KclValue, Solid}, | ||||
|     std::{sketch::FaceTag, Args}, | ||||
| }; | ||||
|  | ||||
| /// Create a shell. | ||||
| pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let solids = args.get_unlabeled_kw_arg_typed( | ||||
|         "solids", | ||||
|         &RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?; | ||||
|     let thickness = args.get_kw_arg("thickness")?; | ||||
|     let faces = args.get_kw_arg("faces")?; | ||||
|  | ||||
|  | ||||
| @ -14,9 +14,9 @@ use serde::{Deserialize, Serialize}; | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         kcl_value::RuntimeType, Artifact, ArtifactId, BasePath, CodeRef, ExecState, Face, GeoMeta, KclValue, Path, | ||||
|         Plane, Point2d, Point3d, PrimitiveType, Sketch, SketchSurface, Solid, StartSketchOnFace, StartSketchOnPlane, | ||||
|         TagEngineInfo, TagIdentifier, | ||||
|         types::{PrimitiveType, RuntimeType}, | ||||
|         Artifact, ArtifactId, BasePath, CodeRef, ExecState, Face, GeoMeta, KclValue, Path, Plane, Point2d, Point3d, | ||||
|         Sketch, SketchSurface, Solid, StartSketchOnFace, StartSketchOnPlane, TagEngineInfo, TagIdentifier, | ||||
|     }, | ||||
|     parsing::ast::types::TagNode, | ||||
|     std::{ | ||||
|  | ||||
| @ -9,10 +9,7 @@ use serde::{Deserialize, Serialize}; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::KclError, | ||||
|     execution::{ | ||||
|         kcl_value::{ArrayLen, RuntimeType}, | ||||
|         ExecState, Helix, KclValue, PrimitiveType, Sketch, Solid, | ||||
|     }, | ||||
|     execution::{types::RuntimeType, ExecState, Helix, KclValue, Sketch, Solid}, | ||||
|     parsing::ast::types::TagNode, | ||||
|     std::{extrude::do_post_extrude, fillet::default_tolerance, Args}, | ||||
| }; | ||||
| @ -28,11 +25,7 @@ pub enum SweepPath { | ||||
|  | ||||
| /// Extrude a sketch along a path. | ||||
| pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed( | ||||
|         "sketches", | ||||
|         &RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty), | ||||
|         exec_state, | ||||
|     )?; | ||||
|     let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?; | ||||
|     let path: SweepPath = args.get_kw_arg("path")?; | ||||
|     let sectional = args.get_kw_arg_opt("sectional")?; | ||||
|     let tolerance = args.get_kw_arg_opt("tolerance")?; | ||||
|  | ||||
| @ -13,10 +13,7 @@ use kittycad_modeling_cmds as kcmc; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::{KclError, KclErrorDetails}, | ||||
|     execution::{ | ||||
|         kcl_value::{ArrayLen, RuntimeType}, | ||||
|         ExecState, KclValue, PrimitiveType, SolidOrSketchOrImportedGeometry, | ||||
|     }, | ||||
|     execution::{types::RuntimeType, ExecState, KclValue, SolidOrSketchOrImportedGeometry}, | ||||
|     std::Args, | ||||
| }; | ||||
|  | ||||
| @ -25,9 +22,9 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K | ||||
|     let objects = args.get_unlabeled_kw_arg_typed( | ||||
|         "objects", | ||||
|         &RuntimeType::Union(vec![ | ||||
|             RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty), | ||||
|             RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty), | ||||
|             RuntimeType::Primitive(PrimitiveType::ImportedGeometry), | ||||
|             RuntimeType::sketches(), | ||||
|             RuntimeType::solids(), | ||||
|             RuntimeType::imported(), | ||||
|         ]), | ||||
|         exec_state, | ||||
|     )?; | ||||
| @ -187,9 +184,9 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu | ||||
|     let objects = args.get_unlabeled_kw_arg_typed( | ||||
|         "objects", | ||||
|         &RuntimeType::Union(vec![ | ||||
|             RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty), | ||||
|             RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty), | ||||
|             RuntimeType::Primitive(PrimitiveType::ImportedGeometry), | ||||
|             RuntimeType::sketches(), | ||||
|             RuntimeType::solids(), | ||||
|             RuntimeType::imported(), | ||||
|         ]), | ||||
|         exec_state, | ||||
|     )?; | ||||
| @ -390,9 +387,9 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue, | ||||
|     let objects = args.get_unlabeled_kw_arg_typed( | ||||
|         "objects", | ||||
|         &RuntimeType::Union(vec![ | ||||
|             RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty), | ||||
|             RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty), | ||||
|             RuntimeType::Primitive(PrimitiveType::ImportedGeometry), | ||||
|             RuntimeType::sketches(), | ||||
|             RuntimeType::solids(), | ||||
|             RuntimeType::imported(), | ||||
|         ]), | ||||
|         exec_state, | ||||
|     )?; | ||||
|  | ||||
| @ -5,7 +5,7 @@ use kcl_derive_docs::stdlib; | ||||
|  | ||||
| use crate::{ | ||||
|     errors::KclError, | ||||
|     execution::{ExecState, KclValue, UnitLen}, | ||||
|     execution::{types::UnitLen, ExecState, KclValue}, | ||||
|     std::Args, | ||||
| }; | ||||
|  | ||||
|  | ||||
| @ -6,8 +6,7 @@ use crate::parsing::{ | ||||
|         CallExpression, CallExpressionKw, CommentStyle, DefaultParamVal, Expr, FormatOptions, FunctionExpression, | ||||
|         IfExpression, ImportSelector, ImportStatement, ItemVisibility, LabeledArg, Literal, LiteralIdentifier, | ||||
|         LiteralValue, MemberExpression, MemberObject, Node, NonCodeNode, NonCodeValue, ObjectExpression, Parameter, | ||||
|         PipeExpression, Program, TagDeclarator, Type, TypeDeclaration, UnaryExpression, VariableDeclaration, | ||||
|         VariableKind, | ||||
|         PipeExpression, Program, TagDeclarator, TypeDeclaration, UnaryExpression, VariableDeclaration, VariableKind, | ||||
|     }, | ||||
|     token::NumericSuffix, | ||||
|     PIPE_OPERATOR, | ||||
| @ -308,7 +307,7 @@ impl Expr { | ||||
|             Expr::AscribedExpression(e) => { | ||||
|                 let mut result = e.expr.recast(options, indentation_level, ctxt); | ||||
|                 result += ": "; | ||||
|                 result += &e.ty.recast(options, indentation_level); | ||||
|                 result += &e.ty.to_string(); | ||||
|                 result | ||||
|             } | ||||
|             Expr::None(_) => { | ||||
| @ -457,6 +456,10 @@ impl TypeDeclaration { | ||||
|             } | ||||
|             arg_str.push(')'); | ||||
|         } | ||||
|         if let Some(alias) = &self.alias { | ||||
|             arg_str.push_str(" = "); | ||||
|             arg_str.push_str(&alias.to_string()); | ||||
|         } | ||||
|         format!("{}type {}{}", vis, self.name.name, arg_str) | ||||
|     } | ||||
| } | ||||
| @ -812,7 +815,7 @@ impl FunctionExpression { | ||||
|         let tab0 = options.get_indentation(indentation_level); | ||||
|         let tab1 = options.get_indentation(indentation_level + 1); | ||||
|         let return_type = match &self.return_type { | ||||
|             Some(rt) => format!(": {}", rt.recast(&new_options, indentation_level)), | ||||
|             Some(rt) => format!(": {rt}"), | ||||
|             None => String::new(), | ||||
|         }; | ||||
|         let body = self.body.recast(&new_options, indentation_level + 1); | ||||
| @ -822,14 +825,14 @@ impl FunctionExpression { | ||||
| } | ||||
|  | ||||
| impl Parameter { | ||||
|     pub fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String { | ||||
|     pub fn recast(&self, _options: &FormatOptions, _indentation_level: usize) -> String { | ||||
|         let at_sign = if self.labeled { "" } else { "@" }; | ||||
|         let identifier = &self.identifier.name; | ||||
|         let question_mark = if self.default_value.is_some() { "?" } else { "" }; | ||||
|         let mut result = format!("{at_sign}{identifier}{question_mark}"); | ||||
|         if let Some(ty) = &self.type_ { | ||||
|             result += ": "; | ||||
|             result += &ty.recast(options, indentation_level); | ||||
|             result += &ty.to_string(); | ||||
|         } | ||||
|         if let Some(DefaultParamVal::Literal(ref literal)) = self.default_value { | ||||
|             let lit = literal.recast(); | ||||
| @ -840,31 +843,6 @@ impl Parameter { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Type { | ||||
|     pub fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String { | ||||
|         match self { | ||||
|             Type::Primitive(t) => t.to_string(), | ||||
|             Type::Array(t) => format!("[{t}]"), | ||||
|             Type::Object { properties } => { | ||||
|                 let mut result = "{".to_owned(); | ||||
|                 for p in properties { | ||||
|                     result += " "; | ||||
|                     result += &p.recast(options, indentation_level); | ||||
|                     result += ","; | ||||
|                 } | ||||
|  | ||||
|                 if result.ends_with(',') { | ||||
|                     result.pop(); | ||||
|                     result += " "; | ||||
|                 } | ||||
|                 result += "}"; | ||||
|  | ||||
|                 result | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Collect all the kcl files in a directory, recursively. | ||||
| #[cfg(not(target_arch = "wasm32"))] | ||||
| #[async_recursion::async_recursion] | ||||
| @ -1414,6 +1392,21 @@ thing(1) | ||||
|         assert_eq!(recasted, some_program_string); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn test_recast_typed_consts() { | ||||
|         let some_program_string = r#"a = 42: number | ||||
| export b = 3.2: number(ft) | ||||
| c = "dsfds": A | B | C | ||||
| d = [1]: [number] | ||||
| e = foo: [number; 3] | ||||
| f = [1, 2, 3]: [number; 1+] | ||||
| "#; | ||||
|         let program = crate::parsing::top_level_parse(some_program_string).unwrap(); | ||||
|  | ||||
|         let recasted = program.recast(&Default::default(), 0); | ||||
|         assert_eq!(recasted, some_program_string); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn test_recast_object_fn_in_array_weird_bracket() { | ||||
|         let some_program_string = r#"bing = { yo = 55 } | ||||
| @ -2438,6 +2431,7 @@ thickness = sqrt(distance * p * FOS * 6 / (sigmaAllow * width))"#; | ||||
| // A comment | ||||
| @(impl = primitive) | ||||
| export type bar(unit, baz) | ||||
| type baz = Foo | Bar | ||||
| "#; | ||||
|         let program = crate::parsing::top_level_parse(some_program_string).unwrap(); | ||||
|         let recasted = program.recast(&Default::default(), 0); | ||||
|  | ||||
| @ -5,7 +5,7 @@ | ||||
| /// ``` | ||||
| /// circumference = 70 | ||||
| /// | ||||
| /// exampleSketch = startSketchOn("XZ") | ||||
| /// exampleSketch = startSketchOn(XZ) | ||||
| ///  |> circle(center = [0, 0], radius = circumference/ (2 * PI)) | ||||
| /// | ||||
| /// example = extrude(exampleSketch, length = 5) | ||||
| @ -15,7 +15,7 @@ export PI = 3.14159265358979323846264338327950288_ | ||||
| /// The value of Euler’s number `e`. | ||||
| /// | ||||
| /// ``` | ||||
| /// exampleSketch = startSketchOn("XZ") | ||||
| /// exampleSketch = startSketchOn(XZ) | ||||
| ///   |> startProfileAt([0, 0], %) | ||||
| ///   |> angledLine({ | ||||
| ///     angle = 30, | ||||
| @ -31,7 +31,7 @@ export E = 2.71828182845904523536028747135266250_ | ||||
| /// The value of `tau`, the full circle constant (τ). Equal to 2π. | ||||
| /// | ||||
| /// ``` | ||||
| /// exampleSketch = startSketchOn("XZ") | ||||
| /// exampleSketch = startSketchOn(XZ) | ||||
| ///   |> startProfileAt([0, 0], %) | ||||
| ///   |> angledLine({ | ||||
| ///     angle = 50, | ||||
| @ -47,7 +47,7 @@ export TAU = 6.28318530717958647692528676655900577_ | ||||
| /// Compute the cosine of a number (in radians). | ||||
| /// | ||||
| /// ``` | ||||
| /// exampleSketch = startSketchOn("XZ") | ||||
| /// exampleSketch = startSketchOn(XZ) | ||||
| ///   |> startProfileAt([0, 0], %) | ||||
| ///   |> angledLine({ | ||||
| ///     angle = 30, | ||||
| @ -59,12 +59,12 @@ export TAU = 6.28318530717958647692528676655900577_ | ||||
| /// example = extrude(exampleSketch, length = 5) | ||||
| /// ``` | ||||
| @(impl = std_rust) | ||||
| export fn cos(num: number(rad)): number(_) {} | ||||
| export fn cos(@num: number(rad)): number(_) {} | ||||
|  | ||||
| /// Compute the sine of a number (in radians). | ||||
| /// | ||||
| /// ``` | ||||
| /// exampleSketch = startSketchOn("XZ") | ||||
| /// exampleSketch = startSketchOn(XZ) | ||||
| ///   |> startProfileAt([0, 0], %) | ||||
| ///   |> angledLine({ | ||||
| ///     angle = 50, | ||||
| @ -76,12 +76,12 @@ export fn cos(num: number(rad)): number(_) {} | ||||
| /// example = extrude(exampleSketch, length = 5) | ||||
| /// ``` | ||||
| @(impl = std_rust) | ||||
| export fn sin(num: number(rad)): number(_) {} | ||||
| export fn sin(@num: number(rad)): number(_) {} | ||||
|  | ||||
| /// Compute the tangent of a number (in radians). | ||||
| /// | ||||
| /// ``` | ||||
| /// exampleSketch = startSketchOn("XZ") | ||||
| /// exampleSketch = startSketchOn(XZ) | ||||
| ///   |> startProfileAt([0, 0], %) | ||||
| ///   |> angledLine({ | ||||
| ///     angle = 50, | ||||
| @ -93,4 +93,4 @@ export fn sin(num: number(rad)): number(_) {} | ||||
| /// example = extrude(exampleSketch, length = 5) | ||||
| /// ``` | ||||
| @(impl = std_rust) | ||||
| export fn tan(num: number(rad)): number(_) {} | ||||
| export fn tan(@num: number(rad)): number(_) {} | ||||
|  | ||||
| @ -3,6 +3,7 @@ | ||||
| // Note that everything in the prelude is treated as exported. | ||||
|  | ||||
| export import * from "std::math" | ||||
| export import * from "std::sketch" | ||||
|  | ||||
| /// A number | ||||
| /// | ||||
| @ -223,6 +224,26 @@ export type Sketch | ||||
| @(impl = std_rust) | ||||
| export type Solid | ||||
|  | ||||
| /// A face. | ||||
| @(impl = std_rust) | ||||
| export type Face | ||||
|  | ||||
| /// A helix. | ||||
| @(impl = std_rust) | ||||
| export type Helix | ||||
|  | ||||
| /// A point in two dimensional space. | ||||
| /// | ||||
| /// `Point2d` is an alias for a two-element array of [number](/docs/kcl/types/number)s. To write a value | ||||
| /// with type `Point2d`, use an array, e.g., `[0, 0]` or `[5.0, 3.14]`. | ||||
| export type Point2d = [number; 2] | ||||
|  | ||||
| /// A point in three dimensional space. | ||||
| /// | ||||
| /// `Point3d` is an alias for a three-element array of [number](/docs/kcl/types/number)s. To write a value | ||||
| /// with type `Point3d`, use an array, e.g., `[0, 0, 0]` or `[5.0, 3.14, 6.8]`. | ||||
| export type Point3d = [number; 3] | ||||
|  | ||||
| export ZERO = 0 | ||||
| export QUARTER_TURN = 90deg | ||||
| export HALF_TURN = 180deg | ||||
|  | ||||
							
								
								
									
										34
									
								
								rust/kcl-lib/std/sketch.kcl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								rust/kcl-lib/std/sketch.kcl
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| @no_std | ||||
|  | ||||
| /// Construct a 2-dimensional circle, of the specified radius, centered at | ||||
| /// the provided (x, y) origin point. | ||||
| /// | ||||
| /// ``` | ||||
| /// exampleSketch = startSketchOn(-XZ) | ||||
| ///   |> circle(center = [0, 0], radius = 10) | ||||
| /// | ||||
| /// example = extrude(exampleSketch, length = 5) | ||||
| /// ``` | ||||
| /// | ||||
| /// ``` | ||||
| /// exampleSketch = startSketchOn(XZ) | ||||
| ///   |> startProfileAt([-15, 0], %) | ||||
| ///   |> line(end = [30, 0]) | ||||
| ///   |> line(end = [0, 30]) | ||||
| ///   |> line(end = [-30, 0]) | ||||
| ///   |> close() | ||||
| ///   |> hole(circle(center = [0, 15], radius = 5), %) | ||||
| /// | ||||
| /// example = extrude(exampleSketch, length = 5) | ||||
| /// ``` | ||||
| @(impl = std_rust) | ||||
| export fn circle( | ||||
|   /// Sketch to extend, or plane or surface to sketch on. | ||||
|   @sketch_or_surface: Sketch | Plane | Face, | ||||
|   /// The center of the circle. | ||||
|   center: Point2d, | ||||
|   /// The radius of the circle. | ||||
|   radius: number, | ||||
|   /// Create a new tag which refers to this circle. | ||||
|   tag?: tag, | ||||
| ): Sketch {} | ||||
| @ -1,25 +1,25 @@ | ||||
| ```mermaid | ||||
| flowchart LR | ||||
|   subgraph path2 [Path] | ||||
|     2["Path<br>[76, 113, 3]"] | ||||
|     3["Segment<br>[119, 136, 3]"] | ||||
|     4["Segment<br>[142, 160, 3]"] | ||||
|     5["Segment<br>[166, 184, 3]"] | ||||
|     6["Segment<br>[190, 246, 3]"] | ||||
|     7["Segment<br>[252, 259, 3]"] | ||||
|     2["Path<br>[76, 113, 4]"] | ||||
|     3["Segment<br>[119, 136, 4]"] | ||||
|     4["Segment<br>[142, 160, 4]"] | ||||
|     5["Segment<br>[166, 184, 4]"] | ||||
|     6["Segment<br>[190, 246, 4]"] | ||||
|     7["Segment<br>[252, 259, 4]"] | ||||
|     8[Solid2d] | ||||
|   end | ||||
|   subgraph path25 [Path] | ||||
|     25["Path<br>[76, 111, 4]"] | ||||
|     26["Segment<br>[117, 134, 4]"] | ||||
|     27["Segment<br>[140, 158, 4]"] | ||||
|     28["Segment<br>[164, 182, 4]"] | ||||
|     29["Segment<br>[188, 244, 4]"] | ||||
|     30["Segment<br>[250, 257, 4]"] | ||||
|     25["Path<br>[76, 111, 5]"] | ||||
|     26["Segment<br>[117, 134, 5]"] | ||||
|     27["Segment<br>[140, 158, 5]"] | ||||
|     28["Segment<br>[164, 182, 5]"] | ||||
|     29["Segment<br>[188, 244, 5]"] | ||||
|     30["Segment<br>[250, 257, 5]"] | ||||
|     31[Solid2d] | ||||
|   end | ||||
|   1["Plane<br>[47, 66, 3]"] | ||||
|   9["Sweep Extrusion<br>[265, 287, 3]"] | ||||
|   1["Plane<br>[47, 66, 4]"] | ||||
|   9["Sweep Extrusion<br>[265, 287, 4]"] | ||||
|   10[Wall] | ||||
|   11[Wall] | ||||
|   12[Wall] | ||||
| @ -34,8 +34,8 @@ flowchart LR | ||||
|   21["SweepEdge Adjacent"] | ||||
|   22["SweepEdge Opposite"] | ||||
|   23["SweepEdge Adjacent"] | ||||
|   24["Plane<br>[47, 66, 4]"] | ||||
|   32["Sweep Extrusion<br>[263, 285, 4]"] | ||||
|   24["Plane<br>[47, 66, 5]"] | ||||
|   32["Sweep Extrusion<br>[263, 285, 5]"] | ||||
|   33[Wall] | ||||
|   34[Wall] | ||||
|   35[Wall] | ||||
|  | ||||
| @ -5,10 +5,10 @@ description: Variables in memory after executing assembly_mixed_units_cubes.kcl | ||||
| { | ||||
|   "cubeIn": { | ||||
|     "type": "Module", | ||||
|     "value": 3 | ||||
|     "value": 4 | ||||
|   }, | ||||
|   "cubeMm": { | ||||
|     "type": "Module", | ||||
|     "value": 4 | ||||
|     "value": 5 | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,17 +1,17 @@ | ||||
| ```mermaid | ||||
| flowchart LR | ||||
|   subgraph path2 [Path] | ||||
|     2["Path<br>[197, 232, 3]"] | ||||
|     3["Segment<br>[197, 232, 3]"] | ||||
|     2["Path<br>[197, 232, 4]"] | ||||
|     3["Segment<br>[197, 232, 4]"] | ||||
|     4[Solid2d] | ||||
|   end | ||||
|   subgraph path6 [Path] | ||||
|     6["Path<br>[113, 148, 4]"] | ||||
|     7["Segment<br>[113, 148, 4]"] | ||||
|     6["Path<br>[113, 148, 5]"] | ||||
|     7["Segment<br>[113, 148, 5]"] | ||||
|     8[Solid2d] | ||||
|   end | ||||
|   1["Plane<br>[172, 191, 3]"] | ||||
|   5["Plane<br>[88, 107, 4]"] | ||||
|   1["Plane<br>[172, 191, 4]"] | ||||
|   5["Plane<br>[88, 107, 5]"] | ||||
|   1 --- 2 | ||||
|   2 --- 3 | ||||
|   2 --- 4 | ||||
|  | ||||
| @ -18,6 +18,72 @@ description: Operations executed assembly_non_default_units.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 1.0, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Inches" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "data": { | ||||
| @ -32,5 +98,71 @@ description: Operations executed assembly_non_default_units.kcl | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 2.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 1.0, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Inches" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -5,10 +5,10 @@ description: Variables in memory after executing assembly_non_default_units.kcl | ||||
| { | ||||
|   "other1": { | ||||
|     "type": "Module", | ||||
|     "value": 3 | ||||
|     "value": 4 | ||||
|   }, | ||||
|   "other2": { | ||||
|     "type": "Module", | ||||
|     "value": 4 | ||||
|     "value": 5 | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -75,6 +75,78 @@ description: Operations executed crazy_multi_profile.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Face", | ||||
|         "artifact_id": "[uuid]" | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 5.15, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 4.34, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 1.66, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "angle": { | ||||
| @ -161,6 +233,78 @@ description: Operations executed crazy_multi_profile.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Plane", | ||||
|         "artifact_id": "[uuid]" | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 7.18, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": -2.11, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 2.67, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
|  | ||||
| @ -149,37 +149,41 @@ description: Operations executed fillet-and-shell.kcl | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Sketch", | ||||
|           "value": { | ||||
|             "artifactId": "[uuid]" | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 7.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "sketch": { | ||||
|         "value": { | ||||
|           "type": "Sketch", | ||||
|           "value": { | ||||
|             "artifactId": "[uuid]" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "name": "hole", | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|             { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
|               "type": "Number", | ||||
|               "value": 7.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 4.0, | ||||
|           "value": 2.5, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
| @ -193,48 +197,64 @@ description: Operations executed fillet-and-shell.kcl | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "name": "extrude", | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Sketch", | ||||
|         "value": { | ||||
|           "artifactId": "[uuid]" | ||||
|         } | ||||
|       }, | ||||
|     "sourceRange": [] | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "m25Screw", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       1310, | ||||
|       1538, | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
|     "sourceRange": [] | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 7.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|     "labeledArgs": { | ||||
|       "data": { | ||||
|               "type": "Number", | ||||
|               "value": 7.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "String", | ||||
|           "value": "XY" | ||||
|           "type": "Number", | ||||
|           "value": 1.25, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "name": "startSketchOn", | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
| @ -324,6 +344,114 @@ description: Operations executed fillet-and-shell.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 7.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 65.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 2.5, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 7.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 65.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 1.25, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
| @ -412,6 +540,310 @@ description: Operations executed fillet-and-shell.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 30.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 65.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 2.5, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 30.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 65.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 1.25, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
|         "value": { | ||||
|           "type": "Sketch", | ||||
|           "value": { | ||||
|             "artifactId": "[uuid]" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "sketch": { | ||||
|         "value": { | ||||
|           "type": "Sketch", | ||||
|           "value": { | ||||
|             "artifactId": "[uuid]" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "name": "hole", | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 4.0, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "name": "extrude", | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Sketch", | ||||
|         "value": { | ||||
|           "artifactId": "[uuid]" | ||||
|         } | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "m25Screw", | ||||
|     "functionSourceRange": [ | ||||
|       1310, | ||||
|       1538, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "data": { | ||||
|         "value": { | ||||
|           "type": "String", | ||||
|           "value": "XY" | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "name": "startSketchOn", | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 30.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 7.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 2.5, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 30.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 7.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 1.25, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
|  | ||||
| @ -18,6 +18,152 @@ description: Operations executed flush_batch_on_end.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Plane", | ||||
|         "artifact_id": "[uuid]" | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.2734375, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "tag": { | ||||
|         "value": { | ||||
|           "type": "TagDeclarator", | ||||
|           "name": "arc000" | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Plane", | ||||
|         "artifact_id": "[uuid]" | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.182, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "tag": { | ||||
|         "value": { | ||||
|           "type": "TagDeclarator", | ||||
|           "name": "arc001" | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
|  | ||||
| @ -18,6 +18,72 @@ description: Operations executed helix_ccw.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 5.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 5.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 10.0, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
|  | ||||
| @ -5,7 +5,7 @@ description: Variables in memory after executing import_foreign.kcl | ||||
| { | ||||
|   "cube": { | ||||
|     "type": "Module", | ||||
|     "value": 3 | ||||
|     "value": 4 | ||||
|   }, | ||||
|   "model": { | ||||
|     "type": "ImportedGeometry", | ||||
|  | ||||
| @ -17,5 +17,71 @@ description: Operations executed import_side_effect.kcl | ||||
|     "sourceRange": [], | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 10.0, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Mm" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -5,6 +5,6 @@ description: Variables in memory after executing import_transform.kcl | ||||
| { | ||||
|   "screw": { | ||||
|     "type": "Module", | ||||
|     "value": 3 | ||||
|     "value": 4 | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,12 +1,12 @@ | ||||
| ```mermaid | ||||
| flowchart LR | ||||
|   subgraph path2 [Path] | ||||
|     2["Path<br>[62, 98, 3]"] | ||||
|     3["Segment<br>[62, 98, 3]"] | ||||
|     2["Path<br>[62, 98, 4]"] | ||||
|     3["Segment<br>[62, 98, 4]"] | ||||
|     4[Solid2d] | ||||
|   end | ||||
|   1["Plane<br>[37, 56, 3]"] | ||||
|   5["Sweep Extrusion<br>[104, 124, 3]"] | ||||
|   1["Plane<br>[37, 56, 4]"] | ||||
|   5["Sweep Extrusion<br>[104, 124, 4]"] | ||||
|   6[Wall] | ||||
|   7["Cap Start"] | ||||
|   8["Cap End"] | ||||
|  | ||||
| @ -18,6 +18,72 @@ description: Operations executed import_whole.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 5.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 5.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 10.0, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Inches" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
|  | ||||
| @ -111,6 +111,6 @@ description: Variables in memory after executing import_whole.kcl | ||||
|   }, | ||||
|   "foo": { | ||||
|     "type": "Module", | ||||
|     "value": 3 | ||||
|     "value": 4 | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -30,6 +30,54 @@ description: Operations executed 80-20-rail.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.75, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.75, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.15375, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
|  | ||||
| @ -74,6 +74,54 @@ description: Operations executed a-parametric-bearing-pillow-block.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": -1.25, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": -2.25, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.35, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -153,6 +201,54 @@ description: Operations executed a-parametric-bearing-pillow-block.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": -1.25, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": -2.25, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.1875, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -232,6 +328,66 @@ description: Operations executed a-parametric-bearing-pillow-block.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 1.5, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
|  | ||||
| @ -42,6 +42,126 @@ description: Operations executed ball-bearing.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.475, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.375, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
| @ -504,6 +624,60 @@ description: Operations executed ball-bearing.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.6, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.03125, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "angle": { | ||||
| @ -725,6 +899,126 @@ description: Operations executed ball-bearing.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.8125, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.725, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
|  | ||||
| @ -1,239 +1,239 @@ | ||||
| ```mermaid | ||||
| flowchart LR | ||||
|   subgraph path2 [Path] | ||||
|     2["Path<br>[361, 394, 3]"] | ||||
|     3["Segment<br>[402, 428, 3]"] | ||||
|     4["Segment<br>[436, 489, 3]"] | ||||
|     5["Segment<br>[497, 550, 3]"] | ||||
|     6["Segment<br>[558, 612, 3]"] | ||||
|     7["Segment<br>[620, 645, 3]"] | ||||
|     8["Segment<br>[653, 673, 3]"] | ||||
|     9["Segment<br>[681, 705, 3]"] | ||||
|     10["Segment<br>[713, 766, 3]"] | ||||
|     11["Segment<br>[774, 799, 3]"] | ||||
|     12["Segment<br>[807, 827, 3]"] | ||||
|     13["Segment<br>[835, 859, 3]"] | ||||
|     14["Segment<br>[867, 919, 3]"] | ||||
|     15["Segment<br>[927, 979, 3]"] | ||||
|     16["Segment<br>[987, 1012, 3]"] | ||||
|     17["Segment<br>[1020, 1044, 3]"] | ||||
|     18["Segment<br>[1052, 1105, 3]"] | ||||
|     19["Segment<br>[1113, 1138, 3]"] | ||||
|     20["Segment<br>[1146, 1173, 3]"] | ||||
|     21["Segment<br>[1181, 1233, 3]"] | ||||
|     22["Segment<br>[1241, 1276, 3]"] | ||||
|     23["Segment<br>[1284, 1291, 3]"] | ||||
|     2["Path<br>[361, 394, 4]"] | ||||
|     3["Segment<br>[402, 428, 4]"] | ||||
|     4["Segment<br>[436, 489, 4]"] | ||||
|     5["Segment<br>[497, 550, 4]"] | ||||
|     6["Segment<br>[558, 612, 4]"] | ||||
|     7["Segment<br>[620, 645, 4]"] | ||||
|     8["Segment<br>[653, 673, 4]"] | ||||
|     9["Segment<br>[681, 705, 4]"] | ||||
|     10["Segment<br>[713, 766, 4]"] | ||||
|     11["Segment<br>[774, 799, 4]"] | ||||
|     12["Segment<br>[807, 827, 4]"] | ||||
|     13["Segment<br>[835, 859, 4]"] | ||||
|     14["Segment<br>[867, 919, 4]"] | ||||
|     15["Segment<br>[927, 979, 4]"] | ||||
|     16["Segment<br>[987, 1012, 4]"] | ||||
|     17["Segment<br>[1020, 1044, 4]"] | ||||
|     18["Segment<br>[1052, 1105, 4]"] | ||||
|     19["Segment<br>[1113, 1138, 4]"] | ||||
|     20["Segment<br>[1146, 1173, 4]"] | ||||
|     21["Segment<br>[1181, 1233, 4]"] | ||||
|     22["Segment<br>[1241, 1276, 4]"] | ||||
|     23["Segment<br>[1284, 1291, 4]"] | ||||
|     24[Solid2d] | ||||
|   end | ||||
|   subgraph path89 [Path] | ||||
|     89["Path<br>[361, 394, 3]"] | ||||
|     90["Segment<br>[402, 428, 3]"] | ||||
|     91["Segment<br>[436, 489, 3]"] | ||||
|     92["Segment<br>[497, 550, 3]"] | ||||
|     93["Segment<br>[558, 612, 3]"] | ||||
|     94["Segment<br>[620, 645, 3]"] | ||||
|     95["Segment<br>[653, 673, 3]"] | ||||
|     96["Segment<br>[681, 705, 3]"] | ||||
|     97["Segment<br>[713, 766, 3]"] | ||||
|     98["Segment<br>[774, 799, 3]"] | ||||
|     99["Segment<br>[807, 827, 3]"] | ||||
|     100["Segment<br>[835, 859, 3]"] | ||||
|     101["Segment<br>[867, 919, 3]"] | ||||
|     102["Segment<br>[927, 979, 3]"] | ||||
|     103["Segment<br>[987, 1012, 3]"] | ||||
|     104["Segment<br>[1020, 1044, 3]"] | ||||
|     105["Segment<br>[1052, 1105, 3]"] | ||||
|     106["Segment<br>[1113, 1138, 3]"] | ||||
|     107["Segment<br>[1146, 1173, 3]"] | ||||
|     108["Segment<br>[1181, 1233, 3]"] | ||||
|     109["Segment<br>[1241, 1276, 3]"] | ||||
|     110["Segment<br>[1284, 1291, 3]"] | ||||
|     89["Path<br>[361, 394, 4]"] | ||||
|     90["Segment<br>[402, 428, 4]"] | ||||
|     91["Segment<br>[436, 489, 4]"] | ||||
|     92["Segment<br>[497, 550, 4]"] | ||||
|     93["Segment<br>[558, 612, 4]"] | ||||
|     94["Segment<br>[620, 645, 4]"] | ||||
|     95["Segment<br>[653, 673, 4]"] | ||||
|     96["Segment<br>[681, 705, 4]"] | ||||
|     97["Segment<br>[713, 766, 4]"] | ||||
|     98["Segment<br>[774, 799, 4]"] | ||||
|     99["Segment<br>[807, 827, 4]"] | ||||
|     100["Segment<br>[835, 859, 4]"] | ||||
|     101["Segment<br>[867, 919, 4]"] | ||||
|     102["Segment<br>[927, 979, 4]"] | ||||
|     103["Segment<br>[987, 1012, 4]"] | ||||
|     104["Segment<br>[1020, 1044, 4]"] | ||||
|     105["Segment<br>[1052, 1105, 4]"] | ||||
|     106["Segment<br>[1113, 1138, 4]"] | ||||
|     107["Segment<br>[1146, 1173, 4]"] | ||||
|     108["Segment<br>[1181, 1233, 4]"] | ||||
|     109["Segment<br>[1241, 1276, 4]"] | ||||
|     110["Segment<br>[1284, 1291, 4]"] | ||||
|     111[Solid2d] | ||||
|   end | ||||
|   subgraph path176 [Path] | ||||
|     176["Path<br>[361, 394, 3]"] | ||||
|     177["Segment<br>[402, 428, 3]"] | ||||
|     178["Segment<br>[436, 489, 3]"] | ||||
|     179["Segment<br>[497, 550, 3]"] | ||||
|     180["Segment<br>[558, 612, 3]"] | ||||
|     181["Segment<br>[620, 645, 3]"] | ||||
|     182["Segment<br>[653, 673, 3]"] | ||||
|     183["Segment<br>[681, 705, 3]"] | ||||
|     184["Segment<br>[713, 766, 3]"] | ||||
|     185["Segment<br>[774, 799, 3]"] | ||||
|     186["Segment<br>[807, 827, 3]"] | ||||
|     187["Segment<br>[835, 859, 3]"] | ||||
|     188["Segment<br>[867, 919, 3]"] | ||||
|     189["Segment<br>[927, 979, 3]"] | ||||
|     190["Segment<br>[987, 1012, 3]"] | ||||
|     191["Segment<br>[1020, 1044, 3]"] | ||||
|     192["Segment<br>[1052, 1105, 3]"] | ||||
|     193["Segment<br>[1113, 1138, 3]"] | ||||
|     194["Segment<br>[1146, 1173, 3]"] | ||||
|     195["Segment<br>[1181, 1233, 3]"] | ||||
|     196["Segment<br>[1241, 1276, 3]"] | ||||
|     197["Segment<br>[1284, 1291, 3]"] | ||||
|     176["Path<br>[361, 394, 4]"] | ||||
|     177["Segment<br>[402, 428, 4]"] | ||||
|     178["Segment<br>[436, 489, 4]"] | ||||
|     179["Segment<br>[497, 550, 4]"] | ||||
|     180["Segment<br>[558, 612, 4]"] | ||||
|     181["Segment<br>[620, 645, 4]"] | ||||
|     182["Segment<br>[653, 673, 4]"] | ||||
|     183["Segment<br>[681, 705, 4]"] | ||||
|     184["Segment<br>[713, 766, 4]"] | ||||
|     185["Segment<br>[774, 799, 4]"] | ||||
|     186["Segment<br>[807, 827, 4]"] | ||||
|     187["Segment<br>[835, 859, 4]"] | ||||
|     188["Segment<br>[867, 919, 4]"] | ||||
|     189["Segment<br>[927, 979, 4]"] | ||||
|     190["Segment<br>[987, 1012, 4]"] | ||||
|     191["Segment<br>[1020, 1044, 4]"] | ||||
|     192["Segment<br>[1052, 1105, 4]"] | ||||
|     193["Segment<br>[1113, 1138, 4]"] | ||||
|     194["Segment<br>[1146, 1173, 4]"] | ||||
|     195["Segment<br>[1181, 1233, 4]"] | ||||
|     196["Segment<br>[1241, 1276, 4]"] | ||||
|     197["Segment<br>[1284, 1291, 4]"] | ||||
|     198[Solid2d] | ||||
|   end | ||||
|   subgraph path262 [Path] | ||||
|     262["Path<br>[361, 394, 3]"] | ||||
|     263["Segment<br>[402, 428, 3]"] | ||||
|     264["Segment<br>[436, 489, 3]"] | ||||
|     265["Segment<br>[497, 550, 3]"] | ||||
|     266["Segment<br>[558, 612, 3]"] | ||||
|     267["Segment<br>[620, 645, 3]"] | ||||
|     268["Segment<br>[653, 673, 3]"] | ||||
|     269["Segment<br>[681, 705, 3]"] | ||||
|     270["Segment<br>[713, 766, 3]"] | ||||
|     271["Segment<br>[774, 799, 3]"] | ||||
|     272["Segment<br>[807, 827, 3]"] | ||||
|     273["Segment<br>[835, 859, 3]"] | ||||
|     274["Segment<br>[867, 919, 3]"] | ||||
|     275["Segment<br>[927, 979, 3]"] | ||||
|     276["Segment<br>[987, 1012, 3]"] | ||||
|     277["Segment<br>[1020, 1044, 3]"] | ||||
|     278["Segment<br>[1052, 1105, 3]"] | ||||
|     279["Segment<br>[1113, 1138, 3]"] | ||||
|     280["Segment<br>[1146, 1173, 3]"] | ||||
|     281["Segment<br>[1181, 1233, 3]"] | ||||
|     282["Segment<br>[1241, 1276, 3]"] | ||||
|     283["Segment<br>[1284, 1291, 3]"] | ||||
|     262["Path<br>[361, 394, 4]"] | ||||
|     263["Segment<br>[402, 428, 4]"] | ||||
|     264["Segment<br>[436, 489, 4]"] | ||||
|     265["Segment<br>[497, 550, 4]"] | ||||
|     266["Segment<br>[558, 612, 4]"] | ||||
|     267["Segment<br>[620, 645, 4]"] | ||||
|     268["Segment<br>[653, 673, 4]"] | ||||
|     269["Segment<br>[681, 705, 4]"] | ||||
|     270["Segment<br>[713, 766, 4]"] | ||||
|     271["Segment<br>[774, 799, 4]"] | ||||
|     272["Segment<br>[807, 827, 4]"] | ||||
|     273["Segment<br>[835, 859, 4]"] | ||||
|     274["Segment<br>[867, 919, 4]"] | ||||
|     275["Segment<br>[927, 979, 4]"] | ||||
|     276["Segment<br>[987, 1012, 4]"] | ||||
|     277["Segment<br>[1020, 1044, 4]"] | ||||
|     278["Segment<br>[1052, 1105, 4]"] | ||||
|     279["Segment<br>[1113, 1138, 4]"] | ||||
|     280["Segment<br>[1146, 1173, 4]"] | ||||
|     281["Segment<br>[1181, 1233, 4]"] | ||||
|     282["Segment<br>[1241, 1276, 4]"] | ||||
|     283["Segment<br>[1284, 1291, 4]"] | ||||
|     284[Solid2d] | ||||
|   end | ||||
|   subgraph path349 [Path] | ||||
|     349["Path<br>[361, 394, 3]"] | ||||
|     350["Segment<br>[402, 428, 3]"] | ||||
|     351["Segment<br>[436, 489, 3]"] | ||||
|     352["Segment<br>[497, 550, 3]"] | ||||
|     353["Segment<br>[558, 612, 3]"] | ||||
|     354["Segment<br>[620, 645, 3]"] | ||||
|     355["Segment<br>[653, 673, 3]"] | ||||
|     356["Segment<br>[681, 705, 3]"] | ||||
|     357["Segment<br>[713, 766, 3]"] | ||||
|     358["Segment<br>[774, 799, 3]"] | ||||
|     359["Segment<br>[807, 827, 3]"] | ||||
|     360["Segment<br>[835, 859, 3]"] | ||||
|     361["Segment<br>[867, 919, 3]"] | ||||
|     362["Segment<br>[927, 979, 3]"] | ||||
|     363["Segment<br>[987, 1012, 3]"] | ||||
|     364["Segment<br>[1020, 1044, 3]"] | ||||
|     365["Segment<br>[1052, 1105, 3]"] | ||||
|     366["Segment<br>[1113, 1138, 3]"] | ||||
|     367["Segment<br>[1146, 1173, 3]"] | ||||
|     368["Segment<br>[1181, 1233, 3]"] | ||||
|     369["Segment<br>[1241, 1276, 3]"] | ||||
|     370["Segment<br>[1284, 1291, 3]"] | ||||
|     349["Path<br>[361, 394, 4]"] | ||||
|     350["Segment<br>[402, 428, 4]"] | ||||
|     351["Segment<br>[436, 489, 4]"] | ||||
|     352["Segment<br>[497, 550, 4]"] | ||||
|     353["Segment<br>[558, 612, 4]"] | ||||
|     354["Segment<br>[620, 645, 4]"] | ||||
|     355["Segment<br>[653, 673, 4]"] | ||||
|     356["Segment<br>[681, 705, 4]"] | ||||
|     357["Segment<br>[713, 766, 4]"] | ||||
|     358["Segment<br>[774, 799, 4]"] | ||||
|     359["Segment<br>[807, 827, 4]"] | ||||
|     360["Segment<br>[835, 859, 4]"] | ||||
|     361["Segment<br>[867, 919, 4]"] | ||||
|     362["Segment<br>[927, 979, 4]"] | ||||
|     363["Segment<br>[987, 1012, 4]"] | ||||
|     364["Segment<br>[1020, 1044, 4]"] | ||||
|     365["Segment<br>[1052, 1105, 4]"] | ||||
|     366["Segment<br>[1113, 1138, 4]"] | ||||
|     367["Segment<br>[1146, 1173, 4]"] | ||||
|     368["Segment<br>[1181, 1233, 4]"] | ||||
|     369["Segment<br>[1241, 1276, 4]"] | ||||
|     370["Segment<br>[1284, 1291, 4]"] | ||||
|     371[Solid2d] | ||||
|   end | ||||
|   subgraph path435 [Path] | ||||
|     435["Path<br>[361, 394, 3]"] | ||||
|     436["Segment<br>[402, 428, 3]"] | ||||
|     437["Segment<br>[436, 489, 3]"] | ||||
|     438["Segment<br>[497, 550, 3]"] | ||||
|     439["Segment<br>[558, 612, 3]"] | ||||
|     440["Segment<br>[620, 645, 3]"] | ||||
|     441["Segment<br>[653, 673, 3]"] | ||||
|     442["Segment<br>[681, 705, 3]"] | ||||
|     443["Segment<br>[713, 766, 3]"] | ||||
|     444["Segment<br>[774, 799, 3]"] | ||||
|     445["Segment<br>[807, 827, 3]"] | ||||
|     446["Segment<br>[835, 859, 3]"] | ||||
|     447["Segment<br>[867, 919, 3]"] | ||||
|     448["Segment<br>[927, 979, 3]"] | ||||
|     449["Segment<br>[987, 1012, 3]"] | ||||
|     450["Segment<br>[1020, 1044, 3]"] | ||||
|     451["Segment<br>[1052, 1105, 3]"] | ||||
|     452["Segment<br>[1113, 1138, 3]"] | ||||
|     453["Segment<br>[1146, 1173, 3]"] | ||||
|     454["Segment<br>[1181, 1233, 3]"] | ||||
|     455["Segment<br>[1241, 1276, 3]"] | ||||
|     456["Segment<br>[1284, 1291, 3]"] | ||||
|     435["Path<br>[361, 394, 4]"] | ||||
|     436["Segment<br>[402, 428, 4]"] | ||||
|     437["Segment<br>[436, 489, 4]"] | ||||
|     438["Segment<br>[497, 550, 4]"] | ||||
|     439["Segment<br>[558, 612, 4]"] | ||||
|     440["Segment<br>[620, 645, 4]"] | ||||
|     441["Segment<br>[653, 673, 4]"] | ||||
|     442["Segment<br>[681, 705, 4]"] | ||||
|     443["Segment<br>[713, 766, 4]"] | ||||
|     444["Segment<br>[774, 799, 4]"] | ||||
|     445["Segment<br>[807, 827, 4]"] | ||||
|     446["Segment<br>[835, 859, 4]"] | ||||
|     447["Segment<br>[867, 919, 4]"] | ||||
|     448["Segment<br>[927, 979, 4]"] | ||||
|     449["Segment<br>[987, 1012, 4]"] | ||||
|     450["Segment<br>[1020, 1044, 4]"] | ||||
|     451["Segment<br>[1052, 1105, 4]"] | ||||
|     452["Segment<br>[1113, 1138, 4]"] | ||||
|     453["Segment<br>[1146, 1173, 4]"] | ||||
|     454["Segment<br>[1181, 1233, 4]"] | ||||
|     455["Segment<br>[1241, 1276, 4]"] | ||||
|     456["Segment<br>[1284, 1291, 4]"] | ||||
|     457[Solid2d] | ||||
|   end | ||||
|   subgraph path522 [Path] | ||||
|     522["Path<br>[1685, 1709, 3]"] | ||||
|     522["Path<br>[1685, 1709, 4]"] | ||||
|   end | ||||
|   subgraph path523 [Path] | ||||
|     523["Path<br>[1717, 1847, 3]"] | ||||
|     524["Segment<br>[1717, 1847, 3]"] | ||||
|     525["Segment<br>[1717, 1847, 3]"] | ||||
|     526["Segment<br>[1717, 1847, 3]"] | ||||
|     527["Segment<br>[1717, 1847, 3]"] | ||||
|     528["Segment<br>[1717, 1847, 3]"] | ||||
|     529["Segment<br>[1717, 1847, 3]"] | ||||
|     530["Segment<br>[1717, 1847, 3]"] | ||||
|     523["Path<br>[1717, 1847, 4]"] | ||||
|     524["Segment<br>[1717, 1847, 4]"] | ||||
|     525["Segment<br>[1717, 1847, 4]"] | ||||
|     526["Segment<br>[1717, 1847, 4]"] | ||||
|     527["Segment<br>[1717, 1847, 4]"] | ||||
|     528["Segment<br>[1717, 1847, 4]"] | ||||
|     529["Segment<br>[1717, 1847, 4]"] | ||||
|     530["Segment<br>[1717, 1847, 4]"] | ||||
|     531[Solid2d] | ||||
|   end | ||||
|   subgraph path553 [Path] | ||||
|     553["Path<br>[1685, 1709, 3]"] | ||||
|     553["Path<br>[1685, 1709, 4]"] | ||||
|   end | ||||
|   subgraph path554 [Path] | ||||
|     554["Path<br>[1717, 1847, 3]"] | ||||
|     555["Segment<br>[1717, 1847, 3]"] | ||||
|     556["Segment<br>[1717, 1847, 3]"] | ||||
|     557["Segment<br>[1717, 1847, 3]"] | ||||
|     558["Segment<br>[1717, 1847, 3]"] | ||||
|     559["Segment<br>[1717, 1847, 3]"] | ||||
|     560["Segment<br>[1717, 1847, 3]"] | ||||
|     561["Segment<br>[1717, 1847, 3]"] | ||||
|     554["Path<br>[1717, 1847, 4]"] | ||||
|     555["Segment<br>[1717, 1847, 4]"] | ||||
|     556["Segment<br>[1717, 1847, 4]"] | ||||
|     557["Segment<br>[1717, 1847, 4]"] | ||||
|     558["Segment<br>[1717, 1847, 4]"] | ||||
|     559["Segment<br>[1717, 1847, 4]"] | ||||
|     560["Segment<br>[1717, 1847, 4]"] | ||||
|     561["Segment<br>[1717, 1847, 4]"] | ||||
|     562[Solid2d] | ||||
|   end | ||||
|   subgraph path585 [Path] | ||||
|     585["Path<br>[2123, 2150, 3]"] | ||||
|     586["Segment<br>[2158, 2180, 3]"] | ||||
|     587["Segment<br>[2188, 2210, 3]"] | ||||
|     588["Segment<br>[2218, 2240, 3]"] | ||||
|     589["Segment<br>[2248, 2271, 3]"] | ||||
|     590["Segment<br>[2279, 2302, 3]"] | ||||
|     591["Segment<br>[2310, 2345, 3]"] | ||||
|     592["Segment<br>[2353, 2360, 3]"] | ||||
|     585["Path<br>[2123, 2150, 4]"] | ||||
|     586["Segment<br>[2158, 2180, 4]"] | ||||
|     587["Segment<br>[2188, 2210, 4]"] | ||||
|     588["Segment<br>[2218, 2240, 4]"] | ||||
|     589["Segment<br>[2248, 2271, 4]"] | ||||
|     590["Segment<br>[2279, 2302, 4]"] | ||||
|     591["Segment<br>[2310, 2345, 4]"] | ||||
|     592["Segment<br>[2353, 2360, 4]"] | ||||
|     593[Solid2d] | ||||
|   end | ||||
|   subgraph path618 [Path] | ||||
|     618["Path<br>[2632, 2661, 3]"] | ||||
|     619["Segment<br>[2669, 2692, 3]"] | ||||
|     620["Segment<br>[2700, 2725, 3]"] | ||||
|     621["Segment<br>[2733, 2757, 3]"] | ||||
|     622["Segment<br>[2765, 2789, 3]"] | ||||
|     623["Segment<br>[2797, 2819, 3]"] | ||||
|     624["Segment<br>[2827, 2862, 3]"] | ||||
|     625["Segment<br>[2870, 2877, 3]"] | ||||
|     618["Path<br>[2632, 2661, 4]"] | ||||
|     619["Segment<br>[2669, 2692, 4]"] | ||||
|     620["Segment<br>[2700, 2725, 4]"] | ||||
|     621["Segment<br>[2733, 2757, 4]"] | ||||
|     622["Segment<br>[2765, 2789, 4]"] | ||||
|     623["Segment<br>[2797, 2819, 4]"] | ||||
|     624["Segment<br>[2827, 2862, 4]"] | ||||
|     625["Segment<br>[2870, 2877, 4]"] | ||||
|     626[Solid2d] | ||||
|   end | ||||
|   subgraph path650 [Path] | ||||
|     650["Path<br>[3152, 3179, 3]"] | ||||
|     651["Segment<br>[3187, 3206, 3]"] | ||||
|     652["Segment<br>[3214, 3304, 3]"] | ||||
|     650["Path<br>[3152, 3179, 4]"] | ||||
|     651["Segment<br>[3187, 3206, 4]"] | ||||
|     652["Segment<br>[3214, 3304, 4]"] | ||||
|   end | ||||
|   subgraph path654 [Path] | ||||
|     654["Path<br>[3404, 3437, 3]"] | ||||
|     655["Segment<br>[3445, 3464, 3]"] | ||||
|     656["Segment<br>[3472, 3494, 3]"] | ||||
|     657["Segment<br>[3502, 3525, 3]"] | ||||
|     658["Segment<br>[3533, 3553, 3]"] | ||||
|     659["Segment<br>[3561, 3585, 3]"] | ||||
|     660["Segment<br>[3593, 3616, 3]"] | ||||
|     661["Segment<br>[3624, 3631, 3]"] | ||||
|     654["Path<br>[3404, 3437, 4]"] | ||||
|     655["Segment<br>[3445, 3464, 4]"] | ||||
|     656["Segment<br>[3472, 3494, 4]"] | ||||
|     657["Segment<br>[3502, 3525, 4]"] | ||||
|     658["Segment<br>[3533, 3553, 4]"] | ||||
|     659["Segment<br>[3561, 3585, 4]"] | ||||
|     660["Segment<br>[3593, 3616, 4]"] | ||||
|     661["Segment<br>[3624, 3631, 4]"] | ||||
|     662[Solid2d] | ||||
|   end | ||||
|   subgraph path688 [Path] | ||||
|     688["Path<br>[3152, 3179, 3]"] | ||||
|     689["Segment<br>[3187, 3206, 3]"] | ||||
|     690["Segment<br>[3214, 3304, 3]"] | ||||
|     688["Path<br>[3152, 3179, 4]"] | ||||
|     689["Segment<br>[3187, 3206, 4]"] | ||||
|     690["Segment<br>[3214, 3304, 4]"] | ||||
|   end | ||||
|   subgraph path692 [Path] | ||||
|     692["Path<br>[3404, 3437, 3]"] | ||||
|     693["Segment<br>[3445, 3464, 3]"] | ||||
|     694["Segment<br>[3472, 3494, 3]"] | ||||
|     695["Segment<br>[3502, 3525, 3]"] | ||||
|     696["Segment<br>[3533, 3553, 3]"] | ||||
|     697["Segment<br>[3561, 3585, 3]"] | ||||
|     698["Segment<br>[3593, 3616, 3]"] | ||||
|     699["Segment<br>[3624, 3631, 3]"] | ||||
|     692["Path<br>[3404, 3437, 4]"] | ||||
|     693["Segment<br>[3445, 3464, 4]"] | ||||
|     694["Segment<br>[3472, 3494, 4]"] | ||||
|     695["Segment<br>[3502, 3525, 4]"] | ||||
|     696["Segment<br>[3533, 3553, 4]"] | ||||
|     697["Segment<br>[3561, 3585, 4]"] | ||||
|     698["Segment<br>[3593, 3616, 4]"] | ||||
|     699["Segment<br>[3624, 3631, 4]"] | ||||
|     700[Solid2d] | ||||
|   end | ||||
|   1["Plane<br>[333, 353, 3]"] | ||||
|   25["Sweep Extrusion<br>[1379, 1417, 3]"] | ||||
|   1["Plane<br>[333, 353, 4]"] | ||||
|   25["Sweep Extrusion<br>[1379, 1417, 4]"] | ||||
|   26[Wall] | ||||
|   27[Wall] | ||||
|   28[Wall] | ||||
| @ -296,8 +296,8 @@ flowchart LR | ||||
|   85["SweepEdge Adjacent"] | ||||
|   86["SweepEdge Opposite"] | ||||
|   87["SweepEdge Adjacent"] | ||||
|   88["Plane<br>[333, 353, 3]"] | ||||
|   112["Sweep Extrusion<br>[1455, 1494, 3]"] | ||||
|   88["Plane<br>[333, 353, 4]"] | ||||
|   112["Sweep Extrusion<br>[1455, 1494, 4]"] | ||||
|   113[Wall] | ||||
|   114[Wall] | ||||
|   115[Wall] | ||||
| @ -361,7 +361,7 @@ flowchart LR | ||||
|   173["SweepEdge Opposite"] | ||||
|   174["SweepEdge Adjacent"] | ||||
|   175["Plane<br>[825, 869, 0]"] | ||||
|   199["Sweep Extrusion<br>[1379, 1417, 3]"] | ||||
|   199["Sweep Extrusion<br>[1379, 1417, 4]"] | ||||
|   200[Wall] | ||||
|   201[Wall] | ||||
|   202[Wall] | ||||
| @ -424,7 +424,7 @@ flowchart LR | ||||
|   259["SweepEdge Adjacent"] | ||||
|   260["SweepEdge Opposite"] | ||||
|   261["SweepEdge Adjacent"] | ||||
|   285["Sweep Extrusion<br>[1455, 1494, 3]"] | ||||
|   285["Sweep Extrusion<br>[1455, 1494, 4]"] | ||||
|   286[Wall] | ||||
|   287[Wall] | ||||
|   288[Wall] | ||||
| @ -488,7 +488,7 @@ flowchart LR | ||||
|   346["SweepEdge Opposite"] | ||||
|   347["SweepEdge Adjacent"] | ||||
|   348["Plane<br>[879, 922, 0]"] | ||||
|   372["Sweep Extrusion<br>[1379, 1417, 3]"] | ||||
|   372["Sweep Extrusion<br>[1379, 1417, 4]"] | ||||
|   373[Wall] | ||||
|   374[Wall] | ||||
|   375[Wall] | ||||
| @ -551,7 +551,7 @@ flowchart LR | ||||
|   432["SweepEdge Adjacent"] | ||||
|   433["SweepEdge Opposite"] | ||||
|   434["SweepEdge Adjacent"] | ||||
|   458["Sweep Extrusion<br>[1455, 1494, 3]"] | ||||
|   458["Sweep Extrusion<br>[1455, 1494, 4]"] | ||||
|   459[Wall] | ||||
|   460[Wall] | ||||
|   461[Wall] | ||||
| @ -615,7 +615,7 @@ flowchart LR | ||||
|   519["SweepEdge Opposite"] | ||||
|   520["SweepEdge Adjacent"] | ||||
|   521["Plane<br>[981, 1025, 0]"] | ||||
|   532["Sweep Extrusion<br>[1949, 1973, 3]"] | ||||
|   532["Sweep Extrusion<br>[1949, 1973, 4]"] | ||||
|   533[Wall] | ||||
|   534[Wall] | ||||
|   535[Wall] | ||||
| @ -636,7 +636,7 @@ flowchart LR | ||||
|   550["SweepEdge Adjacent"] | ||||
|   551["SweepEdge Opposite"] | ||||
|   552["SweepEdge Adjacent"] | ||||
|   563["Sweep Extrusion<br>[2015, 2039, 3]"] | ||||
|   563["Sweep Extrusion<br>[2015, 2039, 4]"] | ||||
|   564[Wall] | ||||
|   565[Wall] | ||||
|   566[Wall] | ||||
| @ -658,7 +658,7 @@ flowchart LR | ||||
|   582["SweepEdge Opposite"] | ||||
|   583["SweepEdge Adjacent"] | ||||
|   584["Plane<br>[1076, 1143, 0]"] | ||||
|   594["Sweep Extrusion<br>[2523, 2547, 3]"] | ||||
|   594["Sweep Extrusion<br>[2523, 2547, 4]"] | ||||
|   595[Wall] | ||||
|   596[Wall] | ||||
|   597[Wall] | ||||
| @ -679,10 +679,10 @@ flowchart LR | ||||
|   612["SweepEdge Adjacent"] | ||||
|   613["SweepEdge Opposite"] | ||||
|   614["SweepEdge Adjacent"] | ||||
|   615["Sweep Extrusion<br>[2523, 2547, 3]"] | ||||
|   616["Sweep Extrusion<br>[2523, 2547, 3]"] | ||||
|   615["Sweep Extrusion<br>[2523, 2547, 4]"] | ||||
|   616["Sweep Extrusion<br>[2523, 2547, 4]"] | ||||
|   617["Plane<br>[1213, 1280, 0]"] | ||||
|   627["Sweep Extrusion<br>[3047, 3071, 3]"] | ||||
|   627["Sweep Extrusion<br>[3047, 3071, 4]"] | ||||
|   628[Wall] | ||||
|   629[Wall] | ||||
|   630[Wall] | ||||
| @ -703,10 +703,10 @@ flowchart LR | ||||
|   645["SweepEdge Adjacent"] | ||||
|   646["SweepEdge Opposite"] | ||||
|   647["SweepEdge Adjacent"] | ||||
|   648["Sweep Extrusion<br>[3047, 3071, 3]"] | ||||
|   649["Plane<br>[3712, 3747, 3]"] | ||||
|   653["Plane<br>[3778, 3809, 3]"] | ||||
|   663["Sweep Sweep<br>[3821, 3848, 3]"] | ||||
|   648["Sweep Extrusion<br>[3047, 3071, 4]"] | ||||
|   649["Plane<br>[3712, 3747, 4]"] | ||||
|   653["Plane<br>[3778, 3809, 4]"] | ||||
|   663["Sweep Sweep<br>[3821, 3848, 4]"] | ||||
|   664[Wall] | ||||
|   665[Wall] | ||||
|   666[Wall] | ||||
| @ -730,9 +730,9 @@ flowchart LR | ||||
|   684["SweepEdge Adjacent"] | ||||
|   685["SweepEdge Opposite"] | ||||
|   686["SweepEdge Adjacent"] | ||||
|   687["Plane<br>[3712, 3747, 3]"] | ||||
|   691["Plane<br>[3778, 3809, 3]"] | ||||
|   701["Sweep Sweep<br>[3821, 3848, 3]"] | ||||
|   687["Plane<br>[3712, 3747, 4]"] | ||||
|   691["Plane<br>[3778, 3809, 4]"] | ||||
|   701["Sweep Sweep<br>[3821, 3848, 4]"] | ||||
|   702[Wall] | ||||
|   703[Wall] | ||||
|   704[Wall] | ||||
| @ -756,18 +756,18 @@ flowchart LR | ||||
|   722["SweepEdge Adjacent"] | ||||
|   723["SweepEdge Opposite"] | ||||
|   724["SweepEdge Adjacent"] | ||||
|   725["StartSketchOnPlane<br>[333, 353, 3]"] | ||||
|   726["StartSketchOnPlane<br>[333, 353, 3]"] | ||||
|   727["StartSketchOnPlane<br>[333, 353, 3]"] | ||||
|   728["StartSketchOnPlane<br>[333, 353, 3]"] | ||||
|   729["StartSketchOnPlane<br>[1657, 1677, 3]"] | ||||
|   730["StartSketchOnPlane<br>[1657, 1677, 3]"] | ||||
|   731["StartSketchOnPlane<br>[2095, 2115, 3]"] | ||||
|   732["StartSketchOnPlane<br>[2604, 2624, 3]"] | ||||
|   733["StartSketchOnPlane<br>[3124, 3144, 3]"] | ||||
|   734["StartSketchOnPlane<br>[3376, 3396, 3]"] | ||||
|   735["StartSketchOnPlane<br>[3124, 3144, 3]"] | ||||
|   736["StartSketchOnPlane<br>[3376, 3396, 3]"] | ||||
|   725["StartSketchOnPlane<br>[333, 353, 4]"] | ||||
|   726["StartSketchOnPlane<br>[333, 353, 4]"] | ||||
|   727["StartSketchOnPlane<br>[333, 353, 4]"] | ||||
|   728["StartSketchOnPlane<br>[333, 353, 4]"] | ||||
|   729["StartSketchOnPlane<br>[1657, 1677, 4]"] | ||||
|   730["StartSketchOnPlane<br>[1657, 1677, 4]"] | ||||
|   731["StartSketchOnPlane<br>[2095, 2115, 4]"] | ||||
|   732["StartSketchOnPlane<br>[2604, 2624, 4]"] | ||||
|   733["StartSketchOnPlane<br>[3124, 3144, 4]"] | ||||
|   734["StartSketchOnPlane<br>[3376, 3396, 4]"] | ||||
|   735["StartSketchOnPlane<br>[3124, 3144, 4]"] | ||||
|   736["StartSketchOnPlane<br>[3376, 3396, 4]"] | ||||
|   1 --- 2 | ||||
|   2 --- 3 | ||||
|   2 --- 4 | ||||
|  | ||||
| @ -9,7 +9,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       1331, | ||||
|       1606, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -21,7 +21,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       309, | ||||
|       1312, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -77,7 +77,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       309, | ||||
|       1312, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -248,7 +248,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       1331, | ||||
|       1606, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -260,7 +260,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       309, | ||||
|       1312, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -316,7 +316,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       309, | ||||
|       1312, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -487,7 +487,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       1331, | ||||
|       1606, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -499,7 +499,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       309, | ||||
|       1312, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -555,7 +555,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       309, | ||||
|       1312, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -726,7 +726,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       1889, | ||||
|       2052, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -738,7 +738,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       1626, | ||||
|       1868, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -800,7 +800,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       1626, | ||||
|       1868, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -889,7 +889,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       2474, | ||||
|       2560, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -901,7 +901,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       2071, | ||||
|       2453, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1007,7 +1007,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       2993, | ||||
|       3084, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1019,7 +1019,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       2580, | ||||
|       2972, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1095,7 +1095,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       3671, | ||||
|       3861, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1131,7 +1131,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       3100, | ||||
|       3325, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1191,7 +1191,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       3344, | ||||
|       3652, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1249,7 +1249,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       3671, | ||||
|       3861, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1285,7 +1285,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       3100, | ||||
|       3325, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1345,7 +1345,7 @@ description: Operations executed bench.kcl | ||||
|     "functionSourceRange": [ | ||||
|       3344, | ||||
|       3652, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
|  | ||||
| @ -255,6 +255,66 @@ description: Operations executed bracket.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": -1.25, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 1.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.25, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -329,6 +389,66 @@ description: Operations executed bracket.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 1.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": -1.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.25, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
|  | ||||
| @ -1,264 +1,264 @@ | ||||
| ```mermaid | ||||
| flowchart LR | ||||
|   subgraph path2 [Path] | ||||
|     2["Path<br>[571, 643, 4]"] | ||||
|     3["Segment<br>[571, 643, 4]"] | ||||
|     2["Path<br>[571, 643, 5]"] | ||||
|     3["Segment<br>[571, 643, 5]"] | ||||
|     4[Solid2d] | ||||
|   end | ||||
|   subgraph path11 [Path] | ||||
|     11["Path<br>[828, 905, 4]"] | ||||
|     12["Segment<br>[828, 905, 4]"] | ||||
|     11["Path<br>[828, 905, 5]"] | ||||
|     12["Segment<br>[828, 905, 5]"] | ||||
|     13[Solid2d] | ||||
|   end | ||||
|   subgraph path19 [Path] | ||||
|     19["Path<br>[1030, 1104, 4]"] | ||||
|     20["Segment<br>[1030, 1104, 4]"] | ||||
|     19["Path<br>[1030, 1104, 5]"] | ||||
|     20["Segment<br>[1030, 1104, 5]"] | ||||
|     21[Solid2d] | ||||
|   end | ||||
|   subgraph path30 [Path] | ||||
|     30["Path<br>[1486, 1526, 4]"] | ||||
|     31["Segment<br>[1486, 1526, 4]"] | ||||
|     30["Path<br>[1486, 1526, 5]"] | ||||
|     31["Segment<br>[1486, 1526, 5]"] | ||||
|     32[Solid2d] | ||||
|   end | ||||
|   subgraph path38 [Path] | ||||
|     38["Path<br>[1630, 1702, 4]"] | ||||
|     39["Segment<br>[1630, 1702, 4]"] | ||||
|     38["Path<br>[1630, 1702, 5]"] | ||||
|     39["Segment<br>[1630, 1702, 5]"] | ||||
|     40[Solid2d] | ||||
|   end | ||||
|   subgraph path47 [Path] | ||||
|     47["Path<br>[1835, 1909, 4]"] | ||||
|     48["Segment<br>[1835, 1909, 4]"] | ||||
|     47["Path<br>[1835, 1909, 5]"] | ||||
|     48["Segment<br>[1835, 1909, 5]"] | ||||
|     49[Solid2d] | ||||
|   end | ||||
|   subgraph path58 [Path] | ||||
|     58["Path<br>[2151, 2244, 4]"] | ||||
|     59["Segment<br>[2151, 2244, 4]"] | ||||
|     58["Path<br>[2151, 2244, 5]"] | ||||
|     59["Segment<br>[2151, 2244, 5]"] | ||||
|     60[Solid2d] | ||||
|   end | ||||
|   subgraph path81 [Path] | ||||
|     81["Path<br>[2500, 2531, 4]"] | ||||
|     82["Segment<br>[2537, 2557, 4]"] | ||||
|     83["Segment<br>[2563, 2583, 4]"] | ||||
|     84["Segment<br>[2589, 2610, 4]"] | ||||
|     85["Segment<br>[2616, 2672, 4]"] | ||||
|     86["Segment<br>[2678, 2685, 4]"] | ||||
|     81["Path<br>[2500, 2531, 5]"] | ||||
|     82["Segment<br>[2537, 2557, 5]"] | ||||
|     83["Segment<br>[2563, 2583, 5]"] | ||||
|     84["Segment<br>[2589, 2610, 5]"] | ||||
|     85["Segment<br>[2616, 2672, 5]"] | ||||
|     86["Segment<br>[2678, 2685, 5]"] | ||||
|     87[Solid2d] | ||||
|   end | ||||
|   subgraph path106 [Path] | ||||
|     106["Path<br>[2986, 3018, 4]"] | ||||
|     107["Segment<br>[3024, 3045, 4]"] | ||||
|     108["Segment<br>[3051, 3071, 4]"] | ||||
|     109["Segment<br>[3077, 3097, 4]"] | ||||
|     110["Segment<br>[3103, 3159, 4]"] | ||||
|     111["Segment<br>[3165, 3172, 4]"] | ||||
|     106["Path<br>[2986, 3018, 5]"] | ||||
|     107["Segment<br>[3024, 3045, 5]"] | ||||
|     108["Segment<br>[3051, 3071, 5]"] | ||||
|     109["Segment<br>[3077, 3097, 5]"] | ||||
|     110["Segment<br>[3103, 3159, 5]"] | ||||
|     111["Segment<br>[3165, 3172, 5]"] | ||||
|     112[Solid2d] | ||||
|   end | ||||
|   subgraph path132 [Path] | ||||
|     132["Path<br>[354, 431, 3]"] | ||||
|     133["Segment<br>[354, 431, 3]"] | ||||
|     132["Path<br>[354, 431, 4]"] | ||||
|     133["Segment<br>[354, 431, 4]"] | ||||
|     134[Solid2d] | ||||
|   end | ||||
|   subgraph path135 [Path] | ||||
|     135["Path<br>[442, 519, 3]"] | ||||
|     136["Segment<br>[442, 519, 3]"] | ||||
|     135["Path<br>[442, 519, 4]"] | ||||
|     136["Segment<br>[442, 519, 4]"] | ||||
|     137[Solid2d] | ||||
|   end | ||||
|   subgraph path144 [Path] | ||||
|     144["Path<br>[684, 761, 3]"] | ||||
|     145["Segment<br>[684, 761, 3]"] | ||||
|     144["Path<br>[684, 761, 4]"] | ||||
|     145["Segment<br>[684, 761, 4]"] | ||||
|     146[Solid2d] | ||||
|   end | ||||
|   subgraph path147 [Path] | ||||
|     147["Path<br>[772, 849, 3]"] | ||||
|     148["Segment<br>[772, 849, 3]"] | ||||
|     147["Path<br>[772, 849, 4]"] | ||||
|     148["Segment<br>[772, 849, 4]"] | ||||
|     149[Solid2d] | ||||
|   end | ||||
|   subgraph path156 [Path] | ||||
|     156["Path<br>[993, 1068, 3]"] | ||||
|     157["Segment<br>[993, 1068, 3]"] | ||||
|     156["Path<br>[993, 1068, 4]"] | ||||
|     157["Segment<br>[993, 1068, 4]"] | ||||
|     158[Solid2d] | ||||
|   end | ||||
|   subgraph path167 [Path] | ||||
|     167["Path<br>[1345, 1426, 3]"] | ||||
|     168["Segment<br>[1345, 1426, 3]"] | ||||
|     167["Path<br>[1345, 1426, 4]"] | ||||
|     168["Segment<br>[1345, 1426, 4]"] | ||||
|     169[Solid2d] | ||||
|   end | ||||
|   subgraph path179 [Path] | ||||
|     179["Path<br>[1785, 1831, 3]"] | ||||
|     180["Segment<br>[1837, 1889, 3]"] | ||||
|     181["Segment<br>[1895, 2000, 3]"] | ||||
|     182["Segment<br>[2006, 2028, 3]"] | ||||
|     183["Segment<br>[2034, 2090, 3]"] | ||||
|     184["Segment<br>[2096, 2103, 3]"] | ||||
|     179["Path<br>[1785, 1831, 4]"] | ||||
|     180["Segment<br>[1837, 1889, 4]"] | ||||
|     181["Segment<br>[1895, 2000, 4]"] | ||||
|     182["Segment<br>[2006, 2028, 4]"] | ||||
|     183["Segment<br>[2034, 2090, 4]"] | ||||
|     184["Segment<br>[2096, 2103, 4]"] | ||||
|     185[Solid2d] | ||||
|   end | ||||
|   subgraph path195 [Path] | ||||
|     195["Path<br>[2239, 2285, 3]"] | ||||
|     196["Segment<br>[2291, 2343, 3]"] | ||||
|     197["Segment<br>[2349, 2456, 3]"] | ||||
|     198["Segment<br>[2462, 2499, 3]"] | ||||
|     199["Segment<br>[2505, 2561, 3]"] | ||||
|     200["Segment<br>[2567, 2574, 3]"] | ||||
|     195["Path<br>[2239, 2285, 4]"] | ||||
|     196["Segment<br>[2291, 2343, 4]"] | ||||
|     197["Segment<br>[2349, 2456, 4]"] | ||||
|     198["Segment<br>[2462, 2499, 4]"] | ||||
|     199["Segment<br>[2505, 2561, 4]"] | ||||
|     200["Segment<br>[2567, 2574, 4]"] | ||||
|     201[Solid2d] | ||||
|   end | ||||
|   subgraph path212 [Path] | ||||
|     212["Path<br>[3085, 3132, 3]"] | ||||
|     213["Segment<br>[3140, 3480, 3]"] | ||||
|     214["Segment<br>[3488, 3520, 3]"] | ||||
|     215["Segment<br>[3528, 3872, 3]"] | ||||
|     216["Segment<br>[3880, 3936, 3]"] | ||||
|     217["Segment<br>[3944, 3951, 3]"] | ||||
|     212["Path<br>[3085, 3132, 4]"] | ||||
|     213["Segment<br>[3140, 3480, 4]"] | ||||
|     214["Segment<br>[3488, 3520, 4]"] | ||||
|     215["Segment<br>[3528, 3872, 4]"] | ||||
|     216["Segment<br>[3880, 3936, 4]"] | ||||
|     217["Segment<br>[3944, 3951, 4]"] | ||||
|     218[Solid2d] | ||||
|   end | ||||
|   subgraph path235 [Path] | ||||
|     235["Path<br>[3085, 3132, 3]"] | ||||
|     236["Segment<br>[3140, 3480, 3]"] | ||||
|     237["Segment<br>[3488, 3520, 3]"] | ||||
|     238["Segment<br>[3528, 3872, 3]"] | ||||
|     239["Segment<br>[3880, 3936, 3]"] | ||||
|     240["Segment<br>[3944, 3951, 3]"] | ||||
|     235["Path<br>[3085, 3132, 4]"] | ||||
|     236["Segment<br>[3140, 3480, 4]"] | ||||
|     237["Segment<br>[3488, 3520, 4]"] | ||||
|     238["Segment<br>[3528, 3872, 4]"] | ||||
|     239["Segment<br>[3880, 3936, 4]"] | ||||
|     240["Segment<br>[3944, 3951, 4]"] | ||||
|     241[Solid2d] | ||||
|   end | ||||
|   subgraph path258 [Path] | ||||
|     258["Path<br>[4480, 4575, 3]"] | ||||
|     259["Segment<br>[4581, 4614, 3]"] | ||||
|     260["Segment<br>[4620, 4671, 3]"] | ||||
|     261["Segment<br>[4677, 4710, 3]"] | ||||
|     262["Segment<br>[4716, 4766, 3]"] | ||||
|     263["Segment<br>[4772, 4813, 3]"] | ||||
|     264["Segment<br>[4819, 4868, 3]"] | ||||
|     265["Segment<br>[4874, 4907, 3]"] | ||||
|     266["Segment<br>[4913, 4947, 3]"] | ||||
|     267["Segment<br>[4953, 4987, 3]"] | ||||
|     268["Segment<br>[4993, 5045, 3]"] | ||||
|     269["Segment<br>[5051, 5085, 3]"] | ||||
|     270["Segment<br>[5091, 5167, 3]"] | ||||
|     271["Segment<br>[5173, 5206, 3]"] | ||||
|     272["Segment<br>[5212, 5288, 3]"] | ||||
|     273["Segment<br>[5294, 5328, 3]"] | ||||
|     274["Segment<br>[5334, 5408, 3]"] | ||||
|     275["Segment<br>[5414, 5448, 3]"] | ||||
|     276["Segment<br>[5454, 5505, 3]"] | ||||
|     277["Segment<br>[5511, 5573, 3]"] | ||||
|     278["Segment<br>[5579, 5630, 3]"] | ||||
|     279["Segment<br>[5636, 5670, 3]"] | ||||
|     280["Segment<br>[5676, 5709, 3]"] | ||||
|     281["Segment<br>[5715, 5748, 3]"] | ||||
|     282["Segment<br>[5754, 5761, 3]"] | ||||
|     258["Path<br>[4480, 4575, 4]"] | ||||
|     259["Segment<br>[4581, 4614, 4]"] | ||||
|     260["Segment<br>[4620, 4671, 4]"] | ||||
|     261["Segment<br>[4677, 4710, 4]"] | ||||
|     262["Segment<br>[4716, 4766, 4]"] | ||||
|     263["Segment<br>[4772, 4813, 4]"] | ||||
|     264["Segment<br>[4819, 4868, 4]"] | ||||
|     265["Segment<br>[4874, 4907, 4]"] | ||||
|     266["Segment<br>[4913, 4947, 4]"] | ||||
|     267["Segment<br>[4953, 4987, 4]"] | ||||
|     268["Segment<br>[4993, 5045, 4]"] | ||||
|     269["Segment<br>[5051, 5085, 4]"] | ||||
|     270["Segment<br>[5091, 5167, 4]"] | ||||
|     271["Segment<br>[5173, 5206, 4]"] | ||||
|     272["Segment<br>[5212, 5288, 4]"] | ||||
|     273["Segment<br>[5294, 5328, 4]"] | ||||
|     274["Segment<br>[5334, 5408, 4]"] | ||||
|     275["Segment<br>[5414, 5448, 4]"] | ||||
|     276["Segment<br>[5454, 5505, 4]"] | ||||
|     277["Segment<br>[5511, 5573, 4]"] | ||||
|     278["Segment<br>[5579, 5630, 4]"] | ||||
|     279["Segment<br>[5636, 5670, 4]"] | ||||
|     280["Segment<br>[5676, 5709, 4]"] | ||||
|     281["Segment<br>[5715, 5748, 4]"] | ||||
|     282["Segment<br>[5754, 5761, 4]"] | ||||
|     283[Solid2d] | ||||
|   end | ||||
|   subgraph path334 [Path] | ||||
|     334["Path<br>[742, 782, 6]"] | ||||
|     335["Segment<br>[790, 852, 6]"] | ||||
|     336["Segment<br>[860, 896, 6]"] | ||||
|     337["Segment<br>[904, 934, 6]"] | ||||
|     338["Segment<br>[942, 994, 6]"] | ||||
|     339["Segment<br>[1002, 1042, 6]"] | ||||
|     340["Segment<br>[1050, 1085, 6]"] | ||||
|     341["Segment<br>[1093, 1131, 6]"] | ||||
|     342["Segment<br>[1139, 1161, 6]"] | ||||
|     343["Segment<br>[1169, 1176, 6]"] | ||||
|     334["Path<br>[742, 782, 7]"] | ||||
|     335["Segment<br>[790, 852, 7]"] | ||||
|     336["Segment<br>[860, 896, 7]"] | ||||
|     337["Segment<br>[904, 934, 7]"] | ||||
|     338["Segment<br>[942, 994, 7]"] | ||||
|     339["Segment<br>[1002, 1042, 7]"] | ||||
|     340["Segment<br>[1050, 1085, 7]"] | ||||
|     341["Segment<br>[1093, 1131, 7]"] | ||||
|     342["Segment<br>[1139, 1161, 7]"] | ||||
|     343["Segment<br>[1169, 1176, 7]"] | ||||
|     344[Solid2d] | ||||
|   end | ||||
|   subgraph path365 [Path] | ||||
|     365["Path<br>[511, 592, 5]"] | ||||
|     366["Segment<br>[598, 699, 5]"] | ||||
|     367["Segment<br>[705, 790, 5]"] | ||||
|     368["Segment<br>[796, 880, 5]"] | ||||
|     369["Segment<br>[886, 972, 5]"] | ||||
|     370["Segment<br>[978, 1063, 5]"] | ||||
|     371["Segment<br>[1069, 1155, 5]"] | ||||
|     372["Segment<br>[1161, 1284, 5]"] | ||||
|     373["Segment<br>[1290, 1376, 5]"] | ||||
|     374["Segment<br>[1382, 1517, 5]"] | ||||
|     375["Segment<br>[1523, 1609, 5]"] | ||||
|     376["Segment<br>[1615, 1739, 5]"] | ||||
|     377["Segment<br>[1745, 1831, 5]"] | ||||
|     378["Segment<br>[1837, 1922, 5]"] | ||||
|     379["Segment<br>[1928, 2014, 5]"] | ||||
|     380["Segment<br>[2020, 2105, 5]"] | ||||
|     381["Segment<br>[2111, 2196, 5]"] | ||||
|     382["Segment<br>[2202, 2209, 5]"] | ||||
|     365["Path<br>[511, 592, 6]"] | ||||
|     366["Segment<br>[598, 699, 6]"] | ||||
|     367["Segment<br>[705, 790, 6]"] | ||||
|     368["Segment<br>[796, 880, 6]"] | ||||
|     369["Segment<br>[886, 972, 6]"] | ||||
|     370["Segment<br>[978, 1063, 6]"] | ||||
|     371["Segment<br>[1069, 1155, 6]"] | ||||
|     372["Segment<br>[1161, 1284, 6]"] | ||||
|     373["Segment<br>[1290, 1376, 6]"] | ||||
|     374["Segment<br>[1382, 1517, 6]"] | ||||
|     375["Segment<br>[1523, 1609, 6]"] | ||||
|     376["Segment<br>[1615, 1739, 6]"] | ||||
|     377["Segment<br>[1745, 1831, 6]"] | ||||
|     378["Segment<br>[1837, 1922, 6]"] | ||||
|     379["Segment<br>[1928, 2014, 6]"] | ||||
|     380["Segment<br>[2020, 2105, 6]"] | ||||
|     381["Segment<br>[2111, 2196, 6]"] | ||||
|     382["Segment<br>[2202, 2209, 6]"] | ||||
|     383[Solid2d] | ||||
|   end | ||||
|   subgraph path439 [Path] | ||||
|     439["Path<br>[487, 544, 7]"] | ||||
|     440["Segment<br>[550, 656, 7]"] | ||||
|     441["Segment<br>[662, 717, 7]"] | ||||
|     442["Segment<br>[723, 820, 7]"] | ||||
|     443["Segment<br>[826, 858, 7]"] | ||||
|     444["Segment<br>[864, 896, 7]"] | ||||
|     445["Segment<br>[902, 933, 7]"] | ||||
|     446["Segment<br>[939, 1054, 7]"] | ||||
|     447["Segment<br>[1060, 1092, 7]"] | ||||
|     448["Segment<br>[1098, 1130, 7]"] | ||||
|     449["Segment<br>[1136, 1167, 7]"] | ||||
|     450["Segment<br>[1173, 1266, 7]"] | ||||
|     451["Segment<br>[1272, 1327, 7]"] | ||||
|     452["Segment<br>[1333, 1406, 7]"] | ||||
|     453["Segment<br>[1412, 1419, 7]"] | ||||
|     439["Path<br>[487, 544, 8]"] | ||||
|     440["Segment<br>[550, 656, 8]"] | ||||
|     441["Segment<br>[662, 717, 8]"] | ||||
|     442["Segment<br>[723, 820, 8]"] | ||||
|     443["Segment<br>[826, 858, 8]"] | ||||
|     444["Segment<br>[864, 896, 8]"] | ||||
|     445["Segment<br>[902, 933, 8]"] | ||||
|     446["Segment<br>[939, 1054, 8]"] | ||||
|     447["Segment<br>[1060, 1092, 8]"] | ||||
|     448["Segment<br>[1098, 1130, 8]"] | ||||
|     449["Segment<br>[1136, 1167, 8]"] | ||||
|     450["Segment<br>[1173, 1266, 8]"] | ||||
|     451["Segment<br>[1272, 1327, 8]"] | ||||
|     452["Segment<br>[1333, 1406, 8]"] | ||||
|     453["Segment<br>[1412, 1419, 8]"] | ||||
|     454[Solid2d] | ||||
|   end | ||||
|   1["Plane<br>[546, 565, 4]"] | ||||
|   5["Sweep Extrusion<br>[652, 708, 4]"] | ||||
|   1["Plane<br>[546, 565, 5]"] | ||||
|   5["Sweep Extrusion<br>[652, 708, 5]"] | ||||
|   6[Wall] | ||||
|   7["Cap Start"] | ||||
|   8["Cap End"] | ||||
|   9["SweepEdge Opposite"] | ||||
|   10["SweepEdge Adjacent"] | ||||
|   14["Sweep Extrusion<br>[918, 980, 4]"] | ||||
|   14["Sweep Extrusion<br>[918, 980, 5]"] | ||||
|   15[Wall] | ||||
|   16["Cap End"] | ||||
|   17["SweepEdge Opposite"] | ||||
|   18["SweepEdge Adjacent"] | ||||
|   22["Sweep Extrusion<br>[1250, 1329, 4]"] | ||||
|   22["Sweep Extrusion<br>[1250, 1329, 5]"] | ||||
|   23[Wall] | ||||
|   24["SweepEdge Opposite"] | ||||
|   25["SweepEdge Adjacent"] | ||||
|   26["Sweep Extrusion<br>[1250, 1329, 4]"] | ||||
|   27["Sweep Extrusion<br>[1250, 1329, 4]"] | ||||
|   28["Sweep Extrusion<br>[1250, 1329, 4]"] | ||||
|   29["Sweep Extrusion<br>[1250, 1329, 4]"] | ||||
|   33["Sweep Extrusion<br>[1532, 1565, 4]"] | ||||
|   26["Sweep Extrusion<br>[1250, 1329, 5]"] | ||||
|   27["Sweep Extrusion<br>[1250, 1329, 5]"] | ||||
|   28["Sweep Extrusion<br>[1250, 1329, 5]"] | ||||
|   29["Sweep Extrusion<br>[1250, 1329, 5]"] | ||||
|   33["Sweep Extrusion<br>[1532, 1565, 5]"] | ||||
|   34[Wall] | ||||
|   35["Cap End"] | ||||
|   36["SweepEdge Opposite"] | ||||
|   37["SweepEdge Adjacent"] | ||||
|   41["Sweep Extrusion<br>[1717, 1782, 4]"] | ||||
|   41["Sweep Extrusion<br>[1717, 1782, 5]"] | ||||
|   42[Wall] | ||||
|   43["Cap Start"] | ||||
|   44["Cap End"] | ||||
|   45["SweepEdge Opposite"] | ||||
|   46["SweepEdge Adjacent"] | ||||
|   50["Sweep Extrusion<br>[2055, 2099, 4]"] | ||||
|   50["Sweep Extrusion<br>[2055, 2099, 5]"] | ||||
|   51[Wall] | ||||
|   52["SweepEdge Opposite"] | ||||
|   53["SweepEdge Adjacent"] | ||||
|   54["Sweep Extrusion<br>[2055, 2099, 4]"] | ||||
|   55["Sweep Extrusion<br>[2055, 2099, 4]"] | ||||
|   56["Sweep Extrusion<br>[2055, 2099, 4]"] | ||||
|   57["Sweep Extrusion<br>[2055, 2099, 4]"] | ||||
|   61["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   54["Sweep Extrusion<br>[2055, 2099, 5]"] | ||||
|   55["Sweep Extrusion<br>[2055, 2099, 5]"] | ||||
|   56["Sweep Extrusion<br>[2055, 2099, 5]"] | ||||
|   57["Sweep Extrusion<br>[2055, 2099, 5]"] | ||||
|   61["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   62[Wall] | ||||
|   63["Cap End"] | ||||
|   64["SweepEdge Opposite"] | ||||
|   65["SweepEdge Adjacent"] | ||||
|   66["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   67["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   68["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   69["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   70["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   71["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   72["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   73["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   74["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   75["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   76["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   77["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   78["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   79["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   80["Sweep Extrusion<br>[2398, 2442, 4]"] | ||||
|   88["Sweep Extrusion<br>[2850, 2918, 4]"] | ||||
|   66["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   67["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   68["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   69["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   70["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   71["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   72["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   73["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   74["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   75["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   76["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   77["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   78["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   79["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   80["Sweep Extrusion<br>[2398, 2442, 5]"] | ||||
|   88["Sweep Extrusion<br>[2850, 2918, 5]"] | ||||
|   89[Wall] | ||||
|   90[Wall] | ||||
|   91[Wall] | ||||
| @ -272,11 +272,11 @@ flowchart LR | ||||
|   99["SweepEdge Adjacent"] | ||||
|   100["SweepEdge Opposite"] | ||||
|   101["SweepEdge Adjacent"] | ||||
|   102["Sweep Extrusion<br>[2850, 2918, 4]"] | ||||
|   103["Sweep Extrusion<br>[2850, 2918, 4]"] | ||||
|   104["Sweep Extrusion<br>[2850, 2918, 4]"] | ||||
|   105["Sweep Extrusion<br>[2850, 2918, 4]"] | ||||
|   113["Sweep Extrusion<br>[3323, 3397, 4]"] | ||||
|   102["Sweep Extrusion<br>[2850, 2918, 5]"] | ||||
|   103["Sweep Extrusion<br>[2850, 2918, 5]"] | ||||
|   104["Sweep Extrusion<br>[2850, 2918, 5]"] | ||||
|   105["Sweep Extrusion<br>[2850, 2918, 5]"] | ||||
|   113["Sweep Extrusion<br>[3323, 3397, 5]"] | ||||
|   114[Wall] | ||||
|   115[Wall] | ||||
|   116[Wall] | ||||
| @ -290,41 +290,41 @@ flowchart LR | ||||
|   124["SweepEdge Adjacent"] | ||||
|   125["SweepEdge Opposite"] | ||||
|   126["SweepEdge Adjacent"] | ||||
|   127["Sweep Extrusion<br>[3323, 3397, 4]"] | ||||
|   128["Sweep Extrusion<br>[3323, 3397, 4]"] | ||||
|   129["Sweep Extrusion<br>[3323, 3397, 4]"] | ||||
|   130["Sweep Extrusion<br>[3323, 3397, 4]"] | ||||
|   131["Plane<br>[329, 348, 3]"] | ||||
|   138["Sweep Extrusion<br>[529, 562, 3]"] | ||||
|   127["Sweep Extrusion<br>[3323, 3397, 5]"] | ||||
|   128["Sweep Extrusion<br>[3323, 3397, 5]"] | ||||
|   129["Sweep Extrusion<br>[3323, 3397, 5]"] | ||||
|   130["Sweep Extrusion<br>[3323, 3397, 5]"] | ||||
|   131["Plane<br>[329, 348, 4]"] | ||||
|   138["Sweep Extrusion<br>[529, 562, 4]"] | ||||
|   139[Wall] | ||||
|   140["Cap Start"] | ||||
|   141["Cap End"] | ||||
|   142["SweepEdge Opposite"] | ||||
|   143["SweepEdge Adjacent"] | ||||
|   150["Sweep Extrusion<br>[859, 892, 3]"] | ||||
|   150["Sweep Extrusion<br>[859, 892, 4]"] | ||||
|   151[Wall] | ||||
|   152["Cap Start"] | ||||
|   153["Cap End"] | ||||
|   154["SweepEdge Opposite"] | ||||
|   155["SweepEdge Adjacent"] | ||||
|   159["Sweep Extrusion<br>[1214, 1248, 3]"] | ||||
|   159["Sweep Extrusion<br>[1214, 1248, 4]"] | ||||
|   160[Wall] | ||||
|   161["SweepEdge Opposite"] | ||||
|   162["SweepEdge Adjacent"] | ||||
|   163["Sweep Extrusion<br>[1214, 1248, 3]"] | ||||
|   164["Sweep Extrusion<br>[1214, 1248, 3]"] | ||||
|   165["Sweep Extrusion<br>[1214, 1248, 3]"] | ||||
|   166["Sweep Extrusion<br>[1214, 1248, 3]"] | ||||
|   170["Sweep Extrusion<br>[1572, 1606, 3]"] | ||||
|   163["Sweep Extrusion<br>[1214, 1248, 4]"] | ||||
|   164["Sweep Extrusion<br>[1214, 1248, 4]"] | ||||
|   165["Sweep Extrusion<br>[1214, 1248, 4]"] | ||||
|   166["Sweep Extrusion<br>[1214, 1248, 4]"] | ||||
|   170["Sweep Extrusion<br>[1572, 1606, 4]"] | ||||
|   171[Wall] | ||||
|   172["SweepEdge Opposite"] | ||||
|   173["SweepEdge Adjacent"] | ||||
|   174["Sweep Extrusion<br>[1572, 1606, 3]"] | ||||
|   175["Sweep Extrusion<br>[1572, 1606, 3]"] | ||||
|   176["Sweep Extrusion<br>[1572, 1606, 3]"] | ||||
|   177["Sweep Extrusion<br>[1572, 1606, 3]"] | ||||
|   178["Plane<br>[1760, 1779, 3]"] | ||||
|   186["Sweep Revolve<br>[2109, 2128, 3]"] | ||||
|   174["Sweep Extrusion<br>[1572, 1606, 4]"] | ||||
|   175["Sweep Extrusion<br>[1572, 1606, 4]"] | ||||
|   176["Sweep Extrusion<br>[1572, 1606, 4]"] | ||||
|   177["Sweep Extrusion<br>[1572, 1606, 4]"] | ||||
|   178["Plane<br>[1760, 1779, 4]"] | ||||
|   186["Sweep Revolve<br>[2109, 2128, 4]"] | ||||
|   187[Wall] | ||||
|   188[Wall] | ||||
|   189[Wall] | ||||
| @ -332,8 +332,8 @@ flowchart LR | ||||
|   191["SweepEdge Adjacent"] | ||||
|   192["SweepEdge Adjacent"] | ||||
|   193["SweepEdge Adjacent"] | ||||
|   194["Plane<br>[2214, 2233, 3]"] | ||||
|   202["Sweep Revolve<br>[2580, 2599, 3]"] | ||||
|   194["Plane<br>[2214, 2233, 4]"] | ||||
|   202["Sweep Revolve<br>[2580, 2599, 4]"] | ||||
|   203[Wall] | ||||
|   204[Wall] | ||||
|   205[Wall] | ||||
| @ -342,8 +342,8 @@ flowchart LR | ||||
|   208["SweepEdge Adjacent"] | ||||
|   209["SweepEdge Adjacent"] | ||||
|   210["SweepEdge Adjacent"] | ||||
|   211["Plane<br>[3054, 3077, 3]"] | ||||
|   219["Sweep Extrusion<br>[3999, 4045, 3]"] | ||||
|   211["Plane<br>[3054, 3077, 4]"] | ||||
|   219["Sweep Extrusion<br>[3999, 4045, 4]"] | ||||
|   220[Wall] | ||||
|   221[Wall] | ||||
|   222[Wall] | ||||
| @ -358,8 +358,8 @@ flowchart LR | ||||
|   231["SweepEdge Adjacent"] | ||||
|   232["SweepEdge Opposite"] | ||||
|   233["SweepEdge Adjacent"] | ||||
|   234["Plane<br>[3054, 3077, 3]"] | ||||
|   242["Sweep Extrusion<br>[3999, 4045, 3]"] | ||||
|   234["Plane<br>[3054, 3077, 4]"] | ||||
|   242["Sweep Extrusion<br>[3999, 4045, 4]"] | ||||
|   243[Wall] | ||||
|   244[Wall] | ||||
|   245[Wall] | ||||
| @ -374,8 +374,8 @@ flowchart LR | ||||
|   254["SweepEdge Adjacent"] | ||||
|   255["SweepEdge Opposite"] | ||||
|   256["SweepEdge Adjacent"] | ||||
|   257["Plane<br>[4455, 4474, 3]"] | ||||
|   284["Sweep Revolve<br>[5767, 5786, 3]"] | ||||
|   257["Plane<br>[4455, 4474, 4]"] | ||||
|   284["Sweep Revolve<br>[5767, 5786, 4]"] | ||||
|   285[Wall] | ||||
|   286[Wall] | ||||
|   287[Wall] | ||||
| @ -424,8 +424,8 @@ flowchart LR | ||||
|   330["SweepEdge Adjacent"] | ||||
|   331["SweepEdge Adjacent"] | ||||
|   332["SweepEdge Adjacent"] | ||||
|   333["Plane<br>[708, 734, 6]"] | ||||
|   345["Sweep Revolve<br>[1184, 1203, 6]"] | ||||
|   333["Plane<br>[708, 734, 7]"] | ||||
|   345["Sweep Revolve<br>[1184, 1203, 7]"] | ||||
|   346[Wall] | ||||
|   347[Wall] | ||||
|   348[Wall] | ||||
| @ -444,8 +444,8 @@ flowchart LR | ||||
|   361["SweepEdge Adjacent"] | ||||
|   362["SweepEdge Adjacent"] | ||||
|   363["SweepEdge Adjacent"] | ||||
|   364["Plane<br>[486, 505, 5]"] | ||||
|   384["Sweep Revolve<br>[2247, 2299, 5]"] | ||||
|   364["Plane<br>[486, 505, 6]"] | ||||
|   384["Sweep Revolve<br>[2247, 2299, 6]"] | ||||
|   385[Wall] | ||||
|   386[Wall] | ||||
|   387[Wall] | ||||
| @ -499,8 +499,8 @@ flowchart LR | ||||
|   435["SweepEdge Adjacent"] | ||||
|   436["SweepEdge Opposite"] | ||||
|   437["SweepEdge Adjacent"] | ||||
|   438["Plane<br>[462, 481, 7]"] | ||||
|   455["Sweep Revolve<br>[1462, 1493, 7]"] | ||||
|   438["Plane<br>[462, 481, 8]"] | ||||
|   455["Sweep Revolve<br>[1462, 1493, 8]"] | ||||
|   456[Wall] | ||||
|   457[Wall] | ||||
|   458[Wall] | ||||
| @ -529,17 +529,17 @@ flowchart LR | ||||
|   481["SweepEdge Adjacent"] | ||||
|   482["SweepEdge Adjacent"] | ||||
|   483["SweepEdge Adjacent"] | ||||
|   484["StartSketchOnFace<br>[795, 822, 4]"] | ||||
|   485["StartSketchOnFace<br>[993, 1024, 4]"] | ||||
|   486["StartSketchOnFace<br>[1451, 1480, 4]"] | ||||
|   487["StartSketchOnFace<br>[1590, 1624, 4]"] | ||||
|   488["StartSketchOnFace<br>[1796, 1829, 4]"] | ||||
|   489["StartSketchOnFace<br>[2116, 2145, 4]"] | ||||
|   490["StartSketchOnFace<br>[2465, 2494, 4]"] | ||||
|   491["StartSketchOnFace<br>[2947, 2980, 4]"] | ||||
|   492["StartSketchOnFace<br>[649, 678, 3]"] | ||||
|   493["StartSketchOnFace<br>[953, 987, 3]"] | ||||
|   494["StartSketchOnFace<br>[1310, 1339, 3]"] | ||||
|   484["StartSketchOnFace<br>[795, 822, 5]"] | ||||
|   485["StartSketchOnFace<br>[993, 1024, 5]"] | ||||
|   486["StartSketchOnFace<br>[1451, 1480, 5]"] | ||||
|   487["StartSketchOnFace<br>[1590, 1624, 5]"] | ||||
|   488["StartSketchOnFace<br>[1796, 1829, 5]"] | ||||
|   489["StartSketchOnFace<br>[2116, 2145, 5]"] | ||||
|   490["StartSketchOnFace<br>[2465, 2494, 5]"] | ||||
|   491["StartSketchOnFace<br>[2947, 2980, 5]"] | ||||
|   492["StartSketchOnFace<br>[649, 678, 4]"] | ||||
|   493["StartSketchOnFace<br>[953, 987, 4]"] | ||||
|   494["StartSketchOnFace<br>[1310, 1339, 4]"] | ||||
|   1 --- 2 | ||||
|   2 --- 3 | ||||
|   2 ---- 5 | ||||
|  | ||||
| @ -18,6 +18,66 @@ description: Operations executed car-wheel-assembly.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 6.0, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -74,6 +134,66 @@ description: Operations executed car-wheel-assembly.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 3.0, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -130,6 +250,66 @@ description: Operations executed car-wheel-assembly.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": -2.25, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.315, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Inches" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -215,6 +395,78 @@ description: Operations executed car-wheel-assembly.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": { | ||||
|       "value": { | ||||
|         "type": "Face", | ||||
|         "artifact_id": "[uuid]" | ||||
|       }, | ||||
|       "sourceRange": [] | ||||
|     }, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.25, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Inches" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -265,6 +517,66 @@ description: Operations executed car-wheel-assembly.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 6.0, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -321,6 +633,66 @@ description: Operations executed car-wheel-assembly.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": -2.25, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.315, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Inches" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -406,6 +778,66 @@ description: Operations executed car-wheel-assembly.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 5.5, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.25, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Inches" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -700,6 +1132,126 @@ description: Operations executed car-wheel-assembly.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 3.0, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 1.5, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
| @ -776,6 +1328,126 @@ description: Operations executed car-wheel-assembly.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 3.0, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 1.5, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
| @ -852,6 +1524,60 @@ description: Operations executed car-wheel-assembly.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 2.25, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.6, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -931,6 +1657,60 @@ description: Operations executed car-wheel-assembly.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 2.25, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.31496062992125984, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -1068,7 +1848,7 @@ description: Operations executed car-wheel-assembly.kcl | ||||
|     "functionSourceRange": [ | ||||
|       2752, | ||||
|       4324, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1455,7 +2235,7 @@ description: Operations executed car-wheel-assembly.kcl | ||||
|     "functionSourceRange": [ | ||||
|       2752, | ||||
|       4324, | ||||
|       3 | ||||
|       4 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
| @ -1880,7 +2660,7 @@ description: Operations executed car-wheel-assembly.kcl | ||||
|     "functionSourceRange": [ | ||||
|       666, | ||||
|       1293, | ||||
|       6 | ||||
|       7 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": {}, | ||||
|  | ||||
| @ -5,7 +5,7 @@ description: Variables in memory after executing car-wheel-assembly.kcl | ||||
| { | ||||
|   "brakeCaliper": { | ||||
|     "type": "Module", | ||||
|     "value": 5 | ||||
|     "value": 6 | ||||
|   }, | ||||
|   "c1": { | ||||
|     "type": "TagIdentifier", | ||||
| @ -14,15 +14,15 @@ description: Variables in memory after executing car-wheel-assembly.kcl | ||||
|   }, | ||||
|   "carRotor": { | ||||
|     "type": "Module", | ||||
|     "value": 4 | ||||
|     "value": 5 | ||||
|   }, | ||||
|   "carTire": { | ||||
|     "type": "Module", | ||||
|     "value": 7 | ||||
|     "value": 8 | ||||
|   }, | ||||
|   "carWheel": { | ||||
|     "type": "Module", | ||||
|     "value": 3 | ||||
|     "value": 4 | ||||
|   }, | ||||
|   "lugCount": { | ||||
|     "type": "Number", | ||||
| @ -39,6 +39,6 @@ description: Variables in memory after executing car-wheel-assembly.kcl | ||||
|   }, | ||||
|   "lugNut": { | ||||
|     "type": "Module", | ||||
|     "value": 6 | ||||
|     "value": 7 | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -132,6 +132,66 @@ description: Operations executed cycloidal-gear.kcl | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.1485, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
| @ -272,6 +332,66 @@ description: Operations executed cycloidal-gear.kcl | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.1485, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
| @ -418,6 +538,66 @@ description: Operations executed cycloidal-gear.kcl | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.1485, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -18,6 +18,60 @@ description: Operations executed flange.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 1.75, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.3125, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "data": { | ||||
| @ -33,6 +87,66 @@ description: Operations executed flange.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 2.3125, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
| @ -138,6 +252,66 @@ description: Operations executed flange.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 1.1565, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -194,6 +368,66 @@ description: Operations executed flange.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 1.25, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -250,6 +484,66 @@ description: Operations executed flange.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.625, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
|  | ||||
| @ -488,6 +488,54 @@ description: Operations executed focusrite-scarlett-mounting-bracket.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 82.0, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 27.333333333333332, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 2.5, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
| @ -874,6 +922,54 @@ description: Operations executed focusrite-scarlett-mounting-bracket.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": -82.0, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 27.333333333333332, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 2.5, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
|  | ||||
| @ -480,6 +480,66 @@ description: Operations executed french-press.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 2.055, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -706,6 +766,132 @@ description: Operations executed french-press.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 1.965, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.15, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Inches" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
| @ -788,6 +974,72 @@ description: Operations executed french-press.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 1.4, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.3, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Inches" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -891,6 +1143,72 @@ description: Operations executed french-press.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.6, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.2, | ||||
|           "ty": { | ||||
|             "type": "Default", | ||||
|             "len": { | ||||
|               "type": "Inches" | ||||
|             }, | ||||
|             "angle": { | ||||
|               "type": "Degrees" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
| @ -961,6 +1279,66 @@ description: Operations executed french-press.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 2.205, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
|  | ||||
| @ -4623,6 +4623,66 @@ description: Operations executed gear.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 4.933386259126019, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
|  | ||||
| @ -1065,6 +1065,54 @@ description: Operations executed gridfinity-baseplate-magnets.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 8.0, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 8.0, | ||||
|               "ty": { | ||||
|                 "type": "Unknown" | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 3.25, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "magnetBase", | ||||
|  | ||||
| @ -657,6 +657,66 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": -8.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 8.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 3.25, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
|  | ||||
| @ -657,6 +657,66 @@ description: Operations executed gridfinity-bins.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": -8.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 8.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Mm" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 3.25, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "length": { | ||||
|  | ||||
| @ -30,6 +30,66 @@ description: Operations executed hex-nut.kcl | ||||
|     "type": "StdLibCall", | ||||
|     "unlabeledArg": null | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionCall", | ||||
|     "name": "circle", | ||||
|     "functionSourceRange": [ | ||||
|       0, | ||||
|       0, | ||||
|       0 | ||||
|     ], | ||||
|     "unlabeledArg": null, | ||||
|     "labeledArgs": { | ||||
|       "center": { | ||||
|         "value": { | ||||
|           "type": "Array", | ||||
|           "value": [ | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             { | ||||
|               "type": "Number", | ||||
|               "value": 0.0, | ||||
|               "ty": { | ||||
|                 "type": "Default", | ||||
|                 "len": { | ||||
|                   "type": "Inches" | ||||
|                 }, | ||||
|                 "angle": { | ||||
|                   "type": "Degrees" | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       }, | ||||
|       "radius": { | ||||
|         "value": { | ||||
|           "type": "Number", | ||||
|           "value": 0.15625, | ||||
|           "ty": { | ||||
|             "type": "Unknown" | ||||
|           } | ||||
|         }, | ||||
|         "sourceRange": [] | ||||
|       } | ||||
|     }, | ||||
|     "sourceRange": [] | ||||
|   }, | ||||
|   { | ||||
|     "type": "UserDefinedFunctionReturn" | ||||
|   }, | ||||
|   { | ||||
|     "labeledArgs": { | ||||
|       "holeSketch": { | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	