diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 9ba5a9c79..ea9fadcfc 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -229,10 +229,6 @@ jobs: timeout_minutes: 30 max_attempts: 3 env: - CI: true - NODE_ENV: development - VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }} - VITE_KC_SKIP_AUTH: true token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }} snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }} @@ -377,11 +373,7 @@ jobs: timeout_minutes: 45 max_attempts: 15 env: - CI: true FAIL_ON_CONSOLE_ERRORS: true - NODE_ENV: development - VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }} - VITE_KC_SKIP_AUTH: true token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }} - uses: actions/upload-artifact@v4 diff --git a/docs/kcl/consts.md b/docs/kcl/consts.md index c204f1d77..385c7bf46 100644 --- a/docs/kcl/consts.md +++ b/docs/kcl/consts.md @@ -9,13 +9,9 @@ layout: manual ### `std` -- [`HALF_TURN`](/docs/kcl/consts/std-HALF_TURN) -- [`QUARTER_TURN`](/docs/kcl/consts/std-QUARTER_TURN) -- [`THREE_QUARTER_TURN`](/docs/kcl/consts/std-THREE_QUARTER_TURN) - [`XY`](/docs/kcl/consts/std-XY) - [`XZ`](/docs/kcl/consts/std-XZ) - [`YZ`](/docs/kcl/consts/std-YZ) -- [`ZERO`](/docs/kcl/consts/std-ZERO) ### `std::math` @@ -23,3 +19,10 @@ layout: manual - [`PI`](/docs/kcl/consts/std-math-PI) - [`TAU`](/docs/kcl/consts/std-math-TAU) +### `std::turns` + +- [`HALF_TURN`](/docs/kcl/consts/std-turns-HALF_TURN) +- [`QUARTER_TURN`](/docs/kcl/consts/std-turns-QUARTER_TURN) +- [`THREE_QUARTER_TURN`](/docs/kcl/consts/std-turns-THREE_QUARTER_TURN) +- [`ZERO`](/docs/kcl/consts/std-turns-ZERO) + diff --git a/docs/kcl/consts/std-HALF_TURN.md b/docs/kcl/consts/std-HALF_TURN.md deleted file mode 100644 index 65a69a56e..000000000 --- a/docs/kcl/consts/std-HALF_TURN.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: "std::HALF_TURN" -excerpt: "" -layout: manual ---- - - - - - -```js -std::HALF_TURN: number(deg) = 180deg -``` - - diff --git a/docs/kcl/consts/std-QUARTER_TURN.md b/docs/kcl/consts/std-QUARTER_TURN.md deleted file mode 100644 index 7fb657840..000000000 --- a/docs/kcl/consts/std-QUARTER_TURN.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: "std::QUARTER_TURN" -excerpt: "" -layout: manual ---- - - - - - -```js -std::QUARTER_TURN: number(deg) = 90deg -``` - - diff --git a/docs/kcl/consts/std-THREE_QUARTER_TURN.md b/docs/kcl/consts/std-THREE_QUARTER_TURN.md deleted file mode 100644 index 4d66e4d2f..000000000 --- a/docs/kcl/consts/std-THREE_QUARTER_TURN.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: "std::THREE_QUARTER_TURN" -excerpt: "" -layout: manual ---- - - - - - -```js -std::THREE_QUARTER_TURN: number(deg) = 270deg -``` - - diff --git a/docs/kcl/consts/std-ZERO.md b/docs/kcl/consts/std-ZERO.md deleted file mode 100644 index 0002979af..000000000 --- a/docs/kcl/consts/std-ZERO.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: "std::ZERO" -excerpt: "" -layout: manual ---- - - - - - -```js -std::ZERO: number = 0 -``` - - diff --git a/docs/kcl/consts/std-turns-HALF_TURN.md b/docs/kcl/consts/std-turns-HALF_TURN.md new file mode 100644 index 000000000..b019c2a5d --- /dev/null +++ b/docs/kcl/consts/std-turns-HALF_TURN.md @@ -0,0 +1,15 @@ +--- +title: "std::turns::HALF_TURN" +excerpt: "" +layout: manual +--- + + + + + +```js +std::turns::HALF_TURN: number(deg) = 180deg +``` + + diff --git a/docs/kcl/consts/std-turns-QUARTER_TURN.md b/docs/kcl/consts/std-turns-QUARTER_TURN.md new file mode 100644 index 000000000..baf369a91 --- /dev/null +++ b/docs/kcl/consts/std-turns-QUARTER_TURN.md @@ -0,0 +1,15 @@ +--- +title: "std::turns::QUARTER_TURN" +excerpt: "" +layout: manual +--- + + + + + +```js +std::turns::QUARTER_TURN: number(deg) = 90deg +``` + + diff --git a/docs/kcl/consts/std-turns-THREE_QUARTER_TURN.md b/docs/kcl/consts/std-turns-THREE_QUARTER_TURN.md new file mode 100644 index 000000000..11ce8e342 --- /dev/null +++ b/docs/kcl/consts/std-turns-THREE_QUARTER_TURN.md @@ -0,0 +1,15 @@ +--- +title: "std::turns::THREE_QUARTER_TURN" +excerpt: "" +layout: manual +--- + + + + + +```js +std::turns::THREE_QUARTER_TURN: number(deg) = 270deg +``` + + diff --git a/docs/kcl/consts/std-turns-ZERO.md b/docs/kcl/consts/std-turns-ZERO.md new file mode 100644 index 000000000..b32ff42de --- /dev/null +++ b/docs/kcl/consts/std-turns-ZERO.md @@ -0,0 +1,15 @@ +--- +title: "std::turns::ZERO" +excerpt: "" +layout: manual +--- + + + + + +```js +std::turns::ZERO: number = 0 +``` + + diff --git a/docs/kcl/index.md b/docs/kcl/index.md index 5b73d3ec1..97bf13f51 100644 --- a/docs/kcl/index.md +++ b/docs/kcl/index.md @@ -23,19 +23,15 @@ layout: manual * [`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) - * [`THREE_QUARTER_TURN`](kcl/consts/std-THREE_QUARTER_TURN) * [`XY`](kcl/consts/std-XY) * [`XZ`](kcl/consts/std-XZ) * [`YZ`](kcl/consts/std-YZ) - * [`ZERO`](kcl/consts/std-ZERO) * [`abs`](kcl/abs) * [`acos`](kcl/acos) * [`angleToMatchLengthX`](kcl/angleToMatchLengthX) @@ -146,3 +142,8 @@ layout: manual * [`tan`](kcl/std-math-tan) * **std::sketch** * [`circle`](kcl/std-sketch-circle) +* **std::turns** + * [`turns::HALF_TURN`](kcl/consts/std-turns-HALF_TURN) + * [`turns::QUARTER_TURN`](kcl/consts/std-turns-QUARTER_TURN) + * [`turns::THREE_QUARTER_TURN`](kcl/consts/std-turns-THREE_QUARTER_TURN) + * [`turns::ZERO`](kcl/consts/std-turns-ZERO) diff --git a/docs/kcl/rotate.md b/docs/kcl/rotate.md index bd74dea02..0f1276a65 100644 --- a/docs/kcl/rotate.md +++ b/docs/kcl/rotate.md @@ -6,6 +6,10 @@ layout: manual Rotate a solid or a sketch. +This is really useful for assembling parts together. You can create a part and then rotate it to the correct orientation. + +For sketches, you can use this to rotate a sketch and then loft it with another sketch. + ### Using Roll, Pitch, and Yaw When rotating a part in 3D space, "roll," "pitch," and "yaw" refer to the three rotational axes used to describe its orientation: roll is rotation around the longitudinal axis (front-to-back), pitch is rotation around the lateral axis (wing-to-wing), and yaw is rotation around the vertical axis (up-down); essentially, it's like tilting the part on its side (roll), tipping the nose up or down (pitch), and turning it left or right (yaw). @@ -166,7 +170,7 @@ fn square() { profile001 = square() profile002 = square() - |> translate(translate = [0, 0, 20]) + |> translate(x = 0, y = 0, z = 20) |> rotate(axis = [0, 0, 1.0], angle = 45) loft([profile001, profile002]) diff --git a/docs/kcl/scale.md b/docs/kcl/scale.md index ea13d8d8b..c3d477fac 100644 --- a/docs/kcl/scale.md +++ b/docs/kcl/scale.md @@ -6,6 +6,10 @@ layout: manual Scale a solid or a sketch. +This is really useful for resizing parts. You can create a part and then scale it to the correct size. + +For sketches, you can use this to scale a sketch and then loft it with another sketch. + By default the transform is applied in local sketch axis, therefore the origin will not move. If you want to apply the transform in global space, set `global` to `true`. The origin of the model will move. If the model is not centered on origin and you scale globally it will look like the model moves and gets bigger at the same time. Say you have a square `(1,1) - (1,2) - (2,2) - (2,1)` and you scale by 2 globally it will become `(2,2) - (2,4)`...etc so the origin has moved from `(1.5, 1.5)` to `(2,2)`. @@ -13,7 +17,9 @@ If you want to apply the transform in global space, set `global` to `true`. The ```js scale( objects: SolidOrSketchOrImportedGeometry, - scale: [number], + x: number, + y: number, + z: number, global?: bool, ): SolidOrSketchOrImportedGeometry ``` @@ -24,7 +30,9 @@ scale( | Name | Type | Description | Required | |----------|------|-------------|----------| | `objects` | [`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) | The solid, sketch, or set of solids or sketches to scale. | Yes | -| `scale` | [`[number]`](/docs/kcl/types/number) | The scale factor for the x, y, and z axes. | Yes | +| `x` | [`number`](/docs/kcl/types/number) | The scale factor for the x axis. | Yes | +| `y` | [`number`](/docs/kcl/types/number) | The scale factor for the y axis. | Yes | +| `z` | [`number`](/docs/kcl/types/number) | The scale factor for the z axis. | Yes | | `global` | [`bool`](/docs/kcl/types/bool) | If true, the transform is applied in global space. The origin of the model will move. By default, the transform is applied in local sketch axis, therefore the origin will not move. | No | ### Returns @@ -54,7 +62,7 @@ sweepSketch = startSketchOn(XY) |> circle(center = [0, 0], radius = 2) |> hole(pipeHole, %) |> sweep(path = sweepPath) - |> scale(scale = [1.0, 1.0, 2.5]) + |> scale(x = 1.0, y = 1.0, z = 2.5) ``` ![Rendered example of scale 0](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAADPfd1WAADhgUlEQVR4Ae3AA6AkWZbG8f937o3IzKdyS2Oubdu2bdu2bdu2bWmMnpZKr54yMyLu+Xa3anqmhztr1a8+6EEP4qqrrrrqqquuuuqqq6666qqrrrrqqquu+j+JylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV/0nu+aaax585syZBwNcc801Dz5z5syDeKZrrrnmwTzTNddc82Cey5kzZx589uzZW8+cOfNg/hXOnj17Kw9w33333coz3XfffbeePXv2GQD33XffrQBnz5699b777ruVq6666qqrrrrqqquu+r8FPehBD+Kqq6666qqrrrrqP8qLvdiLvfbrvM7rvNc111zz4DNnzjz4mmuueTD/gvvuu4/73Xfffdzv7Nmz/FucOXOGB7rmmmu45ppreGHuu+++W3mmr//6r3+ff/iHf/htrrrqqquuuuqqq6666n8/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V1111VX/SWzzb2Eb2wDYxja2sQ2AbQBsY5vnRxL3k8QLIonnxzZXXXXVVVddddVVV131fwDBVVddddVVV1111X+CiLgVIDOxzQPZxjYAtvnXsA2Abf4zSQLgmmuueTBXXXXVVVddddVVV131vxeVq6666qqrrrrqqv8kmcn9bGObF8Q2tnkg29jGNraxjW1s80C2eUEk8aKQxFVXXXXVVVddddVVV/0fROWqq6666qqrrrrqP0nXddjmgWzzwtgGwDb3sw2Abe5nG9s8P5IAkMS/lSSuuuqqq6666qqrrrrq/wCCq6666qqrrrrqqv8kR0dHt9rGNs+PbZ4f2wDYxjYAtgGwjW3uZxsA2wBIAkASDySJB5LEc5MEgCQAzp49y1VXXXXVVVddddVVV/0vR+Wqq6666qqrrrrqP0mtFdsA2OYFsc0LYxvb2MY2trGNbV4UkgCQhCSemyTuJwkASUQEV1111VVXXXXVVVdd9b8cwVVXXXXVVVddddV/ktVqdSuAbQBsA2Ab27wobHM/2zw/tnl+JCGJf48zZ848mKuuuuqqq6666qqrrvrfi+Cqq6666qqrrrrqP5FtAGzzL7HN/WxjGwDb2AbANraxjW1sc9VVV1111VVXXXXVVVe9QFSuuuqqq6666qqr/pNEBLaxzf1s80C2AbANgG1scz/bANjGNraxjW1eEElI4gWRBIAkrrrqqquuuuqqq6666v84KlddddVVV1111VX/ScZxvNU2/162AbDNA9nmP4MkJHHhwgWuuuqqq6666qqrrrrqfzkqV1111VVXXXXVVf9JbGMb29jGNg9kmxfENrYBsI1tbGMb29gGwDYviCQkIQlJ/GtFBFddddVVV1111VVXXfW/HMFVV1111VVXXXXVf5LMvNU2tnkg29jmfrZ5QWwDYBsA29jmudnmgSTxH+Gaa655MFddddVVV1111VVXXfW/F8FVV1111VVXXXXVfxLb2OaBbPOC2AbANgC2AbANgG3uZxvb2ObfQxIAkgCQBIAkrrrqqquuuuqqq6666v8AKlddddVVV1111VX/STIT29jGNrb5l9jmgWwDYBvb2MY2L4wknh9JvDCSeCBJXHXVVVddddVVV1111f9yVK666qqrrrrqqqv+k9h+hm1eGNsA2OaBbHM/29gGwDa2sY1tAGzz/EhCEg8kiX+JJAAuXLjAVVddddVVV1111VVX/S9HcNVVV1111VVXXfWfxDa2sY1t7mebF4VtbHM/29gGwDa2sc2/RBLPTRL/kojgqquuuuqqq6666qqr/pejctVVV1111VVXXfWfJCJuzUweyDb3s83zY5sHso1tbANgm+dmmweSxANJ4gWRxHOTBMCZM2cexFVXXXXVVVddddVVV/3vReWqq6666qqrrrrqP0lmYhvbANjmfra5n22em20AbPNAtrGNbWxjG9tcddVVV1111VVXXXXVVc8Xlauuuuqqq6666qr/RJmJbWzzL7GNbe5nGwDb2MY2tgGwzXOzzQNJ4vmRxItCElddddVVV1111VVXXfW/HJWrrrrqqquuuuqq/yQRcSv/Atu8KGxjG9vYBsA2trHNCyKJfw1JAEhid3eXq6666qqrrrrqqquu+l+OylVXXXXVVVddddV/otYatrGNbWxjm+dmm/vZxjYAtrENgG0AbGObB7LNCyIJAEm8KCRx1VVXXXXVVVddddVV/0dQueqqq6666qqrrvpPlJn8W9nmfrYBsA2AbWxjm38rSbwwkrjmmmsezFVXXXXVVVddddVVV/3vReWqq6666qqrrrrqP0lE3CqJzMQ2D2Qb2wDY5n62eSDb2MY2trGNbR7INs9NEg8kiX+JJO4niauuuuqqq6666qqrrvo/gOCqq6666qqrrrrqP1Fmcj/b2OYFsc0LYxsA29jGNrYBsM1zk8Rzk8TzI4nnJomrrrrqqquuuuqqq676X47gqquuuuqqq6666j9R13XY5oFs88LYxja2sY1tbANgG9vYxjYAtgGwDYAk7ieJF0YSL8ju7i5XXXXVVVddddVVV131vxzBVVddddVVV1111X+io6OjW21jm+fHNgC2+ZfYxjYPZJv/aJIAkMRVV1111VVXXXXVVVf9L0flqquuuuqqq6666j9RrRXbANjmfrZ5UdnGNraxjW1sY5v72eYFkcS/liQArrnmmgdz1VVXXXXVVVddddVV/3sRXHXVVVddddVVV/0nWq1WtwLYBsA297PNc7PN/Wxjm+dmG9sA2MY2/1EkcT9JXHXVVVddddVVV1111f9yVK666qqrrrrqqqv+k9kGwDYAtnkg2wDYBsA2trmfbWxjG9vYBsA2D2SbF0YS95PEv+TSpUtcddVVV1111VVXXXXV/3JUrrrqqquuuuqqq/4TRQS2sc2/hW0AbGMb2wDYxja2sc3zIwlJAEjifpJ4IElcddVVV1111VVXXXXV/1FUrrrqqquuuuqqq/4TjeN4q21eENu8ILYBsM39bGMb2wDY5oFsc9VVV1111VVXXXXVVVc9C8FVV1111VVXXXXVf6LMBMA2trENgG0eyDYPZJsHso1tAGwDYBsA2zyQbf69JCGJM2fOPJirrrrqqquuuuqqq67634vKVVddddVVV1111X8i27dmJra5n20AbPPcbPNAtrENgG1sYxvb2MY2ALaxzf0kcT9J/GtIAkASV1111VVXXXXVVVdd9b8cwVVXXXXVVVddddV/ItvY5oWxzQPZBsA297MNgG0AbHM/27yoJPGCSOKqq6666qqrrrrqqqv+j6Fy1VVXXXXVVVdd9Z8oM7GNbWxjmxfENs/NNraxjW0AbGMb29gGwDb/0S5dusRVV1111VVXXXXVVVf9L0dw1VVXXXXVVVdd9Z/I9jNs869lm+dmG9vYBsA2ALYBsI1tXlSSuJ8kHkgSkrjqqquuuuqqq6666qr/5ahcddVVV1111VVX/SeyjW1sYxsA29gGwDYAtnlutgGwjW0AbGMb2wDYBsA2z48k/jUk8UDXXHPNg7nqqquuuuqqq6666qr/vQiuuuqqq6666qqr/hNFxK2Zyf1scz/bPDfb2OZ+trmfbWwDYBvb2MY2/xJJSOJfQxJXXXXVVVddddVVV131vxyVq6666qqrrrrqqv9EmYltbGObfwvb2MY2ALaxjW0eyDYPJImrrrrqqquuuuqqq676f47KVVddddVVV1111X+yzMQ2L4htAGxzP9s8P7axDYBtbGObfytJPDdJAOzv73PVVVddddVVV1111VX/yxFcddVVV1111VVX/SeKiFt5ANvYxjb/EtvYBsA2trGNbWwDYBvb3M82z00S/1qSsM1VV1111VVXXXXVVVf9L0dw1VVXXXXVVVdd9Z+stYZtbPPcbPPcbPNAtrmfbQBsY5v72cY2/5EkAXDNNdc8mKuuuuqqq6666qqrrvrfieCqq6666qqrrrrqP1lmYpvnZpv72QbANs+PbWwDYBvb2MY2tnkg27wwkpDEv0QSV1111VVXXXXVVVdd9b8clauuuuqqq6666qr/RBFxK89kG9u8KGxjG9vYBsA2trHN/WwDYBsA21x11VVXXXXVVVddddVVz0Jw1VVXXXXVVVdd9Z/MNra5n21scz/bANjmBbENgG1sYxvbANgGwDb/FpIAkMRzO3v2LFddddVVV1111VVXXfW/GJWrrrrqqquuuuqq/2Rd12Eb2/xb2AbANvezjW1sYxvbPJBtnh9JvCgkARARXHXVVVddddVVV1111f9iBFddddVVV1111VX/yY6Ojm61DYBt7mcb2zw32wDYxjYAtrGNbWxjG9vY5n62eW6SAJDEi0IS95MEwJkzZx7MVVddddVVV1111VVX/e9E5aqrrrrqqquuuuo/Wa0V29gGwDbPzTYAtgGwzf1scz/b2OaBbGMbANv8e0niqquuuuqqq6666qqr/o8guOqqq6666qqrrvpPtlqtbuW52OZFYRsA29gGwDa2sY1tAGxjGwDbPD+S+Nc6d+4cV1111VVXXXXVVVdd9b8YwVVXXXXVVVddddV/AdvYxjbPzTYAtvmX2AbANraxjW3+M0hCElddddVVV1111VVXXfW/GJWrrrrqqquuuuqq/2SSyEyem21eGNsA2MY2trGNbWxjG9vYxja2sc1zk8S/RBIPJAmAUgpXXXXVVVddddVVV131vxjBVVddddVVV1111X+yaZpuBbCNbWxzP9s8N9vYBsA297MNgG1s81/lmmuueTBXXXXVVVddddVVV131vxOVq6666qqrrrrqqv9kmYltHsg2D2QbANs8N9vYBsA2tgGwjW1sYxvb2MY2LwpJXHXVVVddddVVV1111f9xVK666qqrrrrqqqv+k9m+1Ta2+dewzQPZxjYAtrGNbWzzn0ESkrjqqquuuuqqq6666qr/xahcddVVV1111VVX/SezjW0AbGOb58c2z802ALa5n21sY5v72cY2/9EuXLjAVVddddVVV1111VVX/S9G5aqrrrrqqquuuuo/WWZiG9s8kG0AbPNAtrHN/WwDYBvb2MY2ALaxjW0AbANgm38rSdwvIrjqqquuuuqqq6666qr/xahcddVVV1111VVX/Sez/YzMxDa2AbANgG1eFLYBsI1tAGxjG9sA2AbANv+Rzpw58yCuuuqqq6666qqrrrrqfycqV1111VVXXXXVVf/JbPNAtnlutgGwzf1sYxvbANjmfraxjW0AbANgm3+JJP4lkpDEVVddddVVV1111VVX/S9H5aqrrrrqqquuuuo/WUTcmpnY5t/KNraxjW1sYxsA2wDY5gWRxPMjiQeSxAPt7u5y1VVXXXXVVVddddVV/4tRueqqq6666qqrrvpPlpnYBsA2ALaxDYBtAGxzP9s8P7axjW1sYxvb2OZ+tnlBJPGCSOK5SeKqq6666qqrrrrqqqv+F6Ny1VVXXXXVVVdd9V8gM7ENgG3uZ5vnZpv72cY2trHNc7MNgG0AbHM/27wgkviXSOKqq6666qqrrrrqqqv+l6Ny1VVXXXXVVVdd9Z8sIm61jW1s86KyzXOzjW1sYxvb2Oa52ea5SeJfSxLXXHPNg7nqqquuuuqqq6666qr/nahcddVVV1111VVX/RfITF4Y2wDY5vmxjW1sYxvb2AbANrYBsM1VV1111VVXXXXVVVdd9SwEV1111VVXXXXVVf8FMhPb2MY2trHNC2Kb+9nmgWxjG9vYxja2uZ9t/jUk8dwkASCJq6666qqrrrrqqquu+l+M4Kqrrrrqqquuuuo/WUTcCmCb58c2ALYBsA2AbWwDYBvb2OaBbHM/29jmP4okdnd3ueqqq6666qqrrrrqqv/FqFx11VVXXXXVVVf9F7CNbWzzQLb5l9jmfraxjW1sYxvb2OZ+trHNv5UkHuiaa655MFddddVVV1111VVXXfW/E8FVV1111VVXXXXVf4FSCvezjW3+tWwDYBvb2AbANrYBsM1/JElcddVVV1111VVXXXXV/2IEV1111VVXXXXVVf8F1uv1rbaxzf1scz/bANjmgWwDYBsA2wDYxja2uZ9trrrqqquuuuqqq6666qrnQHDVVVddddVVV131X6CUgm0AbPMvsY1tAGwDYBsA29zPNraxzf1s8x9lb2+Pq6666qqrrrrqqquu+l+M4Kqrrrrqqquuuuq/wGq1utU2z802tgGwDYBtnpttAGxjG9vYxja2sY1tbANgG9u8qCTx3CRx1VVXXXXVVVddddVV/8tRueqqq6666qqrrvovZBsA27wobHM/29gGwDa2AbDNVVddddVVV1111VVXXfV8Ubnqqquuuuqqq676LxARZCa2sQ2AbV4UtrHN/WxjG9vYBsA2ALaxzb+XJAAkcebMmQdz1VVXXXXVVVddddVV/ztRueqqq6666qqrrvovMI7jrbwQtgGwDYBtbPNAtrGNbe5nG9vYBsA2D2Sbq6666qqrrrrqqquu+n+MylVXXXXVVVddddV/gczENrYBsA2AbWzzgtjm+bGNbWxjmweyjW3+LSTxQHt7e1x11VVXXXXVVVddddX/YlSuuuqqq6666qqr/gvYvjUzAbANgG0eyDYAtnkg29jGNraxjW1sA2Ab2wDY5j+KJK666qqrrrrqqquuuup/OYKrrrrqqquuuuqq/wK2AbDNv5dtbGMb2wDY5rnZ5qqrrrrqqquuuuqqq/6fo3LVVVddddVVV131XyAzsQ2AbWzz/NgGwDa2uZ9tbGOb+9nGNrYBsI1tbPPvIYn7SeKaa655MFddddVVV1111VVXXfW/E5Wrrrrqqquuuuqq/wK2n5GZ2OaBbANgm+fHNra5n21sYxsA29jGNg9km6uuuuqqq6666qqrrroKgquuuuqqq6666qr/AraxzQPZBsA2D2Sb58c2ALaxjW3uZxsA29jm30ISz00SV1111VVXXXXVVVdd9b8Ylauuuuqqq6666qr/ApJutY1tbGOb52abF8Q2ALa5n21sYxsA2/xHkYQk9vb2uOqqq6666qqrrrrqqv/FqFx11VVXXXXVVVf9F7CNbWzzorKNbWwDYBsA29jGNraxjW0AbGMb29jmhZHEVVddddVVV1111VVX/R9HcNVVV1111VVXXfVfJDMBsA2AbWwDYBsA2wDY5oFsA2Ab29gGwDa2sc1/pmuuuebBXHXVVVddddVVV1111f8+VK666qqrrrrqqqv+C0TErbaxDYBt7mebF4VtHsg2D2Qb2zyQbf49JHHVVVddddVVV1111VX/i1G56qqrrrrqqquu+i+SmdjGNi+MbR7INvezjW1sYxvb2MY297ONbf6jnD17lquuuuqqq6666qqrrvpfiuCqq6666qqrrrrqv0hmYpsXxDYPZBvbANjGNvezDYBtbGMbANvczzb/XpKICK666qqrrrrqqquuuup/KYKrrrrqqquuuuqq/wIRcaskAGxjG9vY5vmxzfNjG9vYxja2sY1tbGMb2/xHkIRtAM6cOfNgrrrqqquuuuqqq6666n8fKlddddVVV1111VX/RTIT2zw329gGwDbPzTYPZBsA27wgtnlBJPGiksRVV1111VVXXXXVVVf9L0blqquuuuqqq6666r9IKQXb2OaFsc1zs41tbANgG9vYxja2sY1tbPNAtrnqqquuuuqqq6666qr/pwiuuuqqq6666qqr/ousVqtbbQNgG9u8MLaxzXOzjW0AbGMb29jmfraxzX+Ec+fOcdVVV1111VVXXXXVVf9LUbnqqquuuuqqq676L1Jr5bnZ5n62uZ9t7mcb29jGNvezjW0eyDa2uZ9t/i0kASCJiOCqq6666qqrrrrqqqv+lyK46qqrrrrqqquu+i+yWq1utY1tbHM/29gGwDb/EtvYxjYAtrGNbf4zRARXXXXVVVddddVVV131vxTBVVddddVVV1111X8h29jmRWWb+9nGNgC2AbCNbWxjG9vYxjb/VpJ4btdcc82Dueqqq6666qqrrrrqqv99qFx11VVXXXXVVVf9F8lMbHM/29jmudkGwDYAtrHN/WwDYBvb2OZ+trmfbf49JHHVVVddddVVV1111VX/y1G56qqrrrrqqquu+i+Smbfaxja2eW62+ZfYxja2sY1tAGxjGwDb/FtJ4oEkIYmrrrrqqquuuuqqq676X4rKVVddddVVV1111X8R29jmudnmudnmudnmgWwDYBvb2OZ+tgGwzb/XxYsXueqqq6666qqrrrrqqv+lqFx11VVXXXXVVVf9F7F9q21sYxvb3M82ALZ5INsA2AbANraxDYBtbPNAtvmPdubMmQdx1VVXXXXVVVddddVV//tQueqqq6666qqrrvovYhvbPJBtnpttAGwDYBsA29zPNraxjW1sY5v72cY297PNv5Ukrrrqqquuuuqqq6666n8pKlddddVVV1111VX/RTIT29jm38o2tgGwzf1scz/bPJBt/q0kcdVVV1111VVXXXXVVf+LUbnqqquuuuqqq676L2L7GbaxjW1sA2AbANvczzYPZJsHsg2AbWxjG9v8Z9jd3eWqq6666qqrrrrqqqv+l6Jy1VVXXXXVVVdd9V/ENrZ5INsA2AbANg9kG9sA2MY2trGNbWxjGwDbANjGNraxzb+VJK666qqrrrrqqquuuup/OSpXXXXVVVddddVV/0Uk3Wob29jmX2KbF8Y297PNfxZJXHXVVVddddVVV1111f9SVK666qqrrrrqqqv+i9gmM7mfbZ4f2zw329jGNraxDYBtbGMb2wDYxjb/HpIAkATANddc82Cuuuqqq6666qqrrrrqfx+Cq6666qqrrrrqqv9CtrGNbe5nGwDb3M8297PNA9kGwDa2sQ2AbR7INv8RJHHVVVddddVVV1111VX/S1G56qqrrrrqqquu+i8SEbdmJrYBsI1tAGzz/NjmgWwDYBvb2MY2tgGwjW1eGNtcddVVV1111VVXXXXV/xMEV1111VVXXXXVVf+FbPPC2OZ+trmfbWwDYJvnZhvb2AbANgC2sc2/x6VLl7jqqquuuuqqq6666qr/pQiuuuqqq6666qqr/gtlJraxzQtim3+JbWxjG9sA2AbANv/Rrrnmmgdz1VVXXXXVVVddddVV//tQueqqq6666qqrrvovEhG3SsI2ALaxjW0AbPPcbGOb+9nGNraxjW1sYxsA2wDYxjb/XpKQxFVXXXXVVVddddVVV/0vRXDVVVddddVVV131XygzAbDNA9nmgWzzQLaxzQtiG9sA2Ob5sc1VV1111VVXXXXVVVf9P0Plqquuuuqqq6666r9QKQXbvCC2uZ9tnpttbGMb29jGNgC2uZ9tAGwDYJt/LUkAXLp0iauuuuqqq6666qqrrvpfiuCqq6666qqrrrrqv9BqtbrVNraxjW1s88LYBsA2z802trHN/WwDYJurrrrqqquuuuqqq676f47KVVddddVVV1111X+hWiu2eX5sA2Cb+9kGwDYAtrGNbWxzP9vY5j+DJM6cOfNgrrrqqquuuuqqq6666n8fgquuuuqqq6666qr/QqvV6lbb2MY297PNA9nmX2Ib29jmfraxjW3uZ5t/K0lcddVVV1111VVXXXXV/2IEV1111VVXXXXVVf+FbPNAtnlR2QbANrYBsI1tbGObB7KNbf61JHHVVVddddVVV1111VX/R1C56qqrrrrqqquu+i8UEdjGNvezzf1scz/bANjGNgC2AbCNbe5nG9sA2MY2/1H29va46qqrrrrqqquuuuqq/6WoXHXVVVddddVVV/0XGsfxVtsA2Ob5sc39bPPC2MY2V1111VVXXXXVVVddddXzReWqq6666qqrrrrqv5BtbGObB7KNbe5nm+dmG9vYxja2sY1tbGMbANvYxjZXXXXVVVddddVVV131/xzBVVddddVVV1111X8h27faxja2sY1t/iW2eW62uZ9tbPPcbPNvIQkASUjimmuueTBXXXXVVVddddVVV131vw+Vq6666qqrrrrqqv9CtslMXhDb3M82ALZ5INvYBsA2trmfbWwDYBsA29jmqquuuuqqq6666qqr/h+ictVVV1111VVXXfVfqLUGgG0AbANgm+fHNvezjW3uZxsA29jGNvezzb+XJAD29/e56qqrrrrqqquuuuqq/6UIrrrqqquuuuqqq/5rPSMzAbDNA9kGwDYvjG1sA2AbANvYBsA2/5Fsc9VVV1111VVXXXXVVf9LUbnqqquuuuqqq676L2QbANvczzbPzTb3s41tbGOb+9nGNra5n20AbGMb2/x7SeKqq6666qqrrrrqqqv+lyK46qqrrrrqqquu+i8k6dbMxDa2sc0D2eZ+tnl+bGMb2wDYxja2AbDN82Mb2/xbXXPNNQ/mqquuuuqqq6666qqr/nehctVVV1111VVXXfVfyDa2eW62sc1zs80LY5sHsg2Abe5nm6uuuuqqq6666qqrrvp/iuCqq6666qqrrrrqv1hmYhvbANjmgWzz3GxjG9vYxja2sY1tbGMbANsA2ObfSxKSOHv2LFddddVVV1111VVXXfW/EJWrrrrqqquuuuqq/0IRcSsPYJvnxzb3s82/xDa2sc0D2QbANs/NNi+qiOCqq6666qqrrrrqqqv+FyK46qqrrrrqqquu+i+WmdjGNs/NNvezzXOzDYBtbGMb29zPNraxzX+0M2fOPJirrrrqqquuuuqqq67634Xgqquuuuqqq6666r9YZmKb+9nGNrZ5brYBsI1tAGzzQLaxjW0eyDZXXXXVVVddddVVV131/xyVq6666qqrrrrqqv9CEXErgG0AbPPcbPMvsY1tbANgGwDbANgGwDa2+feQxFVXXXXVVVddddVVV/0vRXDVVVddddVVV131XywzAbDNC2Kb+9nmfraxzQPZBsA2/1nOnz/PVVddddVVV1111VVX/S9EcNVVV1111VVXXfVfrLV2q20eyDYAtrmfbV4Q29jGNraxjW1sYxvb2OY/SkRw1VVXXXXVVVddddVV/wtRueqqq6666qqrrvovlpnYxja2sQ2AbZ6bbQBsYxsA29zPNi8q2/xrSQJAElddddVVV1111VVXXfW/EMFVV1111VVXXXXVf7FaK7Z5QWzzQLa5n20AbGMbANvYxja2sY1tbGMb29jmX0sSAJIAuOaaax7MVVddddVVV1111VVX/e9CcNVVV1111VVXXfVfbL1e3wpgG9v8e9gGwDYAtvmX2Oaqq6666qqrrrrqqqv+nyC46qqrrrrqqquu+i9mG9vczza2eSDb2OZ+trENgG0AbANgGwDbANjmP9qFCxe46qqrrrrqqquuuuqq/4UIrrrqqquuuuqqq/6L2cY2tnkg29jmgWzzQLYBsA2AbQBsYxvbANjGNrZ5INv8W0QEV1111VVXXXXVVVdd9b8Qlauuuuqqq6666qr/Ypl5q20AbPMvsc0D2QbANgC2eSDb/Gc4c+bMg7jqqquuuuqqq6666qr/XQiuuuqqq6666qqr/ovZBsA2ALZ5INs8P7axDYBtAGxjG9vYxjYAtrmfbWzzQLZ5UUlCElddddVVV1111VVXXfW/EJWrrrrqqquuuuqq/2K2b81MAGwDYJsHss0D2ea52eZ+trmfbQBsY5urrrrqqquuuuqqq676f4zgqquuuuqqq6666r+YbWxjmweyjW3uZxvbPDfb2AbANrYBsI1tAGzz3Gzzb3Xx4kWuuuqqq6666qqrrrrqfyEqV1111VVXXXXVVf/FbPNAtnlhbHM/29zPNvezzf1sA2Cb/yiSuOqqq6666qqrrrrqqv+FCK666qqrrrrqqqv+i7XWyExsYxsA29zPNs+Pbe5nGwDb2AbANrYBsM39bPPvIQmAa6655sFcddVVV1111VVXXXXV/y5Urrrqqquuuuqqq/7rPcM2tnlBbPNAtrmfbQBscz/b2AbANvezzb+HJAAkcdVVV1111VVXXXXVVf8LEVx11VVXXXXVVVf9N7ANgG1sA2Ab29zPNs/NNg9kG9vczzb3s839bHPVVVddddVVV1111VX/D1G56qqrrrrqqquu+i8m6Vbb2OZ+tnl+bGMbANsA2MY2trENgG1sA2Ab2/x7SOKqq6666qqrrrrqqqv+DyC46qqrrrrqqquu+i9mG9sA2Oa52ea52eYFsY1tAGzzQLaxzb/XpUuXuOaaax7MVVddddVVV1111VVX/e9C5aqrrrrqqquuuuq/WETcmpnYBsA2ALaxDYBtnh/bANjGNraxDYBtbANgG9s8N9v8a0niqquuuuqqq6666qqr/peictVVV1111VVXXfXfIDOxzQtjmweyDYBtnptt/iW2AbDNv5Ykrrrqqquuuuqqq6666n8hKlddddVVV1111VX/DWxjG9vYxjbPj21s8/zYxja2AbCNbf6jSOJ+ly5d4qqrrrrqqquuuuqqq/4XonLVVVddddVVV131XywibrWNbWxzP9sA2Oa52QbANgC2eSDbPJBtbGMbANv8W0jifmfOnHkwV1111VVXXXXVVVdd9b8LwVVXXXXVVVddddV/g2EYbrUNgG1sA2AbANs8N9sA2AbANraxDYBtbGObB7LNv4ckJHHVVVddddVVV1111VX/C1G56qqrrrrqqquu+m8gCdvY5gWxjW1s89xs80C2eSDb/Efa29vjmmuueTBXXXXVVVddddVVV131vwvBVVddddVVV1111X+DaZputY1tbGMb2wDY5rnZBsA2tgGwjW1sA2Ab2/x7SOK5SUISV1111VVXXXXVVVdd9b8QwVVXXXXVVVddddV/A9vY5rnZBsA2z80297PNA9nmfrYBsM2/hSSe2/7+PgDXXHPNg7nqqquuuuqqq6666qr/PQiuuuqqq6666qqr/htEBLaxjW2eH9vY5rnZBsA2trGNbWxzP9sA2Oa5SeJFIQlJSOJ+Z86ceTBXXXXVVVddddVVV131vweVq6666qqrrrrqqv8GwzDcmpnYBsA2tgGwzQPZxjYAtgGwzf1sA2Ab2/xbSeJ+knggSVy4cIGrrrrqqquuuuqqq676X4bgqquuuuqqq6666r9BZt5qG9vY5n62eUFs80C2sQ2Abf6zSEISFy5c4JprrnkwV1111VVXXXXVVVdd9b8Hlauuuuqqq6666qr/Bq01bHM/29jmfraxzXOzjW1scz/bANjGNgCSsM2LShLPjyQAJBERXHXVVVddddVVV1111f8yVK666qqrrrrqqqv+G9h+RmZiG9vczza2uZ9tbGOb52Yb2wDY5oFs8/xI4kUlCQBJSGJ3d5czZ848iKuuuuqqq6666qqrrvrfg+Cqq6666qqrrrrqv4GkWzMT29jGNv8S2wDYxjYAtrGNbWxjmxdEEveTxP0k8UCSuJ8kACRx6dIlrrnmmgdz1VVXXXXVVVddddVV/3sQXHXVVVddddVVV/03sE1mYpv72eZ+trHNc7PN/WwDYJv72cY2LwpJSOKBJAEgiftJAuDSpUtcc801D+aqq6666qqrrrrqqqv+96By1VVXXXXVVVdd9d8gIm7NTGxjG9sA2MY297ONbWxjGwDb2AbANgC2sc39bPOvJYkHksT9IoK9vT3OnDnzYK666qqrrrrqqquuuup/D4Krrrrqqquuuuqq/yaZiW1sYxvb3M82z49t7mcbANsA2MY2tgGwjW2emyReVJKQBMD+/j5XXXXVVVddddVVV131vwzBVVddddVVV1111X+DiLjVNpmJ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V1111VVXXfU/2Ww2+61rr732tTc3N5nNZnRdR9d1lFKotVJKISIopRARRASlFCKCUgoRQSmFiKCUQkQQEZRSiAgiAklEBJIAkASAbQBsYxvb2MY2trGNbTIT29jGNraxjW1sYxvb2AbANraxjW1sYxvbZCa2sU1mYhvb2MY2/1PYxja22dzc5Prrr8c2N9xwA9vb28xms1v/4R/+4bd/67d+63v+4R/+4be56qqrrrrqqquuuuq/A3rQgx7EVVddddVVV1111f9ktdbfuuaaa157e3ub2WxG3/d0XUcphVorpRQiglIKEUEphYggIiilEBGUUogISilEBBFBKYWIICKICCQhCUkASALANgC2sY1tbGMb29jGNraxjW1sYxvb2MY2ALaxDYBtAGxjG9vYxja2AchMAGxjm/vZ5kUliX8v2wBIAsA2tgGwjW0yk8zENq01NjY2uO6663jMYx7DbDa79bd+67e++7d/+7e/57777ruVq6666qqrrrrqqqv+q6AHPehBXHXVVVddddVVV/1Plpmvfe211/7WsWPHWCwW9H1PrZVaK7VWSimUUogISilEBBFBKYWIICIopRARlFKICCKCUgoRQUQQEUgiIpAEgCQAbHM/29jGNraxjW1sYxvb2AbANraxjW3uZxsA29zPNgC2AbANgG0AbANgGwDbPDdJ/FexDYBtbJOZ2CYzsU1m0lqjtUZrjY2NDR7xiEfwqq/6qtx33323fv3Xf/37/MM//MNvc9VVV1111VVXXXXVfzb0oAc9iKuuuuqqq6666qr/yTLzwSdPnnz6iRMn2NjYoO97uq6j1kqtlVIKpRQiglIKEUFEUEohIogISilEBKUUIoKIoJRCRBARRAQRgSQkIQkASQDYBsA2ALaxjW1sA2Ab29jGNgC2sc39bPNvYRsA2/xPYBvb2MY2mYltMpPMJDNprZGZtNZorTFNE4vFgkc+8pE89rGPZRiGWz/rsz7rde67775bueqqq6666qqrrrrqPwt60IMexFVXXXXVVVddddX/dLPZ7Leuueaa197c3GQ2m9H3PbVWaq2UUiilEBGUUogISilEBBFBKYWIICIopRARRASlFCKCiCAiiAgkEREASAJAEgC2AbANgG1sA2Ab29gGwDa2uZ9tHkgS95MEgCQAJCEJSUhCEvfLTABs89wk8V/FNpmJbTKTzKS1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rrrqqv8lCK666qqrrrrqqqv+D/vFX/zFX+Cq/xGOjo6+Z3d397eHYWCaJlprZCa2sY1tbGMb29jGNraxjW1s80C2sY1tbPNvJYn7SUISz00SkpDEpUuXeOxjH/taXHXVVVddddVVV/3PR3DVVVddddVVV131f9zbvd3biQd4u7d7O3HVf4dbd3d332e5XDJNE9M00VojM8lMMpPMxDa2sQ2AbWxjGwDb2MY2tnlutrENgG1eGEk8kCTuJwkASUjifhHB7u4uV1111VVXXXXVVf9LEFx11VVXXXXVVVf9P/AjP/Ijnw3wIz/yI5/NVf9tbN963333vc96vWaaJjKT1hqZiW1sYxvb2MY2trmfbWxjm/vZxja2sc1zsw2Abf61JHE/SUhCEru7u7z4i7/463DVVVddddVVV131Px/BVVddddVVV1111f8D11xzzYMBXud1Xue9ueq/1TRN333hwoXfHseRaZrITDKTzMQ2trGNbWxjG9vYxjb3s41tbPPcbGOb+9nmBZEEgCReEEkASEISEcE111zzYK666qqrrrrqqqv+5yO46qqrrrrqqquu+n/gxV7sxV4b4Jprrnnwi73Yi702V/23Ojg4eJ/1es00TbTWyEwyk8wkM8lMbGMb29jGNgC2sY1t7mcb29jGNvezzb+FJCQBIAkASQBI4tKlS9x3331cddVVV1111VVX/S9AcNVVV1111VVXXfV/3Iu92Iu91jXXXPNgnunFXuzFXour/rvdeu7cue8ehoFpmshMMpPMxDa2sY1tAGwDYBvb3M82tnl+bPOiksT9JHE/STyQJAAkIelB11xzzYO56qqrrrrqqquu+p+N4Kqrrrrqqquuuur/uGuuuebBPMDrvM7rvDdX/bdbr9efs16vmaaJ1hqZiW0yE9vYxja2sY1tbANgG9vczza2sY1tbHM/27yoJPH8SOJ+kpCEJM6cOfNgrrrqqquuuuqqq/5nI7jqqquuuuqqq676P+7FXuzFXpsHuOaaax784i/+4q/NVf+tJN169uzZ9xmGgWmayEwyE9vYxja2sY1tbANgG9sA2MY2tvnPIgkASUhCEpJ48pOfzDXXXPNgrrrqqquuuuqqq/5nI7jqqquuuuqqq676P+7FXuzFXpvn8tjHPva1uOq/3TRNvz0MA9M00VojM8lMMhPb2MY2ALaxjW0AbGOb+9nG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H00S/10k8YLYxjZnz559BlddddVVV1111VX/cxFcddVVV1111VVX/T/xdm/3dvqQD/mQhwB3AtNnfuZnvg5X/Y9nm38L2zw/tnlukpAEgCQkIYl/yYkTJ7jqqquuuuqqq676H47gqquuuuqqq6666v+fG4H64R/+4d/FVf/jSeLfyzYvCklcddVVV1111VVX/R9DcNVVV1111VVXXfX/yH333XfrP/zDP/w2wDXXXPPg13md13lvrvofTRIvKtv8e0niRXXixAmuuuqqq6666qqr/ocjuOqqq6666qqrrvp/7B3f8R0/i6v+R+v7/sH8J5GEJAAkIQkASbwobHPffffdylVXXXXVVVddddX/XARXXXXVVVddddVV/49dc801D37Hd3zHz+Kq/7EyE0m8MLa5n23+tSRxP0kASEISz49tAGxz1VVXXXXVVVdd9T8cwVVXXXXVVVddddX/c6/zOq/z3tdcc82Duer/DNs8P7Z5QSQhCQBJ/Etsc/LkSc6ePXsrV1111VVXXXXVVf9zEVx11VVXXXXVVVf9P3PmzJkH8wDXXHPNg9/xHd/xs7jqfyTb/HvY5rlJ4oEk8YJI4gWxzVVXXXXVVVddddX/cARXXXXVVVddddVVV/FiL/Zir/3iL/7ir81V/+NI4j+TJO4nCUm8qE6dOsVVV1111VVXXXXV/3AEV1111VVXXXXVVVdxzTXXPPgd3/EdP5ur/kfJzAfzn0gS95PE/SQhiRfFfffddytXXXXVVVddddVV/3MRXHXVVVddddVVV1112Yu92Iu91ou92Iu9Nlf9jySJ+9nmfrYBsM1zs82LQhL3k8TzI4kHso1trrrqqquuuuqqq/6HI7jqqquuuuqqq676f+aaa655MC/Ah3/4h38XV/2/IAkASQBIQhIPJIn72eaBJHHq1Cmuuuqqq6666qqr/oejctVVV1111VVXXXUV9913363/8A//8Nv33XffrVz1f4JtJHE/20ji+ZHEA0nigSTx3Gxz33333cpVV1111VVXXXXV/2xUrrrqqquuuuqqq/6f+ZEf+ZHPPnv27K333XffM97pnd7ps17sxV7stf/hH/7ht7/+67/+fbjqfxxJvCC2kcT9bCOJfwtJSOJ+knh+bAMgiauuuuqqq6666qr/BahcddVVV1111VVX/T/zoz/6o5/DM33913/9rd/0Td/09Bd7sRd77WuuuebB9913361c9T9GZj6YF8A2knhutgGQxL9EEpL4t9jZ2eHs2bO3ctVVV1111VVXXfU/G8FVV1111VVXXXXV/2P33Xffrb/1W7/13ddcc82D3/Ed3/GzuOp/NNv8Z5CEJCQhiauuuuqqq6666qr/Qwiuuuqqq6666qqr/p/70R/90c8BeJ3XeZ33frEXe7HX5qr/MSTxorDNi0oS/xJJvDC2OX78OPfdd9+tXHXVVVddddVVV/3PRnDVVVddddVVV131/9x9991369d//de/D8CHf/iHfxdX/b8gCUlIQhKSkMSLyjZXXXXVVVddddVV/wsQXHXVVVddddVVV13FP/zDP/z23//93//2Nddc8+AP//AP/y6u+h8hMx8MIIn72eZfyzYvKkkASOK52eaqq6666qqrrrrqfxmCq6666qqrrrrqqqu47777bv36r//69wZ4ndd5nfd+ndd5nffmqv92kpDEfzRJ3E8SkpCEJAAkASCJ+0nigY4fP8599913K1ddddVVV1111VX/sxFcddVVV1111VVXXXXZ2bNnn/H1X//173Pffffd+o7v+I6f9WIv9mKvzVX/rSTxorLNfwRJvChsc9VVV1111VVXXfW/AMFVV1111VVXXXXVVc/yW7/1W9/9W7/1W999zTXXPPjDP/zDv+uaa655MFf9t4kI/iW2eWFs84JIAkASkpDEc5PEVVddddVVV1111f9iBFddddVVV1111VVXPYff/u3f/p5/+Id/+O1rrrnmwZ/7uZ/721z1v4ZtXlSSAJAEgCQAJCEJSbwwJ06c4OzZs8/gqquuuuqqq6666n82gquuuuqqq6666qqrnsN9991369d//de/z3333XfrmTNnHvRN3/RNT+eq/xaS+Neyzb+WJAAk8aKyzVVXXXXVVVddddX/AgRXXXXVVVddddVVVz2P++6779bP+qzPep377rvv1muuuebB3/RN3/R0rvovl5kP4t/ANraxzQsjCUlIQhKSkMSL4sSJE1x11VVXXXXVVVf9L0Bw1VVXXXXVVVddddXzdd999936mZ/5ma/9D//wD799zTXXPPibvumbnn7NNdc8mKv+y5RSkMR/NUk8P5K4n23uu+++W7nqqquuuuqqq676n43gqquuuuqqq6666qoX6OzZs8/4+q//+ve57777br3mmmse/Dmf8zm/dc011zyYq/5HsM2/hSQkIQlJSEISkpAEgCQk8YLY5qqrrrrqqquuuup/AYKrrrrqqquuuuqqq16o++6779bP+qzPep1/+Id/+O1rrrnmwZ/7uZ/72+/4ju/4WVz1n04Sz49tHsg2/16SuJ8kXhjbnDhxgrNnz97KVVddddVVV1111f9sBFddddVVV1111VVX/Yvuu+++W7/+67/+fX7kR37ks237nd7pnT77Hd/xHT+Lq/5TSeI/kiSemyQkASAJSbwobHPVVVddddVVV131vwDBVVddddVVV1111VUvkvvuu+/WH/3RH/2c3/qt3/pugHd6p3f67G/6pm96+ou92Iu9Nlf9p5D0YF4A2/x7SEISkpCEJCTxojp58iRXXXXVVVddddVV/wsQXHXVVVddddVVV131r/KjP/qjn/MhH/IhD/mHf/iH377mmmse/OEf/uHf9U7v9E6fzVX/4STxorLNi0ISz48kACQhCUn8S+67775bueqqq6666qqrrvqfjeCqq6666qqrrrrqqn+1++6779av//qvf58f+ZEf+exrrrnmwe/4ju/4Wd/0Td/09Hd8x3f8LK76DyWJF5VtbPOikoQkJAEgiecmiauuuuqqq6666qr/xQiuuuqqq6666qqrrvo3ue+++2790R/90c/5kA/5kIf8wz/8w29fc801D36nd3qnz/6mb/qmp7/O67zOe3PVv5sk/jNIQhL3k4QkJCEJSQBI4gU5efIkV1111VVXXXXVVf8LUI4fP85VV1111VVXXXXVVf92h4eHu7/1W7/1PWfPnn3Ggx/84Je+5pprHvyKr/iKb/26r/u673N4eLh76623/jVX/ZvUWt96sVi8dCmFUgoRQUQgCUlIAkASkpCEJCQhCUlIQhKSiAgigoiglEKtlVorpRRKKdyvtUZrjdYarTUyk8wkM8lMWms85jGPecbP//zPfzVXXXXVVVddddVV/7NRjh8/zlVXXXXVVVddddVV/3633nrrX//Zn/3ZzxweHu5ec801D77mmmse/Iqv+Ipv/Tqv8zrvvbm5eRzQ2bNnb+WqF9lisfjo2Wz24FIKpRQigohAEpKQhCQkIQlJSEISkpCEJCQhiYggIogISimUUqi1UkqhlIIkbJOZtNZordFaIzPJTDKTzCQzebmXe7lLP//zP//VXHXVVVddddVVV/3PRuWqq6666qqrrrrqqv8w9913360/+qM/+jm//du//T1nzpx58Du90zt91ou92Iu99ju90zt9NsDZs2ef8Zu/+Zvf9du//dvfc999993KVS9Ua43/LJKQBIAkJAEgiX/Jzs4O9913361cddVVV1111VVX/c9HOX78OFddddVVV1111VVX/cc6PDzcPXv27K2/9Vu/9T2//du//T2bm5vHH/KQh7z05ubm8Rd/8Rd/7Td/8zf/6Nd5ndd5783NzeOAzp49eyv/Cm/7tm/7bq/8yq/89n/913/92/wXed/3fd/Pv+WWW0498YlPfBz/Rfq+f+/5fP7gUgqlFCKCiEASkpCEJCQhCUlIQhKSkIQkJCGJiCAiKKVQSqGUQq2VWisRgSQyk9YarTVaa7TWyEwyk8wkM+m6joc85CHP+K3f+q3v5qqrrrrqqquuuup/NvSgBz2Iq6666qqrrrrqqqv+811zzTUPfrEXe7HXerEXe7HXfp3XeZ335gHuu+++WwH+4R/+4bf/4R/+4Xfuu+++W8+ePXvrfffddyvP5Sd+4ifMA3zAB3xAvXDhQuMBrrnmmgefOXPmwS/2Yi/2Wi/+4i/+2vfdd98zvv7rv/69+Td4yEMesvjyL//yIx7g7d7u7cR/gY2Njd86duzYa/d9T9d1lFIopRARRAQRgSQkERFIQhKSKKUQEUQEEUFEUEqh1kqtla7rmM1mzGYzuq6j1gpAa41hGFiv16zXa9brNeM4Mo4j0zQxjiPXXXcdN9100/d8/dd//Xtz1VVXXXXVVVdd9T8betCDHsRVV1111VVXXXXVVf+1rrnmmgefOXPmwS/2Yi/2Wi/+4i/+2i/2Yi/22rwA9913361nz569FdCLvdiLvRbPx2/91m99N8A111zz4Bd7sRd7bZ7L2bNnn/H3f//3v8VzEmCekwDzAK/zOq/z3jyXs2fPPuM3f/M3v+vs2bPPALjvvvtuPXv27K333Xffrddcc82DAc6cOfNggGuuuebBAGfOnHkQwG//9m9/z3333XcrL4Ljx48/fbFYPLjve7quo5RCKYWIICKICCQhiYhAEpKQRCmFiCAiiAgiglIKtVZqrfR9T9/3zGYz+r6n1gpAa431es16vWa9XrNerxnHkXEcmaaJcRy57rrruOmmm77n67/+69+bq6666qqrrrrqqv/Z0IMe9CCuuuqqq6666qqrrvrvdc011zz4zJkzD77mmmsefObMmQe9+Iu/+GufOXPmwddcc82DAe67775br7nmmgfzf8CHfMiHPOS+++67lRfB9vb207e2th48m82otVJKoZRCRBARSCIikIQkIgJJSKKUQkQQEUQEEUEphVortVb6vmc2mzGbzej7nlorANM0MQwDq9WK9XrNMAwMw8A4jkzTxDiOXHfdddx0003f8/Vf//XvzVVXXXXVVVddddX/bFSuuuqqq6666qqrrvpvd999991633333foP//APAPzoj/7o5/BM11xzzYPPnDnzYMAf/uEf/t3XXHPNg3kuX//1X/8+AC/2Yi/2Wtdcc82DX+zFXuy1eYB/+Id/+O3f+q3f+h6ekwHxnAyIB/jwD//w7+L5+Id/+IfffrEXe7HX5l/hH/7hH377vvvuu5V/BUk8kG1eENsASMI2L4gk7icJSUgCQBIAknhBjh07xn333fd0rrrqqquuuuqqq/7nQw960IO46qqrrrrqqquuuup/j5/4iZ8wD/B2b/d24rlcc801DwZ4sRd7sdd+sRd7sdc6e/bsM37kR37ks/k3+omf+AnzAG/3dm8ngGuuuebBr/3ar/1er/M6r/Pe11xzzYN5EZw9e/YZv/mbv/ld//AP//A7//AP//DbvBDb29tP397efnDXdXRdRymFiKCUQkQgiYhAEpKQhCQigoiglEJEEBFEBKUUaq10XUff98xmM2azGbPZjFortpmmiWEYWK1WrFYrhmFgGAbGcWSaJsZx5JGPfCSr1eqzf/RHf/RzuOqqq6666qqrrvqfDT3oQQ/iqquuuuqqq6666qqr/j2uueaaB7/Yi73Ya73Yi73Ya7/O67zOe/Miuu+++2790R/90c/5rd/6re/m+djZ2Xn61tbWg/u+p9ZKKYWIoJRCRCCJiEASkpCEJCKCiKCUQkQQEZRSKKVQSqHrOvq+Zz6fM5vNmM1mlFIAmKaJ9XrNarVitVoxDAPDMDCOI9M0MY4jj3zkI1mtVp/9oz/6o5/DVVddddVVV1111f9slOPHj3PVVVddddVVV1111VX/HoeHh7u33nrr3/zpn/7pz/z2b//299x6661/s7m5efyaa655MA/wmZ/5ma/zW7/1W98N8JCHPOSlNzc3j7/iK77iW7/u677u+2xsbBz7h3/4h9/hAWaz2Uf3fX+8lEJEEBFIIiIAkIQkJCEJSUhCEpKICCQhiYggIiilUEqh1kqtla7rqLUSEUjCNq01pmmitUZrjdYatslMMpOHPexhPP3pT/+eW2+99a+56qqrrrrqqquu+p8NPehBD+Kqq6666qqrrrrqqqv+M5w5c+ZBr/M6r/Per/M6r/Pe11xzzYPf7u3eTjzTNddc8+AXe7EXe+3XeZ3Xea8Xe7EXe22A++6779bf+q3f+u4f/dEf/RyAEydOeLFY0Pc9tVZKKUQEEUFEEBFEBJKQhCQkERFEBKUUIoKIoJRCKYVaK13X0fc98/mc+XzObDajlALAOI6s12tWqxWr1Yr1es0wDEzTxDiOjOPIK7zCK/D3f//37/Nbv/Vb381VV1111VVXXXXV/2zoQQ96EFddddVVV1111VVXXfWf6ZprrnkwwH333Xcrz8eZM2ce9BEf8RHf/WIv9mKvDXDffffd+tu//dvf82u/9mufNZ/P6fueWiulFCKCiCAiiAgkERFIQhKSiAgigoiglEJEUEqhlEKtla7rmM1mzOdz5vM5fd9TawVgHEfW6zXL5ZLVasV6vWYcR8ZxZBxHxnHkDd7gDfj93//99/mt3/qt7+aqq6666qqrrrrqfzaCq6666qqrrrrqqquu+k9233333Xrffffdygtw9uzZZ3zmZ37m63zIh3zIQ/7hH/7ht6+55poHv+M7vuNn2eY/gyQeSBKSAJDEi+Ls2bO3ctVVV1111VVXXfU/H8FVV1111VVXXXXVVVf9D3Hffffd+pmf+Zmv8/Vf//Xvc999993KA9jmBbHNi0oSAJKQhCQkIQlJ3E8SkpDEc8tMrrrqqquuuuqqq/6XoHLVVVddddVVV1111VX/w/zWb/3Wd//93//9b0m6lX8l27yoJCEJSUgCQBKSeGFOnDjBfffddytXXXXVVVddddVV//MRXHXVVVddddVVV1111f9A9957L8/NNi+IbWzzwkgCQBKSAJCEJCQhCUn8S2xz1VVXXXXVVVdd9b8Elauuuuqqq6666qqrrvp/ShKSkIQk7icJSbwgJ06c4Kqrrrrqqquuuup/CSpXXXXVVVddddVVV131v5RtJPGvIQkASUhCEpKQBIAkXhT33XffrVx11VVXXXXVVVf9z0flqquuuuqqq6666qqr/geTxH80SUhCEpKQhCQAJCEJAEk8kCSuuuqqq6666qqr/pehctVVV1111VVXXXXVVf9DSeI/myQiAkk8kCRekBMnTnDVVVddddVVV131vwSVq6666qqrrrrqqquu+h/I9oP5DySJ+0lCEpKQhCQkASAJSdxPEpJ4oPvuu+9Wrrrqqquuuuqqq/53oHLVVVddddVVV1111VX/x0kCQBKSuJ8kJCEJSQBI4vmRBIAkrrrqqquuuuqqq/4XIbjqqquuuuqqq6666qr/hWwDYJvnZpsXRhKSkIQkJBERSEISkpDE87O9vc3Zs2dv5aqrrrrqqquuuup/BypXXXXVVVddddVVV131/5AkJCEJSUhCEg8kiecmiauuuuqqq6666qr/RahcddVVV1111VVXXXXV/0CZ+WBeRLa5nyReGElIAkASkpCEJAAkIYkXZGdnh/vuu+9Wrrrqqquuuuqqq/53ILjqqquuuuqqq6666qr/gSQhiedmG9v8e0lCEpKQhCQkIQlJSOKqq6666qqrrrrq/wAqV1111VVXXXXVVVdd9T+QJP6jSQJAEpKQhCQiAklIQhIPJImrrrrqqquuuuqq/8WoXHXVVVddddVVV1111f9AkvjPIAkASQBIQhKSkASAJAAk8dx2dna46qqrrrrqqquu+l+EylVXXXXVVVddddVVV/0PJIn/SJK4nyQAJBERSEISkpAEgCTuJ4kHuu+++27lqquuuuqqq6666n8Hgquuuuqqq6666qqrrvpfyjb/VpKQhCQkERFIQhKSuOqqq6666qqrrvo/guCqq6666qqrrrrqqqv+Z3ow/8EkIQlJSEISkogIJCEJSTw/kgDY2dnh7Nmzz+Cqq6666qqrrrrqfwcqV1111VVXXXXVVVdd9T+QJP4zSUISkpCEJCQhCUlI4vmxzVVXXXXVVVddddX/IlSuuuqqq6666qqrrrrqfyBJSOJfyzb3k8TzIwmAiEASkpBERPBAkpDE/SRx/Phxrrrqqquuuuqqq/4XIbjqqquuuuqqq6666qr/gSTxorDN/Wzz/EjifpIAkIQkIgJJSEISkpDEC2Kb++6771auuuqqq6666qqr/ncguOqqq6666qqrrrrqqv+BIuLBvIhs8y+RhCQAJCEJSUgiIogIJCEJAElcddVVV1111VVX/R9AcNVVV1111VVXXXXVVf8D2QZAEs+PbR7INs+PJB5IEpKQhCQkIQlJSEISknggSdxvZ2eHs2fP3spVV1111VVXXXXV/w5Urrrqqquuuuqqq6666n8gSfxnkoQkJBERSEISDySJq6666qqrrrrqqv/lqFx11VVXXXXVVVddddX/E5KQhCQkIYmIQBKSkIQkJCGJ5+f48eNcddVVV1111VVX/S9C5aqrrrrqqquuuuqqq/4HksR/FklIQhKSkEREIAlJPJAkACRxv/vuu+9Wrrrqqquuuuqqq/53oHLVVVddddVVV1111VX/Q0niP4oknpskJBERSEISkpCEJJ4f21x11VVXXXXVVVf9L0Jw1VVXXXXVVVddddVV/wNFxIN5LrYBsM2/lSQkIYmIICKQhCQkIYn7SeK5nThxgquuuuqqq6666qr/RQiuuuqqq6666qqrrrrqfyBJ/Ets86KQBIAkACQhCUlIQhIRgSQAJPFAkrjffffddytXXXXVVVddddVV/3tQueqqq6666qqrrrrqqv8jbPMvkQSAJCQREUQEkpCEJCQhiecmiauuuuqqq6666qr/ZQiuuuqqq6666qqrrrrqfxHb/FtIQhIAkpCEJCQhCUlIQhIvyPb2NmfPnr2Vq6666qqrrrrqqv89CK666qqrrrrqqquuuup/oL7vH8yLwDYAtnlRSEISkpBERBARRASSkIQkACQhCQBJXHXVVVddddVVV/0vRHDVVVddddVVV1111VX/A7XWeFHZ5gWRxANJAkASEYEkJCEJSUgCQBLPbWdnh/vuu+9Wrrrqqquuuuqqq/73oHLVVVddddVVV1111VX/T0gCQBKSkIQkIgJJSAJAEg8kiauuuuqqq6666qr/pahcddVVV1111VVXXXXV/3GSkASAJCQhCUlEBJKQhCQkcdVVV1111VVXXfV/CJWrrrrqqquuuuqqq676H0oSL4htJPFvIQlJRASSiAgkERFIQhKSeG7b29tcddVVV1111VVX/S9D5aqrrrrqqquuuuqqq/4HksS/lyQeSBKSkIQkJBERSEISkpDE/SQhiQe67777buWqq6666qqrrrrqfw8qV1111VVXXXXVVVdd9T9QKeXB/CeKCCQhiYgAQBKSkMRzk8RVV1111VVXXXXV/0IEV1111VVXXXXVVVdd9X+QJB5IEpKQhCQkERFEBJKICCRxP0k8t52dHc6ePfsMrrrqqquuuuqqq/73oHLVVVddddVVV1111VX/x0nifpKQhCQkIQlJSEISkpDEA0kCwDZXXXXVVVddddVV/8tQueqqq6666qqrrrrqqv+lbCOJF0YSz00SkogIIoKIAEASkrifJCRxv52dHa666qqrrrrqqqv+lyG46qqrrrrqqquuuuqq/wVs8/zYBsA295PEc5OEJCQhCUlIQhKSiAgkIQlJSOK52ea+++67lauuuuqqq6666qr/PQiuuuqqq6666qqrrrrqf5jMfDAvhG0eyDb/GpKQhCQigohAEpK46qqrrrrqqquu+j+GylVXXXXVVVddddVVV/0fJwkASUhCEhFBRCAJSQBIQhKSeH62t7c5e/bsrVx11VVXXXXVVVf970Hlqquuuuqqq6666qqr/h+QBIAkJCEJSUQEEYFtJCEJAElIAkASkrjqqquuuuqqq676X4jKVVddddVVV1111VVX/Q8kiX8vSTyQJAAkIYmIQBKSkIQkJCGJ+0nifseOHeOqq6666qqrrrrqfxkqV1111VVXXXXVVVdd9T9MZj6Y/yCSeCBJAEhCEhFBRGAbSfxL7rvvvlu56qqrrrrqqquu+t+DylVXXXXVVVddddVVV/0vYhtJ/GtIQhKSkIQkJBERSEISAJKQhCSeH9tcddVVV1111VVX/S9DcNVVV1111VVXXXXVVf/DSAJAEg9km/vZ5t9KEhGBJCICSUhCEpIAkIQkHuj48eNcddVVV1111VVX/S9D5aqrrrrqqquuuuqqq/4PkcQLIglJSEISkpBERGAbSQBI4n6SkIQk7rvvvlu56qqrrrrqqquu+t+FylVXXXXVVVddddVVV/0fYJsHksQDSQJAEpKQREQQEUgCQBKSeH4kcdVVV1111VVXXfW/EMFVV1111VVXXXXVVVf9D5OZD5bEv8Q2/xJJSAJAEpKQhCQkIYmIQBKSkIQkJPFAm5ubnD179lauuuqqq6666qqr/nehctVVV1111VVXXXXVVf/DSOKBbPOC2AZAEs9NEs+PJCKCiCAikIQkJCGJ+0niqquuuuqqq6666n85KlddddVVV1111VVXXfU/jCT+o0lCEpKQhCQkIQlJSEISz48ktre3ue+++27lqquuuuqqq6666n8XKlddddVVV1111VVXXfU/jCT+s0hCEpKICCKCiABAEpKQhCQAJHHVVVddddVVV131vxiVq6666qqrrrrqqquu+j9OEpKQhCQkERFIQhKSkIQkJHHVVVddddVVV131fwjBVVddddVVV1111VVX/Q8jiRfGNi+MJO4niecmCUlEBBGBJCQhCQBJAEjifltbW1x11VVXXXXVVVf9L0Tlqquuuuqqq6666qqr/oex/SD+E0hCEpKQhCQkIQlJSEISAJK4nyQA7rvvvlu56qqrrrrqqquu+t+FylVXXXXVVVddddVVV/0PIwlJ/HtIQhIAkpCEJCQREUQEEUFEEBHY5vmRxFVXXXXVVVddddX/YgRXXXXVVVddddVVV131P4wk/rVs86KQhCQkIQlJSEISkpCEJJ7b9vY2Z8+efQZXXXXVVVddddVV/7tQueqqq6666qqrrrrqqv9hJPEfRRIAkpCEJCQhiYhAEpKQhCQkcT9J3M82V1111VVXXXXVVf8LEVx11VVXXXXVVVddddX/MBHxYP4FtnlRSeKBJCEJSUQEkpCEJAAkIYkH2tnZ4aqrrrrqqquuuup/IYKrrrrqqquuuuqqq676H8Y2/xq2+ZdIQhKSkEREIAlJSEISkpDEA0lCEpnJfffddytXXXXVVVddddVV/7sQXHXVVVddddVVV1111f8wknhBbHM/29jmBZHEA0lCEpKQREQgCUlIQhJXXXXVVVddddVV/8cQXHXVVVddddVVV1111f8RkpDEA0lCEpIAkIQkIgJJRAQRgSQAJCEJAEncb2tri7Nnz97KVVddddVVV1111f8uVK666qqrrrrqqquuuup/GElI4t9KEpJ4bpKQhCQkERFIQhKSkMT9JPFAtrnqqquuuuqqq676X4jKVVddddVVV1111VVX/T8gCUlIQhKSkIQkJCEJSUjigSQBcOzYMa666qqrrrrqqqv+FyK46qqrrrrqqquuuuqq/2EkPZjnYhvb/GtJQhIPJImIQBKSkIQkACQhiQeShG3uu+++W7nqqquuuuqqq67634XKVVddddVVV1111VVX/Q8jif8IknggSUhCEpKICCQhCQBJvCC2ueqqq6666qqrrvpfiMpVV1111VVXXXXVVVf9HycJSQBIIiKQhCQkIQlJSEISAJKQxP2OHTvGVVddddVVV1111f9CBFddddVVV1111VVXXfW/jG3+JZJ4bpKQhCQkIYmIAEAS95PE/SQhifvuu+9Wrrrqqquuuuqqq/73oXLVVVddddVVV1111VX/w5RSHsx/EEkASEISkpBERCAJSUhCEpKQxHOTxFVXXXXVVVddddX/UgRXXXXVVVddddVVV131v5xtHkgSAJIAkMT9JCEJSUQEkpAEgCSen42NDc6ePXsrV1111VVXXXXVVf/7EFx11VVXXXXVVVddddX/UJJ4QWzzQJIAkMTzIwlJSEISkpCEJCQhiftJQhKSkMRVV1111VVXXXXV/2JUrrrqqquuuuqqq6666n8gSfxLbAMgiRdEEpIAkIQkJBERSEISkpCEJCTx3DY3N7nvvvtu5aqrrrrqqquuuup/HypXXXXVVVddddVVV131f5AkHkgS95OEJCQhCUlI4qqrrrrqqquuuur/ICpXXXXVVVddddVVV131P0zXdQ/mP4Ak7icJSUhCEpKQhCTuJ4kHkgSAJK666qqrrrrqqqv+lyK46qqrrrrqqquuuuqq/2Eyk38LSQBI4n6SkASAJCQREUgiIgCQhCQkIQlJ3E8SGxsbXHXVVVddddVVV/0vRXDVVVddddVVV1111VX/w0jiBbHNv4UkJCEJSUhCEpKQxHOTxP0kcd99993KVVddddVVV1111f8+BFddddVVV1111VVXXfU/yOu8zuu8t23+vSQhCQBJ3E8SkogIJCEJAElcddVVV1111VVX/R9EcNVVV1111VVXXXXVVf+DvOM7vuNn8e8giQeSBIAkJCEJSUhCEpKQBIAkJPHcNjc3OXv27DO46qqrrrrqqquu+t+HylVXXXXVVVddddVVV/0PI4n/DJKQhCQkIQlJSEISz00SkrDNVVddddVVV1111f9SVK666qqrrrrqqquuuup/kHvvvRfb/GvY5oEk8UCSkASAJCQhCUncTxKSAJDEA21tbXHVVVddddVVV131vxTBVVddddVVV1111VVX/Q9xzTXXPPglXuIlHiyJF8Y2/xJJSEIS95OEJCQhCUlIQhLPTRL3s8199913K1ddddVVV1111VX/+xBcddVVV1111VVXXXXV/xD33XffrQCPfvSjeVHZ5l8iCUlIQhKSkASAJB5IEveThCSuuuqqq6666qqr/hcjuOqqq6666qqrrrrqqv9B/uEf/uG3X/3VX53nxzYviCQk8dwkASCJ+0lCEpIAkIQkJPH8XHPNNZw9e/ZWrrrqqquuuuqqq/73Ibjqqquuuuqqq6666qr/QX7rt37rex796Edz6tQpXhjb2Oa5SeJ+kgCQBIAkJCEJSUhCEv+S5XL5jPvuu+9Wrrrqqquuuuqqq/73Ibjqqquuuuqqq6666qr/QX7rt37ruzPz1rd4i7fg30oSknggSUhCEpKQhCQkIQlJPD+PetSjuO+++57OVVddddVVV1111f9OBFddddVVV1111VVXXfU/zI/+6I9+zsMe9rBb3/RN3xQA2/xbSUISAJKQhCQkIYkXRBKLxYJHPepR/NZv/db3cNVVV1111VVXXfW/E5Wrrrrqqquuuuqqq676H+a3fuu3vvvMmTMPeqd3eqfPlsSv/uqv8m8hiftJAkASkpCEJCRxP0kASGI2m/HIRz6Sf/iHf/jt3/qt3/purrrqqquuuuqqq/53Irjqqquuuuqqq6666qr/gX7rt37ru//hH/7ht9/kTd6Ez/iMz+DEiRP8W0hCEgCSkIQkJHE/STxQrZWHPvShnDhxgh/5kR/5HK666qqrrrrqqqv+96IcP36cq6666qqrrrrqqquu+p/m6Ojo0j/8wz/8zq233vo3r/Var/XWL/7iL87GxgZPe9rTkIQkJCEJSZRSqLVSSqGUQimFUgq1Vmqt9H3PfD5nc3OT7e1ttre32djYoO97JJGZrFYrVqsVJ0+e5ClPecpvf/3Xf/37/MM//MNvc9VVV1111VVXXfW/F+X48eNcddVVV1111VVXXXXV/0SHh4e7R0dHu7feeuvfvNZrvdZbP+xhD+PlX/7lWSwWPP3pT0cSkgAopVBKoZRCKYVSCrVWSil0XUfXdcznczY2Ntje3mZ7e5uNjQ26rkMS586dY29vj4jgvvvuu/W7vuu7PuYf/uEffpurrrrqqquuuuqq/90ox48f56qrrrrqqquuuuqqq/6nOjw83L311lv/+rd/+7e/5yEPechL33LLLQ9+6EMfysu93Mtxww03sFqt2N3dpdZKKYVSCqUUSimUUqi1Umul73vm8zmbm5tsb2+zvb1N13UcHBxw++23s1qtuPfee2+99dZb//pLv/RL3+bWW2/9a6666qqrrrrqqqv+90MPetCDuOqqq6666qqrrrrqqv8tXuzFXuy13+md3umzXuzFXuy1eaaLFy9y2223cfvtt3N4eEitleVyyWq1YjabcerUKTY2Njh9+jTXX389W1tbzOdzbHO/++6779Yf/dEf/Zzf+q3f+m6uuuqqq6666qqr/u9AD3rQg7jqqquuuuqqq6666qr/ba655poHv/Zrv/Z7vfiLv/hrv9iLvdhr829w33333fpbv/Vb33327Nln/NZv/dZ3c9VVV1111VVXXfV/D3rQgx7EVVddddVVV1111VVX/W92zTXXPPjFXuzFXvvFXuzFXuuaa655MMCZM2cefM011zwY4L777rsV4OzZs7fed999t9533323/sM//MPv/MM//MNvc9VVV1111VVXXfV/G3rQgx7EVVddddVVV1111VVXXXXVVVddddVVV131fxKVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1X8I75L/M2Yj6jAAAAAAElFTkSuQmCC) @@ -66,7 +74,7 @@ sweepSketch = startSketchOn(XY) import "tests/inputs/cube.sldprt" as cube cube - |> scale(scale = [1.0, 1.0, 2.5]) + |> scale(x = 1.0, y = 1.0, z = 2.5) ``` ![Rendered example of scale 1](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAADPfd1WAAEj5UlEQVR4Ae3AA6AkWZbG8f937o3IzKdyS2Oubdu2bdu2bdu2bWmMnpZKr54yMyLu+Xa3anqmhztr1a8+6EEP4qqrrrrqqquuuuqqq6666qqrrrrqqquu+j+JylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrvoXvNiLvdhrc9VVV/2PdPbs2Vvvu+++W7nqqquuuuqqq656/qhcddVVV1111VVXvQAv9mIv9tof/uEf/l3XXHPNg7nqqqv+R/qHf/iH3/77v//73/7RH/3Rz+Gqq6666qqrrrrqeaEHPehBXHXVVVddddVVVz23d3zHd/ysd3qnd/rsv/iLv+DHfuzHuOr/D9tc9b/H67/+6/MGb/AG/MM//MNvf+ZnfubrcNVVV1111VVXXfWc0IMe9CCuuuqqq6666qqr7nfNNdc8+MM//MO/68Ve7MVe+9d//df59V//da666v8j2/xvceLECT7ogz6IcRxv/azP+qzXue+++27lqquuuuqqq6666gr0oAc9iKuuuuqqq6666iqAa6655sGf8zmf81td1z34x3/8x3na057GVf+32eaq/xtOnDjBB37gBzKO462/9Vu/9d0/+qM/+jlcddVVV1111VVXAeX48eNcddVVV1111VVXvc7rvM57f+7nfu5v3Xvvvce/7uu+josXL3LV/32SkIQkJCEJSUhCEpKQhCQkIQlJSEISkpCEJCQhCUlIQhKSkIQkJCEJSUhCEpKQhCQk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IEn8R7LNCyKJq/53sM3/FLZ5bhsbGwDcd999t3LVVVddddVVV/1vR+Wqq6666qqrrvo/ZWNjg8PDQyTxorANgCReFLYBkMSLwjb3k8SLyjYAkvjXsM39JPFvYZv7SeLfwzbPTRL/GWzzwkjiqv9atvmfyDYvzMbGBlddddVVV1111f8ZBFddddVVV1111f8J99133608gG1s86KyjW1eVLaxzb+GbWzzr2Eb29jmX8s2trGNbf4tbGMb29jmP4JtbGMb29jmv4JtbGMb29jGNraxjW2uetHZxja2sY1tbGMb29jmfwrb2MY2tnlRnT179lauuuqqq6666qr/7Qiuuuqqq6666qr/E86ePXsrwMbGBg9kG9u8qGxjmxeVbWxjmxeVbWxjm38N29jGNv8WtrGNbf6tbGMb29jmP4ptbGMb29jGNv/VbGMb29jGNraxjW1sYxvb2MY2/5fYxja2sY1tbGMb29jGNrb5n8w2trGNba666qqrrrrqqv/XqFx11VVXXXXVVf8v2AZAEi8K2wBI4kVlGwBJvKhscz9JvKhscz9J/GvZ5oEk8W9hm+cmif8otnl+JPE/hW2u+u9lm/9IGxsbANx33323ctVVV1111VVX/W9HcNVVV1111VVX/Z9w33333QqwubnJC2Mb27yobGMb27yobGMb2/xr2MY2/1q2sY1t/q1sYxvb/HvZxja2sc1/BtvYxja2sY1trvq/zza2sY1tbHPVVVddddVVV131QlC56qqrrrrqqqv+T9nY2OBFYZv7SeJFYRsASbyobAMgiReVbe4niX8N2zyQJP61bPNAkvj3sM1zk8R/Btu8MJK46n8H2/x32NjYAOC+++67lauuuuqqq6666v8CKlddddVVV1111f8J99133608k20AJPGisA2AJF4UtgGQxIvKNveTxIvKNveTxL+Wbe4niX8L2zyQJP69bPPcJPGfzTYvjCSu+q9lm/9JNjY2ADh79uytXHXVVVddddVV/xdQueqqq6666qqr/s+yDYAkXhS2AZDEi8I295PEi8o2AJL417DN/STxr2Wb+0ni38o2DySJ/wi2eW6S+K9kmxeVJK564Wzzv83GxgYA9913361cddVVV1111VX/F1C56qqrrrrqqqv+Tzh79uwzADY3N3lutgGQxIvCNgCSeFHZBkASLyrb3E8S/xq2uZ8k/rVs80CS+LeyzQNJ4j+KbZ4fSfx3s82/hST+N7LNVVddddVVV1111f9CVK666qqrrrrqqv8T7rvvvlsBNjc3eUFsAyCJF4Vt7ieJF4Vt7ieJF5Vt7ieJfw3b3E8S/xa2uZ8k/j1s89wk8R/JNs+PJP6ns81V/7PY5n62ueqqq6666qqr/k+hctVVV1111VVX/b9jGwBJvKhsAyCJF5VtACTxr2Gb+0niX8M295PEv4VtHkgS/162eSBJ/GewzQsiiauuArDNC7KxsQHAfffddytXXXXVVVddddX/BVSuuuqqq6666qr/E86ePXsrwObmJi8q2wBI4kVlGwBJvKhscz9J/GvYBkAS/1q2uZ8k/q1s80CS+PeyzXOTxH8m27wgkrjq/y7bvKg2NjYAOHv27DO46qqrrrrqqqv+L6By1VVXXXXVVVf9n2MbAEm8KGwDIIkXlW3uJ4kXlW0AJPGvYZv7SeJfyzYPJIl/K9s8kCT+I9jmuUniv4Jt/iWSuOp/NttcddVVV1111VVXPRcqV1111VVXXXXV/wn33XffrQCbm5vczzYAknhR2OZ+knhR2QZAEi8q29xPEv8atrmfJP4tbHM/Sfx72OaBJPEfxTbPTRL/HWzzopDEVf95bPOfaWNjA4D77rvvVq666qqrrrrqqv8LqFx11VVXXXXVVf/n2QZAEi8q2wBI4kVlGwBJ/GvY5n6S+Newzf0k8W9hmweSxL+HbR5IEv+RbPP8SOJ/Atv8a0niKrDNVVddddVVV1111X8wKlddddVVV1111f8Z9913363XXHPNgzc3Nzk8POS52QZAEi8q2wBI4kVlm/tJ4l/DNgCS+Neyzf0k8W9lm/tJ4t/LNg8kif8Mtnl+JPE/nW3+o0niv4pt/q/Y2NgA4OzZs7dy1VVXXXXVVVf9X0Bw1VVXXXXVVVf9n3H27NlbATY3N3lhbGObfw3b2OZfyza2+deyjW1s829hG9vY5t/DNraxjW3+I9jGNraxjW3+M9nGNraxjW1s83+dbWxjG9vYxja2sY1tbGMb29jGNraxjW1sYxvb2MY2trGNbWxjm6uuuuqqq6666qr/wahcddVVV1111VX/b9kGQBIvKtvcTxIvKtvcTxL/Gra5nyT+tWzzQJL4t7LNA0niP4JtHkgS/9ls84JI4qr/nzY2NgC47777buWqq6666qqrrvq/gOCqq6666qqrrvo/47777rsVYGNjA9u8qGxjG9v8a9jGNv9atrHNv4VtbGObfyvb2MY2/162sY1t/iPZxja2sY1t/ivZxja2sY1tbGMb21x11VVXXXXVVVdd9b8Glauuuuqqq6666v8s2wBI4kVlGwBJvKhscz9JvKhscz9J/GvZ5n6S+Lewzf0k8e9hmweSxH8k2zw3Sfx3sM2/RBJX/e+ysbEBwNmzZ5/BVVddddVVV131fwWVq6666qqrrrrq/4z77rvvVoDNzU0eyDYAknhR2QZAEv8atgGQxL+Gbe4niX8t29xPEv8WtnkgSfx72OaBJPEfzTbPjyT+u9nmXyKJq/7n2NjYAOC+++67lauuuuqqq6666v8KKlddddVVV1111f8btgGQxIvKNgCS+NewDYAk/rVsAyCJfwvb3E8S/1a2uZ8k/r1s89wk8Z/BNs9NEv/T2OZFJYmr/nNtbGwAcN99993KVVddddVVV131fwWVq6666qqrrrrq/4yzZ88+A2Bra4sXxjYAknhR2eZ+knhR2eZ+kvjXsM39JPFvYZv7SeLfyjYPJIn/CLZ5IEn8Z7HN8yOJ/w1s828hiauuuuqqq6666qr/x6hcddVVV1111VX/Z9x33323AmxubvKisA2AJP41bAMgiX8N2wBI4l/LNveTxL+Fbe4niX8P29xPEv9RbPNAkvjPZpsXRBL/29nmP4Ik/i+wzQtim6uuuuqqq6666v8cKlddddVVV1111f85tvnXsA2AJP41bAMgiX8N29xPEv9atrmfJP4tbHM/Sfx72OaBJPEfxTbPTRL/VWzz/Eji/xvb/F+3sbEBwH333fd0rrrqqquuuuqq/yuoXHXVVVddddVV/2ecPXv2VoCtrS1sAyCJF5VtACTxr2Gb+0niX8M295PEv5Zt7ieJfwvb3E8S/162eSBJ/EeyzXOTxH8l27wgkrjqf6fNzU0Azp49+wyuuuqqq6666qr/K6hcddVVV1111VX/p9kGQBIvKtvcTxL/GrYBkMS/lm0AJPFvYZv7SeLfwjYPJIl/L9s8kCT+o9nmuUniv4NtXhBJXHXVVVddddVVV131X4rKVVddddVVV131f8Z99913K8Dm5ibPzTYAkvjXsA2AJP41bAMgiX8t29xPEv8WtrmfJP6tbHM/SfxHsM0DSeI/g22emyT+O9nmhZHEVf99NjY2uOqqq6666qqr/s+hctVVV1111VVX/b9iGwBJ/GvYBkAS/xq2uZ8k/rVscz9J/FvY5n6S+LeyzQNJ4j+CbR5IEv9ZbPPcJPE/hW1eGElc9Z/v7Nmzt3LVVVddddVVV/1fQXDVVVddddVVV/2fct99990KsLm5yQtjG9v8a9nGNv8WtrHNv5VtbPPvYRvb2Obfyza2sc1/JNvYxja2+c9mG9vYxja2sc3/RLaxjW1sYxvb2MY2V/37bGxsAHDffffdylVXXXXVVVdd9X8FwVVXXXXVVVdd9X/K2bNnbwXY3NzkRWEb2/xr2cY2tvnXso1tbPNvYRvb2Obfwza2sc2/l21sYxvb/EeyjW1sY5v/KraxjW1sY5v/6WxjG9vYxja2sY1trrrqqquuuuqqq/4fonLVVVddddVVV10F2OZ+kvjXsA2AJP61bAMgiX8L29xPEv9WtrmfJP69bHM/SfxHss1zk8R/Bds8P5L438A2/xJJ/H+1sbEBwH333XcrV1111VVXXXXV/xUEV1111VVXXXXV/yn33XffrQCbm5vYxjb/Wraxzb+WbWzzb2Eb29jm38o2trHNv4dtbGOb/wi2sY1tbPOfwTa2sY1t/qvZxja2sY1tbPO/kW1sYxvb2MY2trHNVVddddVVV1111f8yVK666qqrrrrqqv/zbAMgiX8N2wBI4l/DNveTxL+Wbe4niX8L2wBI4t/DNveTxH8E2zyQJP6j2ea5SeK/mm2emyT+N7PNCyKJ/602NjYAuO+++27lqquuuuqqq676v4TKVVddddVVV131f8p99913K8Dm5ibPzTYAkvjXsA2AJP61bAMgiX8L2wBI4t/CNveTxL+HbR5IEv8RbPNAkvjPYJsHksR/B9s8P5L43842L4gk/ifb2NgA4OzZs7dy1VVXXXXVVVf9X0Llqquuuuqqq676f8c2AJL417ANgCT+tWxzP0n8a9nmfpL4t7DN/STx72Wb+0niP4pt7ieJ/yy2eW6S+O9im+dHEv8X2Ob5kcT/BBsbG1x11VVXXXXVVf8nUbnqqquuuuqqq/5POXv27DMAtra2+JfYBkAS/xq2uZ8k/rVsAyCJfwvbAEji38o295PEv5dt7ieJ/yi2eSBJ/GeyzXOTxH8n2zw/kvi/wDbPjyT+O9x33323ctVVV1111VVX/V9C5aqrrrrqqquu+j/lvvvuuxVgc3OTF5VtACTxr2UbAEn8a9kGQBL/Fra5nyT+rWxzP0n8e9nmgSTxH8U2DySJ/2y2eSBJ/E9gm+cmif8rbPNAkrjqqquuuuqqq676N6By1VVXXXXVVVdd9Uy2AZDEv5ZtACTxr2Wb+0ni38I295PEv5Vt7ieJ/wi2uZ8k/iPZ5oEk8Z/NNs9NEv8T2Oa5SeL/Ats8N0n8R9nY2ADgvvvuu5Wrrrrqqquuuur/EipXXXXVVVddddX/KWfPnr0VYHNzE9sASOJfwzYAkvjXss39JPGvZRsASfxb2eZ+kvi3ss39JPEfwTYPJIn/SLZ5IEn8V7DNc5PE/wS2eW6S+L/ANveTxL/H5uYmAGfPnn0GV1111VVXXXXV/yVUrrrqqquuuuqq//NsAyCJfw3b3E8S/1q2AZDEv5Zt7ieJfyvbAEji38M2DySJ/wi2uZ8k/qPZ5oEk8V/FNg8kif8pbPPcJPG/mW3uJ4mrrrrqqquuuuqqZ6Jy1VVXXXXVVVf9n3LffffdCrC1tcVzsw2AJP61bAMgiX8t2wBI4t/CNveTxL+Fbe4niX8v29xPEv8RbPNAkviPZpsHksR/Fds8N0n8T2GbB5LE/1a2uZ8kXhQbGxtcddVVV1111VX/J1G56qqrrrrqqqv+37ENgCT+tWwDIIl/LdvcTxL/FrYBkMS/lW3uJ4l/L9vcTxL/UWxzP0n8Z7DNA0niv5JtHkgS/1PY5oEk8b+RbQAk8aK47777buWqq6666qqrrvq/hOCqq6666qqrrvo/57777rsVYHNzkxfGNrb5t7CNbf6tbGObfyvb2MY2/x62sY1t/iPYxja2+Y9kG9vYxjb/WWxjG9vY5r+abWxjG9vY5n8K29jGNrb538Y2tnlBNjY2ADh79uytXHXVVVddddVV/5cQXHXVVVddddVV/+ecPXv2VoCtrS1eFLaxzb+FbWzzb2Ub2/x72MY2/162sY1t/iPYxja2+Y9mG9vY5j+TbWxjG9v8d7CNbWxjm/8pbGMb29jmfwvb2Oaqq6666qqrrvp/g8pVV1111VVXXXXVM9kGQBL/Wra5nyT+tWxzP0n8W9jmfpL497DN/STx72Wb+0niP5JtHkgS/1ls80CS+K9mmweSxP8EtrmfJP6ns40k7rexsQHAfffddytXXXXVVVddddX/JVSuuuqqq6666qr/szY3N/m3sA2AJP4tbAMgiX8L2wBI4t/KNveTxL+Hbe4niX8v2zyQJP4j2eaBJPGfxTYPJIn/ara5nyT+J7ANgCT+J7MNgCSuuuqqq6666qr/swiuuuqqq6666qr/c+67775beSbb2Obfwja2sc2/hW1s829lG9vY5t/DNrb5j2Ab29jmP4ptbGOb/wy2sY1t/rPZxja2sc1/NdvYxja2+e9mG9vY5n+yxWIBwH333XcrV1111VVXXXXV/zVUrrrqqquuuuqq/3Puu+++WwE2Nze5n20AJPFvYRsASfxr2eZ+kvi3sA2AJP6tbHM/Sfx72eZ+kviPYJv7SeI/mm0eSBL/mWzzQJL4r2Sb+0niv5NtACTxP83GxgYAZ8+evZWrrrrqqquuuur/GipXXXXVVVddddX/K7YBkMS/hW0AJPFvYRsASfxb2OZ+kvi3ss39JPHvZZv7SeI/gm3uJ4n/DLa5nyT+s9nmfpL4r2Sb+0niv4tt7ieJq6666qqrrrrqqv9kVK666qqrrrrqqv9zzp49+wyAra0tXhDbAEji38I2AJL4t7ANgCT+rWwDIIl/D9vcTxL/XrYBkMR/FNs8kCT+o9nmfpL4z2ab+0niv5Jt7ieJ/y62kcR/t83NTQDuu+++W7nqqquuuuqqq/6voXLVVVddddVVV/2fc999990KsLW1xb/ENgCS+LewDYAk/i1sAyCJfyvb3E8S/x62AZDEv5dt7ieJ/0i2uZ8k/qPZ5oEk8Z/JNg8kif8qtrmfJP6r2QZAElddddVVV1111VX/CahcddVVV1111VVXAbYBkMS/hW0AJPFvYZv7SeLfyjYAkvj3sM39JPHvZZv7SeI/km3uJ4n/DLa5nyT+s9nmfpL4r2IbAEn8V7MNgCT+q21sbABw33333cpVV1111VVXXfV/DZWrrrrqqquuuur/nLNnz94KsLm5yb+WbQAk8W9hm/tJ4t/CNgCS+Leyzf0k8e9hm/tJ4t/LNveTxH8k29xPEv8ZbHM/Sfxns839JPFfwTb3k8R/JdtI4r/SxsYGAGfPnn0GV1111VVXXXXV/zVUrrrqqquuuuqq/9NsI4l/LdsASOLfyjYAkvi3sM39JPFvZRsASfx72QZAEv8RbHM/SfxHss39JPGfwTb3k8R/NtvcTxL/FWwDIIn/KrYBkMRVV1111VVXXXXVvxOVq6666qqrrrrq/5z77rvvVoCtrS0AbAMgiX8t2wBI4t/KNgCS+LeyDYAk/q1scz9J/HvY5n6S+I9gm/tJ4j+Sbe4nif8MtrmfJP6z2QZAEv8VbAMgif8qtpHEVVddddVVV1111b8Dlauuuuqqq6666v8N2wBI4l/LNgCS+LeyDYAk/q1sAyCJfw/bAEji38s295PEfwTb3E8S/5Fscz9J/Gewzf0k8Z/JNveTxH822wBI4r+CbSTxn2ljYwOA++6771auuuqqq6666qr/awiuuuqqq6666qr/k+67775bAba2tnhutrHNv4VtbPPvYRvb2Obfyja2sc2/h21sY5v/CLaxjW3+o9jGNrb5j2Yb29jmP4ttbGOb/2y2sc1/BdvY5r+Cbf4zbW5uAnD27Nlbueqqq6666qqr/q8huOqqq6666qqr/k86e/bsrQCbm5u8ILaxzb+FbWzz72Ub2/x72MY2/162sY1t/iPYxjb/kWxjG9v8R7ONbWzzn8U2trHNfybb2MY2/9ls81/BNlddddVVV1111VX/BlSuuuqqq6666qr/92wDIIl/LdsASOLfwzYAkvi3ss39JPHvYRsASfx72eZ+kviPYpv7SeI/km3uJ4n/DLa5nyT+s9gGQBL/WWwDIIn/jTY2NgC47777buWqq6666qqrrvq/hspVV1111VVXXXXVM9kGQBL/Wra5nyT+rWwDIIl/D9sASOLfwzb3k8S/l23uJ4n/KLa5nyT+I9nmfpL4z2AbAEn8Z7ENgCT+s9hGEv9ZbCOJq6666qqrrrrqqn8Fgquuuuqqq6666v+k++6771aAra0t/rVsY5t/K9vY5t/DNraxzb+HbWzzH8E2tvmPYhvb2OY/km1s85/BNrb5z2Ib2/xnso1t/rPY5j+Tbf4jbWxsAHDffffdylVXXXXVVVdd9X8Rlauuuuqqq6666v+k++6771aAzc1N/q1sAyCJfwvbAEji38M2AJL4t7LN/STx72Gb+0niP4JtACTxH8U295PEfyTb3E8S/9Fscz9J/GewjST+M9hGEv8bbGxsAHD27Nlbueqqq6666qqr/i+ictVVV1111VVX/Z9nGwBJ/FvYBkAS/xa2AZDEv4dtACTx72EbAEn8e9kGQBL/EWxzP0n8R7HN/STxH8k2AJL4z2AbAEn8R7MNgCT+o9kGQBL/0Wwjiauuuuqqq6666qoXAZWrrrrqqquuuur/pLNnzz4DYGtri/vZBkAS/xa2AZDEv4VtACTx72EbAEn8e9jmfpL497DN/STxH8E2AJL4j2QbAEn8R7LN/STxH802AJL4j2YbAEn8R7ONJP6n2tzcBOC+++67lauuuuqqq6666v8iKlddddVVV1111f9J9913360AW1tbPDfbAEji38I2AJL4t7ANgCT+PWxzP0n8e9gGQBL/XrYBkMR/BNvcTxL/UWxzP0n8R7INgCT+o9kGQBL/0Wwjiauuuuqqq6666qr/Qwiuuuqqq6666qr/t2xjm38r29jm38o2tvmPYBvb/HvZxjb/EWxjG9v8R7GNbWzzH8k2tvmPZhvb/GewjW3+o9nmP5pt/qPZ5j/CxsYGAPfdd9+tXHXVVVddddVV/xdRueqqq6666qqr/k86e/bsrQBbW1v8S2wDIIl/C9sASOLfwjb3k8S/h20AJPHvYZv7SeLfyzYAkviPYhsASfxHsc39JPEfxTb3k8R/JNtI4j+SbQAk8R/FNpL4n2ZjYwOAs2fPPoOrrrrqqquuuur/IipXXXXVVVddddVVz2QbAEn8W9gGQBL/VrYBkMS/h23uJ4l/D9sASOLfyzb3k8R/BNsASOI/km0AJPEfyTYAkviPYhsASfxHso0k/qPYRhJXXXXVVVddddVV/4WoXHXVVVddddVV/6dtbW3xr2UbSfxb2QZAEv9WtgGQxL+XbQAk8e9hm/tJ4t/LNgCS+I9gm/tJ4j+KbQAk8R/JNgCS+I9iGwBJ/EexjSSuuuqqq6666qqr/pciuOqqq6666qqr/k+67777buXfwTa2+fewjW3+PWxjm/8ItrHNfwTb2OY/gm1sY5v/KLaxzX8k29jmP5ptbPMfyTb/kWzzH8U2/5NsbGwAcN99993KVVddddVVV131fxHBVVddddVVV131f9Z99913K8Dm5ib/Vraxzb+HbWzz72Eb2/xHsI1t/iPYxjb/UWxjm/8otrHNfyTb2OY/mm3+I9nGNv9RbPMfxTb/EWzz77W5uQnA2bNnb+Wqq6666qqrrvq/iOCqq6666qqrrvo/6+zZs7cCbG1tYRvb/FvZxjb/Hraxzb+HbWzzH8E2trHNv5dtbGOb/wi2sc1/FNvYxjb/UWxjm/9ItrHNfyTb/EexzVVXXXXVVVddddX/MgRXXXXVVVddddX/K7axzb+VbWzz72Eb2/x72MY2tvmPYBvb/EewjW3+I9jGNrb5j2Ib2/xHsY1t/iPZxjb/UWzzH8U2/xFs8z/BxsYGAPfdd9+tXHXVVVddddVV/xcRXHXVVVddddVV/y/Zxjb/Vraxzb+HbWzz72Ub2/xHsI1t/iPYxjb/UWxjm/8otrHNfxTb2OY/km3+o9jmP4ptrrrqqquuuuqqq/6XILjqqquuuuqqq/7Puu+++24F2Nra4gWxjW3+rWxjm38P29jm38s2tvmPYBvb/EewjW3+o9jGNv9RbGOb/yi2sc1/FNvY5j+CbWxz1RUbGxsA3Hfffbdy1VVXXXXVVVf9X0Vw1VVXXXXVVVf9n3XffffdCrC1tcW/xDa2+beyjW3+PWxjm38v29jmP4JtbPMfwTa2+Y9iG9v8R7GNbf6j2MY2/1Fs8x/FNv9etvn3ss1/p83NTQDOnj17K1ddddVVV1111f9VVK666qqrrrrqqqsewDYAkvi3sA2AJP6tbAMgiX8P2wBI4t/LNveTxL+Hbe4niX8v2wBI4j+CbQAk8R/BNgCS+PeyDYAk/r1sI4l/D9tI4qqrrrrqqquuuup/MIKrrrrqqquuuur/rLNnzz4DYGtri38t29jm38o2tvn3sI1t/r1sY5v/KLaxzX8E29jmP4JtbPMfxTa2+Y9im/8otvmPYJv/zzY2NgC47777buWqq6666qqrrvq/iuCqq6666qqrrvo/67777rsVYGtri38r2/x72MY2/x62sc2/l21s8x/FNrb5j2Ab2/xHsI1t/qPYxjb/EWxjm/8ItvmPYJt/D9v8e9jm30oS/1aSuOqqq6666qqr/l8guOqqq6666qqr/l+wzb+VbWzz72Eb2/x72MY2/162sc1/FNvY5j+CbWzzH8E2tvmPYpv/KLb5j2Cbq/7tNjY2ALjvvvtu5aqrrrrqqquu+r+K4Kqrrrrqqquu+j/r7NmztwJsbW0BYBvb/FvZxjb/Hraxzb+HbWzz72Ub2/xHsY1t/iPYxjb/EWxjm/8ItrHNfwTb2Obfyzb/Xrb597DN/yaSANjc3ATg7Nmzz+Cqq6666qqrrvq/iuCqq6666qqrrvp/xza2+beyjW3+PWxjm38P29jm38s2tvmPYhvb/EewjW3+I9jGNv8RbGOb/wi2+feyzb+Xba666qqrrrrqqqv+DyK46qqrrrrqqqv+37LNv4dtbPPvYRvb/HvYxjb/XraxzX8U29jmP4JtbPMfwTa2+Y9gm/8Itvn3ss2/l23+rWzzv4Ekrrrqqquuuuqq/1cIrrrqqquuuuqq/7Puu+++WwG2trZ4QWxjm38P29jm38M2tvn3sI1t/r1sY5v/KLaxzX8E29jmP4JtbPPvZRvb/HvZxjb/Hra56kW3sbEBwH333XcrV1111VVXXXXV/1UEV1111VVXXXXV/2n33XffrQBbW1u8MLaxzb+HbWzz72Eb2/x72MY2/162sc1/FNvY5j+CbWzzH8E2/xFs8x/BNv8etvn3sM2/lW3+N9nY2ADg7Nmzt3LVVVddddVVV/1fRXDVVVddddVVV/2fdvbs2VsBtra2eFHYxjb/Hraxzb+HbWzz72Eb2/x72cY2/1FsY5v/CLaxzb+XbWzz72Ub2/x72ebfwzZXPS9JXHXVVVddddVV/+8QXHXVVVddddVVVz0ftrHNv4dtbPPvYRvb/HvYxjb/XraxzX8U29jmP4Jt/iPY5j+Cbf69bPPvYZt/K9v8V7LNv5Yk/r02NjYAuO+++27lqquuuuqqq676v4rgqquuuuqqq6666oWwjW3+PWzz72Ub2/x72MY2/162sc1/FNvY5t/LNrb597KNbf69bPPvZZt/D9v8W9nm/xJJXHXVVVddddVV/y8RXHXVVVddddVV/6fdd999twJsbW3x72Gbfw/b2Obfyza2+fewjW3+vWxjm/8otrHNv5dtbPPvZRvb/HvYxjb/Hrb597DNfyXb/G+wsbEBwNmzZ5/BVVddddVVV131fxnBVVddddVVV131f9p99913K8DW1ha2sc2/lW1s8+9hG9v8e9nm38s2tvn3so1t/qPY5j+Cbf4j2Obfyzb/Hra56t9OEs9tY2MDgPvuu+9Wrrrqqquuuuqq/8sIrrrqqquuuuqq/3ds8+9hG9v8e9jGNv8etrHNv5dtbPPvZRvb/EewjW3+vWxjm38v2/x72ebfwzb/Vrb5t7DN/0SSuOqqq6666qqrrnoREVx11VVXXXXVVf+nnT179hkAW1tbPJBtbPPvYRvb/HvYxjb/Hraxzb+XbWzz72Ub2/xHsI1t/r1s8+9lG9v8e9jm38M2/1a2uerZNjY2ALjvvvtu5aqrrrrqqquu+r+M4Kqrrrrqqquu+j/tvvvuuxVga2uL58c2tvn3sI1t/j1sY5t/D9vY5t/LNrb597LNfxTb/HvZxjb/Xrb597DNv4dt/ivZ5j+bJP6zSOKqq6666qqrrvp/jeCqq6666qqrrroKsI1t/j1s8+9lm38v29jm38s2/162sc1/BNvY5t/LNv9etvn3sM2/h23+LWzzX8E2/9NtbGwAcN999z2dq6666qqrrrrq/zKCq6666qqrrrrq/7SzZ8/eCrC9vc2Lwjb/Hraxzb+HbWzz72Ub2/x72MY2/162sc1/BNvY5t/DNrb597CNbf6tbHPVfy5JvCCbm5tcddVVV1111VX/LxBcddVVV1111VVXPRfb2Obfwza2+fewjW3+vWzz72Ub2/x72cY2/xFs8+9lm38v2/xb2ebfyjb/Frb517LN/xSS+I909uzZZ3DVVVddddVVV/1fRnDVVVddddVVV131AtjGNv8etrHNv4dtbPPvYRvb/HvZxjb/Xrb5j2Ab2/x72MY2/x62+beyzb+Vba56/iRx1VVXXXXVVVddBRBcddVVV1111VX/p9133323AmxtbfFvZZt/L9v8e9nGNv8etrHNv5dt/r1sY5v/CLb597LNv4dt/q1s81/JNv/fbWxsAHD27Nlbueqqq6666qqr/i8juOqqq6666qqr/s+77777bgXY2tri38o2tvn3sI1t/r1s8+9lG9v8e9jGNv9etvmPYBvb/HvY5t/DNv9Wtvm3sM3/F5L4j7KxsQHAfffddytXXXXVVVddddX/ZQRXXXXVVVddddX/G1tbW9jm38M2tvn3sI1t/j1sY5t/L9v8e9nGNv8etrHNfwTb/HvY5t/DNv9Wtvm3sM1/Ntv8byGJq6666qqrrrrqqmciuOqqq6666qqr/s87e/bsrTyAbWzz72Eb2/x72MY2/x62sc2/h21s8+9lm38v29jm38s2/x62sc2/lW3+rWzzX8E2/59tbGwAcN99993KVVddddVVV131fxnBVVddddVVV131/5ZtbPPvYZt/L9v8e9nm38s2tvn3sI1t/r1s8+9lG9v8e9jm38o2/5VscxVI4qqrrrrqqquuuuoBCK666qqrrrrqqv/z7rvvvlsBtra2eH5s8+9hG9v8e9jGNv8etrHNv5dt/r1sY5t/D9v8R7DNv4dt/q1s829hm/8KtvnvJokXhST+o2xubgJw33333cpVV1111VVXXfV/HcFVV1111VVXXfV/3n333XcrwNbWFi+IbWzz72Eb2/x72MY2/x62sc2/h21s8+9lm38P29jm38s2/x62+beyzb+Fbf61bPP/mSReFBsbGwCcPXv2Vq666qqrrrrqqv/rCK666qqrrrrqqqsewDa2+fewzb+Xbf69bPPvZRvb/HvYxjb/Hrb597LNv4dt/q1sc9X/DJK46qqrrrrqqqv+XyG46qqrrrrqqqv+zzt79uwzALa3t3lR2ebfwza2+fewjW3+PWxjm38v2/x72ebfwza2+fewjW3+rWzzX8k2/1q2+c9im/8OkviPIAmAjY0NAO67775bueqqq6666qqr/q8juOqqq6666qqr/s+77777bgXY2triX8M2tvn3sI1t/j1sY5t/D9vY5t/DNrb597CNbf49bPPvZZt/K9v8W9jmfyLb/F8giauuuuqqq6666qrng+Cqq6666qqrrrrqX2Cbfy/b/HvZ5t/LNv9etvn3ss2/h23+vWzzb2Wbfwvb/GvZ5qp/P0ncb2NjA4D77rvvVq666qqrrrrqqv/rCK666qqrrrrqqv83tre3+beyjW3+PWxjm38P29jm38M2tvn3sI1t/j1s8+9hm38v2/xb2ebfwjb/Wrb517DN/waS+I8giauuuuqqq6666qoXgOCqq6666qqrrvo/7+zZs7cC2MY2/x62sc2/h21s8+9hm38v2/x72ebfwza2+beyjW3+PWzzb2Wbq/5zSeLfSxIPtLGxAcDZs2efwVVXXXXVVVdd9X8dwVVXXXXVVVdd9f+ObWzz72Gbfy/b/HvYxjb/Hraxzb+HbWzz72Gbfw/b/HvY5r+Sbf61bPOfxTZXXXXVVVddddVV/0cRXHXVVVddddVV/+fdd999twJsb2/zQLb597CNbf49bGObfw/b2Obfwzb/Xrb597DNv4dt/j1s829hm38L2/xnss3/B5J4YSTx3DY2NgC47777buWqq6666qqrrvq/juCqq6666qqrrvp/4b777rsVYGtriweyjW3+PWzz72Wbfy/b/HvYxjb/Hrb597CNbf6tbPPvYZt/C9v8V7DN/yeS+M+wsbEBwNmzZ2/lqquuuuqqq676v47gqquuuuqqq666CrDNv4dtbPPvYRvb/HvYxjb/Hrb597CNbf49bPNvZZt/D9v8W9jmX8s2V/3bSeKFkcRVV1111VVXXfX/HsFV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M9nmP4NtXhS2ueo/hiT+PSTxbyGJ/0iS+LeQxL+GJO63WCwAuO+++27lqquuuuqqq676/47gqquuuuqqq6666t/BNv9atvnXsM1V//tJ4vmRxP9kkvjXkMSLShIvCkncTxL3k8TzM5/PATh79uytXHXVVVddddVV/98RXHXVVVddddVVVwH33XffrQDb29v8a9nmfxLbvKhs89/BNlf995PEv5YkHkgSLypJvCCSuOqqq6666qqrrvpPQHDVVVddddVVV10F3HfffbcCbG9v81/BNv8atvnvZpv/Sra56jlJ4v8DSfxbSWKxWHDVVVddddVVV131TARXXXXVVVddddVVz8U2/1q2+Z/ENi8q2/xHss1V//NI4l8iif9Ikvj3ksT9JHE/SdxPEs/PfffddytXXXXVVVddddX/dwRXXXXVVVddddVVz4dt/rVs869hm38N21z1P5sk/qtJ4rlJ4j+CJP41JPGiksRVV1111VVXXXXVfwGCq6666qqrrrrqKuDs2bO3Amxvb/NfyTb/WWzzH802V/3/JYkHksSLShIviCT+I0hisVgAcPbs2Wdw1VVXXXXVVVddBQRXXXXVVVddddVVwH333XcrwM7ODvezzb+Wbf4z2eY/g23+q9nm38s2/xdJ4j+bJP4zSeLfQhL3k8T9JHE/SdxPEg80n88BuO+++27lqquuuuqqq666Cgiuuuqqq6666qqrXgjb/GvZ5l/DNv9ZbPPfwTZX/e8iif8qkvjPslgsALjvvvtu5aqrrrrqqquuugoIrrrqqquuuuqqq4CzZ8/eCrC9vc1zs83/JLb5/8I2/x62+b9CEv9WkvjXksQLI4kHksQLIokXRBL/ESRx1VVXXXXVVVdd9XwQXHXVVVddddVVVwH33XffrQA7Ozv8R7DNv4Zt/rvZ5kVhm6v+Y0ji30MSz00S/xkk8Z9NEveTxP0kcT9J3E8SV1111VVXXXXVVf8Cgquuuuqqq6666qoXgW3+J7HNi8o2V/33ksT/JJL4zySJ/y6LxQKA++677+lcddVVV1111VVXAcFVV1111VVXXXUVcN99990KsL29zQtim38N2/xr2Ob/Ettc9f+DJF5UkviPJon7zedzAM6ePfsMrrrqqquuuuqqq4Dgqquuuuqqq6666j+Rbf41bPOiss2LyjYvCtu8KGzzH8E2V/3nksS/RBIPJIkXRhIvKkm8IJK4nyT+JZK4nySuuuqqq6666qqrXgQEV1111VVXXXXVVf8Ktrnq/zdJ/GeSxP80kvivJIn7SeJFJYnFYgHA2bNnb+Wqq6666qqrrroKCK666qqrrrrqqquAs2fPPgNgZ2eHf4lt/jVs869hmxeVba76v08SLwpJ/HeTxAsiif9oknig+XwOwH333XcrV1111VVXXXXVVUBw1VVXXXXVVVdd9Uz33XffrQDb29v8X2SbF4VtrvqfTxL/FpL4jySJF0QSL4gk/q0kcdVVV1111VVXXfUiIrjqqquuuuqqq656prNnz94KsLOzw7/ENv8atvnXsM2Lyjb/HWzzL7HNv5dt/jeQxL+GJP4nkMQDSeKBJPFAkviPJon7SeJ+krifJK666qqrrrrqqqv+DQiuuuqqq6666qqr/ovY5qqr/itJ4r+SJP67SAJgsVgAcN99993KVVddddVVV111FRBcddVVV1111VVX/RvZ5j+Tbf6j2eZFYZv/Kra56v8+SdxPEv9WkrifJK666qqrrrrqqqv+BQRXXXXVVVddddVVz3TffffdCrC9vc2Lyjb/Grb5z2Cb/69s8z+ZJF5Ukvi3ksS/RBL/kSTxgkjiRSGJ+0nifpK4nyReFPP5HID77rvvVq666qqrrrrqqquuILjqqquuuuqqq656pvvuu+9WgJ2dHf4vs81/FNtc9Z9LEs9NEv8RJPHCSOKBJPE/kSQAFosFAGfPnr2Vq6666qqrrrrqqisIrrrqqquuuuqqq/6dbPOvYZsXlW1eVLb5j2Sb/wi2ueq/niT+tSTxbyWJF0QS/9Ek8dzm8zkA9913361cddVVV1111VVXXUFw1VVXXXXVVVdd9Uxnz559BsD29jb/Wra56qr/TyTxbyGJ+0niXyKJ+0nihZHEVVddddVVV1111XMhuOqqq6666qqrrnqm++6771aAnZ0d/rPZ5kVlm/9otrnqBZPEfyZJ/FeTxH8VSfxrSeJ+knhRSeKqq6666qqrrrrqhSC46qqrrrrqqquuej5s869lm/9utrnq/x9J/GtJ4oWRxANJ4n8KSTw/8/kcgPvuu+9Wrrrqqquuuuqqq64guOqqq6666qqrrnqms2fP3gqwvb3NfwXbvKhs89/BNv8S2/x72eb/O0m8KCTxn0ES/1aSeEEkcT9J/FtJ4oWRxGKxAODs2bPP4KqrrrrqqquuuuoKgquuuuqqq6666qoXwDb/Wrb572abq/5rSeI/gyT+LSTxn0kSL4gkXhSSuJ8k7ieJ+0nihZHEVVddddVVV1111b+A4KqrrrrqqquuuuqFsM1/Jtu8qGzzH8k2/1Vs8+9hm/8JJPGvIYn/CyTxP4UkXpD5fA7AfffddytXXXXVVVddddVVVxBcddVVV1111VVXPdN99913K8DOzg7/Hra56qr/KpL4l0jigSTxwkjiRSWJF0QS/xEk8cJIAmCxWHDVVVddddVVV131XAiuuuqqq6666qqrHuC+++67FWBnZ4f72eY/k23+o9nmP4pt/iW2uep/L0n8Z5PE/SRxP0ncTxL3k8S/1dmzZ2/lqquuuuqqq6666gqCq6666qqrrrrqqgc4e/bsrQDb29s8kG3+NWzzn8E2/5Fsc9V/LUn8W0niv5skXhBJ/FeRxFVXXXXVVVddddWLgOCqq6666qqrrrrqP4ltXlS2uer/L0k8N0n8W0jiP5Ik/qeQxAszn88BuO+++27lqquuuuqqq6666gqCq6666qqrrrrqqheRbf4nsM2LwjZXXSWJfw1JvKgk8YJI4n6S+NeQxP0k8cJI4qqrrrrqqquuuuqFILjqqquuuuqqq656gPvuu+9WgJ2dHf4j2OZFZZv/Drb5l9jm38s2V/3HksS/liQeSBL/ESTxopDE/SRxP0m8qCTx3BaLBQD33XffrVx11VVXXXXVVVc9G8FVV1111VVXXXXVA9x33323Amxvb/P82Oaq/xy2uep/Nkn8d5HECzOfzwE4e/bsrVx11VVXXXXVVVc9G8FVV1111VVXXXXVfzLb/EezzYvCNv9VbHPVs0niP5Ik/iWS+I8kiRdEEi+IJP4jSOKFkcT9FosFAPfdd9+tXHXVVVddddVVVz0bwVVXXXXVVVddddUDnD179hkAOzs7vCC2+c9im6v+a0jiP4Ik/qeSxL+GJP6jSeJ+krifJO4niftJ4oWRxFVXXXXVVVddddW/AsFVV1111VVXXXXVA9x33323Auzs7PDC2OZfwzb/0WzzH8U2/xLbXPXvI4nnJonnJon/DJJ4IEm8qCTxgkjiP5MkXhhJXHXVVVddddVVV70ABFddddVVV1111VX/w9jmP5Jtrvr3k8T/JJL4v0wSL4wkHmg+nwNw33333cpVV1111VVXXXXVsxFcddVVV1111VVXPcDZs2dvBdje3uZfYpt/Ddtc9T+fJK4CSbwgknhBJHE/SfxrSOLfaj6fA3D27NlncNVVV1111VVXXfVsBFddddVVV1111VX/A9nmRWGbq/7vk8S/RBL/HpL4t5DEi0IS95PE/STxopLEc5PEVVddddVVV1111QtBcNVVV1111VVXXfXvYJv/DWzzL7HNv5dtXhjbXPVfQxIPJIkHksSLShL/XSTxopjP5wDcd999t3LVVVddddVVV131bARXXXXVVVddddVVD3DffffdCrCzs8N/Btv8b2abq/5lkvi3ksT/VpL4t5LE/STxwkjiuUniqquuuuqqq6666vkguOqqq6666qqrrnou9913360AOzs7vChs85/BNi8K21z1P58knpsk/i0k8Z9JEi+IJF4UkrifJO4niftJ4kUliecmifvN53MAzp49eytXXXXVVVddddVVz0Zw1VVXXXXVVVdd9QJsb2/zn8E2V/3fIIn/CSTx7yGJfwtJ/GeSxFVXXXXVVVddddW/E8FVV1111VVXXXXVczl79uyt/CvZ5j+Dbf6j2OZfYpur/meRxL+WJB5IEg8kiReVJP4rSeKFkcRzk8R8Pgfgvvvuu5WrrrrqqquuuuqqZyO46qqrrrrqqquu+m9gm/9Itvm/zjZX/eeTxAsiiRdEEveTxL9EEveTxAsjiauuuuqqq6666qp/I4Krrrrqqquuuuqq53LffffdCrC9vY1tXlS2uQps829lm//PJPEvkcT/JpK4nyT+o0jifvP5HID77rvvVq666qqrrrrqqqueE8FVV1111VVXXXXVc7nvvvtuBdjZ2eE/k21eFLb5j2Kbfy/bXPV/hyReEEm8IJL4zySJ5yaJ5yaJ+XwOwNmzZ2/lqquuuuqqq6666jkRXHXVVVddddVVV/0LbPOiss1/F9v8R7DNVc9JEi8qSTw3STw3SfxHkMQDSeKBJPFAkviPJol/K0ncTxL/FvP5HID77rvvVq666qqrrrrqqqueE5Wrrrrqqquuuuqq53L27NlnAOzs7HDVVf+dJPFfSRIviCReFJK4nyTuJ4n7SeJFJYnnJomrrrrqqquuuuqqFxHBVVddddVVV1111XO57777bgXY2dnhfrZ5UdnmRWWbF4Vt/q+wzVX/u0niP5Mkrrrqqquuuuqqq/6DEFx11VVX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zQtim38t2zw/tvm/ShL/X0ni30oSL4gkXhBJAEjiqquuuuqqq6666t+A4KqrrrrqqquuuupFcN99990KsLOzw7+Xbf6/ss3/NZJ4IEn8Z5PEfxVJvDCSeG6S+LeQxL9kPp8DcN99993KVVddddVVV1111b+M4KqrrrrqqquuuupfwTb/Etv8X2Obq/5nksR/NEm8MJL4t5LEv0QSL8hsNgPg7Nmzt3LVVVddddVVV131LyO46qqrrrrqqquuehHcd999twLs7OzwH8E2L4xtrvq/TxIviCT+tSTxbyWJfw9JPDdJvCCSuOqqq6666qqrrvovQHDVVVddddVVV131r2Sbf4lt/jPZ5oWxzQtim6v+75PE/SRxP0ncTxIvKkn8W0niBZHECyIJAEncbz6fA3DffffdylVXXXXVVVddddW/jOCqq6666qqrrrrqRXD27NlnABw7doz/y2zz38E2/xNI4qoXnSSemyT+LSTxL5HEVVddddVVV1111b8SwVVXXXXVVVddddWL4L777rsVYGdnBwDb/HvZ5oWxzVX/t0ji30IS/x0k8R9JEv8SSbwws9kMgPvuu+9Wrrrqqquuuuqqq/5lBFddddVVV1111VX/SWzzn8k2/xPY5vmxzVUvOkn8TyCJF0YSz00Sz00SL4gk/q1msxlXXXXVVVddddVV/woEV1111VVXXXXVVS+Cs2fP3gqws7PD/xa2eUFs869lm6v++0niP5ok/jtI4gWRBIAknp+zZ88+g6uuuuqqq6666qp/GcFVV1111VVXXXXVv5Ft/iW2eWFs88LY5qqrXhBJ/GtI4t9CEv9WkviPIAkASVx11VVXXXXVVVf9KxBcddVVV1111VVXvQjuu+++WwF2dnb4n8Q2/9Fs85/JNv9fSOK/iiTuJ4n7SeL5kcS/hySemyReEEm8IJIAkMS/ZDabAXDffffdylVXXXXVVVddddW/jOCqq6666qqrrrrq38E2/162ueqqB5LEfzdJ/E80m80AOHv27K1cddVVV1111VVX/csIrrrqqquuuuqqq15E9913360AOzs7/GvY5t/DNv9WtnlBbHPVCyeJ/yyS+N9GEs9NEs9NEi+IJP4lkgCQxFVXXXXVVVddddW/E8FVV1111VVXXXXVi+js2bO3Auzs7PBAtvn/wjbPj22u+t9PEv+RJPGCSOJFJQkAScxmMwDuu+++W7nqqquuuuqqq676lxFcddVVV1111VVX/RewzQtjm38r2/xfZZvnZpv/qSTxH00S/5kk8cJI4kUhiX8LSVx11VVXXXXVVVf9JyK46qqrrrrqqquuehHdd999twLs7Ozw3Gzzn8k2/1a2+deyzX8E21z1H0cS/xNI4l9DEv8SSfxLZrMZAPfdd9+tXHXVVVddddVVV71oCK666qqrrrrqqquu+h/BNlf9x5LE/SRxP0m8MJL4zyCJf4kkXpDZbAbA2bNnb+Wqq6666qqrrrrqRUNw1VVXXXXVVVdd9SK67777bgXY2dnh38I2L4xt/q1s829hm/8LbPO/mST+tSRxP0ncTxL/GSTx3CTx3CTxH0ESAJIAkMRVV1111VVXXXXVvwHBVVddddVVV1111X8Q2/xnss3/Fbb5v0ASLypJ/H8iiRdEEv8Ws9kMgPvuu+9Wrrrqqquuuuqqq140BFddddVVV1111VUvorNnzz4D4NixY/xb2eaFsc1/Btv8a9nm+bHN82Obq/73ksR/NUlcddVVV1111VVX/ScjuOqqq6666qqrrnoR3XfffbcC7Ozs8ILY5r+Lba666j+SJJ6bJJ6bJF4QSfxLJPGimM1mANx33323ctVVV1111VVXXfWiIbjqqquuuuqqq676X8Q2/9Fsc9X/HJL4ryKJ/yqS+JdIAkASV1111VVXXXXVVf9BCK666qqrrrrqqqteRGfPnr0VYGdnhxfGNi+MbV4Y2/xfYpur/n+QxH8kSQBIAmA+nwNw9uzZZ3DVVVddddVVV131oiG46qqrrrrqqquu+n/CNlf9/ySJ+0nihZHEi0IS/xaSuOqqq6666qqrrvovRHDVVVddddVVV131IrrvvvtuBdjZ2eFfYpsXxjb/VrZ5QWzzH8k2z49t/qezzf92kvi3ksR/FEn8a0jiXyKJf63ZbAbAfffddytXXXXVVVddddVVLxqCq6666qqrrrrqqn8D2/xnss1/Jdv8R7DNv4dtnpttrvq/SxIvqtlsBsDZs2dv5aqrrrrqqquuuupFQ3DVVVddddVVV131r3DffffdCrCzs8NV/z62uepFJ4n7SeJ+krifJP4tJPFvJYkXRBIvKklcddVVV1111VVX/ScguOqqq6666qqrrvpXuO+++24F2NnZ4V9imxfGNv9WtnlBbPOC2Ob/Atv8byaJ/+kk8dwk8W8hiReVJAAkASAJAEnMZjMA7rvvvlu56qqrrrrqqquuetFQueqqq6666qqrrvo3eJVXeRXuuOMO/iWS+PeQxL+FJP61JPGvIYl/DUm8KCTxopDEv0QSL4wkXhhJvDCSeGEk8fxI4gWRxPMjiedHEs+PJJ4fSTw3STw3STw3STw3STw3STyQJJ6bJB5IEg8kiQeaz+dcddVVV1111VVX/RtQueqqq6666qqrrvpX+NEf/dHPueaaax588803P/jmm2/mqquu+q/19V//9e/DVVddddVVV1111YsOPehBD+Kqq6666qqrrrrqX+PFXuzFXvvFXuzFXourrrrqv9TZs2ef8Vu/9VvfzVVXXXXVVVddddWLDj3oQQ/iqquuuuqqq6666qqrrrrqqquuuuqqq676P4nKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8V/wjJ/RBQDxGi4QAAAABJRU5ErkJggg==) @@ -100,7 +108,12 @@ sweepPath = startProfileAt([0, 0], sketch002) parts = sweep([rectangleSketch, circleSketch], path = sweepPath) // Scale the sweep. -scale(parts, scale = [1.0, 1.0, 0.5]) +scale( + parts, + x = 1.0, + y = 1.0, + z = 0.5, +) ``` ![Rendered example of scale 2](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAADPfd1WAAEgoUlEQVR4Ae3AA6AkWZbG8f937o3IzKdyS2Oubdu2bdu2bdu2bWmMnpZKr54yMyLu+Xa3anqmhztr1a8+6EEP4qqrrrrqqquuuuqqq6666qqrrrrqqquu+j+JylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVS/AT/zET5hnWq/X973ru77rtVx11VVXXXXVVVdd9b8JwVVXXXXVVVddddVVVz0fP/ETP2EeYDabXfPiL/7i13DVVVddddVVV1111f8mBFddddVVV1111VVXXfUiesd3fMcf4aqrrrrqqquuuuqq/02oXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqhfRZ37mZ74OV1111VVXXXXVVVf9b0Jw1VVXXXXVVVddddVVz8fbvd3b6R/+4R9+kGd6u7d7O3HVVVddddVVV1111f82BFddddVVV1111VVXXfUCfOZnfua7cdVVV1111VVXXXXV/2YEV1111VVXXXXVVVdd9ULcd999twJcc801D+aqq6666qqrrrrqqv9tqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XEVx11VVXXXXVVVddddULcfbs2VsBzpw582Cuuuqqq6666qqrrvrfhspVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KoKrrrrqqquuuuqqq656Ie67775bAa655poHc9VVV1111VVXXXXV/zZUrrrqqquuuuqqq6666oW47777bgU4c+bMg7jqqquuuuqqq6666n8bKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddULcfbs2WcAXHPNNQ/mqquuuuqqq6666qr/bahcddVVV1111VVXXXXVC3HffffdCnDNNdc8mKuuuuqqq6666qqr/rehctVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV70QZ8+evRXgzJkzD+aqq6666qqrrrrqqv9tqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qoX4r777rsV4JprrnkwV1111VVXXXXVVVf9b0Plqquuuuqqq6666qqrrrrqqquuuuqqq676v4rgqquuuuqqq6666qqr/gX33XffrQDXXHPNg7nqqquuuuqqq6666n8TKlddddVVV1111VVXXXXVVVddddVVV1111f9VBFddddVVV1111VVXXfUvOHv27K0AZ86ceTBXXXXVVVddddVVV/1vQuWqq6666qqrrrrqqquuuuqqq6666qqrrvq/iuCqq6666qqrrrrqqqv+Bffdd9+tANdcc82Dueqqq6666qqrrrrqfxMqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666l9w33333Qpw5syZB3HVVVddddVVV1111f8mVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddW/4OzZs88AuOaaax7MVVddddVVV1111VX/m1C56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVV/4L77rvvVoBrrrnmwVx11VVXXXXVVVdd9b8Jlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXfUvOHv27K0AZ86ceTBXXXXVVVddddVVV/1vQuWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq676F9x33323AlxzzTUP5qqrrrrqqquuuuqq/02oXHXVVVddddVVV1111VVXXXXVVVddddVV/1cRXHXVVVddddVVV1111YvgvvvuuxXgmmuueTBXXXXVVVddddVVV/1vQXDVVVddddVVV1111VUvgrNnz94KcObMmQdz1VVXXXXVVVddddX/FlSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/VxFcddVVV1111VVXXXXVi+C+++67FeCaa655MFddddVVV1111VVX/W9B5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV70I7rvvvlsBzpw58yCuuuqqq6666qqrrvrfgspVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq656EZw9e/YZANdcc82Dueqqq6666qqrrrrqfwsqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666kVw33333QpwzTXXPJirrrrqqquuuuqqq/63oHLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqqteBGfPnr0V4MyZMw/mqquuuuqqq6666qr/LahcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVL4L77rvvVoBrrrnmwVx11VVXXXXVVVdd9b8FwVVXXXXVVVddddVVV72I7rvvvlsBrrnmmgdz1VVXXXXVVVddddX/BlSuuuqqq6666qqrrrrqqquuuuqqq6666qr/qwiuuuqqq6666qqrrrrqRXT27NlbAc6cOfNgrrrqqquuuuqqq67634DKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yqCq6666qqrrrrqqquuehHdd999twJcc801D+aqq6666qqrrrrqqv8NqFx11VVXXXXVVVddddWL6L777rsV4MyZMw/iqquuuuqqq6666qr/DahcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVL6KzZ88+A+Caa655MFddddVVV1111VVX/W9A5aqrrrrqqquuuuqqq15E9913360A11xzzYO56qqrrrrqqquuuup/AypXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVi+js2bO3Apw5c+bBXHXVVVddddVVV131vwGVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVdd9SK67777bgW45pprHsxVV1111VVXXXXVVf8bULnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vIrjqqquuuuqqq6666qp/hfvuu+9WgGuuuebBXHXVVVddddVVV131Px2Vq6666qqrrrrqqquuuuqqq6666qqrrrrq/yqCq6666qqrrrrqqquu+lc4e/bsrQBnzpx5MFddddVVV1111VVX/U9H5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+K4Kqrrrrqqquuuuqqq/4V7rvvvlsBrrnmmgdz1VVXXXXVVVddddX/dFSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVv8J99913K8CZM2cexFVXXXXVVVddddVV/9NRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVf8KZ8+efQbANddc82Cuuuqqq6666qqrrvqfjspVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq676V7jvvvtuBbjmmmsezFVXXXXVVVddddVV/9NRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVf8KZ8+evRXgzJkzD+aqq6666qqrrrrqqv/pqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VX/Cvfdd9+tANdcc82Dueqqq6666qqrrrrqfzoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1UEV1111VVXXXXVVVdd9a9033333QpwzTXXPJirrrrqqquuuuqqq/4nI7jqqquuuuqqq6666qp/pbNnz94KcObMmQdz1VVXXXXVVVddddX/ZFSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/VxFcddVVV1111VVXXXXVv9J99913K8A111zzYK666qqrrrrqqquu+p+MylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8V5fjx41x11VVXXXXVVVddddW/xid90if9NMArvuIrvvXGxsZf/fVf//UTueqqq6666qqrrrrqfyKCq6666qqrrrrqqquu+lf4iZ/4CfMAb/EWb/EzXHXVVVddddVVV131PxXBVVddddVVV1111VVX/Tt96Id+6Ldy1VVXXXXVVVddddX/RFSuuuqqq6666qqrrrrq3+mee+75Xa666qqrrrrqqquu+p+IylVXXXXVVVddddVVV/07/eRP/uT3c9VVV1111VVXXXXV/0QEV1111VVXXXXVVVdd9a/wdm/3drrnnnuezDO93du9nbjqqquuuuqqq6666n8qgquuuuqqq6666qqrrvpX+sZv/MYPBPiHf/iH3+aqq6666qqrrrrqqv/JqFx11VVXXXXVVVddddW/0tmzZ28FOHPmzIO56qqrrrrqqquuuup/MipXXXXVVVddddVVV131b3T27Nlbueqqq6666qqrrrrqfzIqV1111VVXXXXVVVdd9W905syZB3PVVVddddVVV1111f9kVK666qqrrrrqqquuuupf6b777rsV4JprrnkwV1111VVXXXXVVVf9T0blqquuuuqqq6666qqrrvof5XVe53Xe+x3f8R0/i/+FJMm2eQBJsu2zZ8/e+vVf//Xvc999993KVVddddVVV131X4XKVVddddVVV1111VVXXfU/xod/+Id/1+u8zuu8N8Af/dEf8W9lm/9pXvVVX/XBn/M5n/Nbn/VZn/U69913361cddVVV1111VX/FahcddVVV1111VVXXXXVVf/jnD9/nu/+7u/mv4Nt/jOcOnWKRz3qUQ9+x3d8x8/6+q//+vfhqquuuuqqq676r0Bw1VVXXXXVVVddddVV/wb33XffrQDXXHPNg7nqP9ypU6d45CMfyX8HSUhCEpKQhCQkIQlJSEISkpDEi+K7v/u7AXixF3ux177mmmsezFVXXXXVVVdd9V+B4Kqrrrrqqquuuuqqq676H+Oaa655MM/0Fm/xFvxvIQlJSEISkpCEJCQhiQsXLvCkJz2Ja6655sHv+I7v+FlcddVVV1111VX/FQiuuuqqq6666qqrrrrqqv9RfvzHfxyAU6dOIQlJSEISkvjf7Lu/+7sBePEXf/HXueaaax7MVVddddVVV131n43gqquuuuqqq6666qqrrvof48yZMw8+d+4cj3vc4zh16hSPfOQjeW6SkIQkJCEJSUhCEpKQhCQkIQlJSOK/2/nz53nSk57EmTNnHvSO7/iOn8VVV1111VVXXfWfjcpVV1111VVXXfW/2jXXXPPgM2fOPPiaa655MA9w33333XrNNdc8GOC+++67FeDs2bO33nfffbdy1VX/Ac6ePXvrNddc8+AzZ848+L777ruVq/5DPe5xj+Oxj30sb/7mb85XfuVX8h9FEv8WtvmP8t3f/d184Rd+IS/2Yi/22tdcc82D77vvvlu56qqrrrrqqqv+s1C56qqrrrrqqqv+V7jmmmsefObMmQe/2Iu92Gu9+Iu/+Gu/2Iu92GvzXO67775br7nmmgfzL7jvvvtuPXv27K333Xffrf/wD//wO7/1W7/13Vx11VX/I1xzzTUPPnv2LI973ON4+7d/e06dOsX/BJL417DNC3L+/Hme+MQn8qhHPerB7/iO7/hZX//1X/8+XHXVVVddddVV/1moXHXVVVddddVV/2Ndc801D36xF3ux136d13md93qxF3ux1+aZzp8/zxOf+ESe9KQnAXD+/HnOnTuHpAfzXCRx6tQpAB75yEcCcOrUqQe/2Iu92INf7MVejNd5ndd57w//8A//rvvuu+/W3/qt3/ruf/iHf/idf/iHf/htrrrqqv9WZ8+e5XGPexyPfexjeeQjH8mTnvQk/jeRxAvzvd/7vXzBF3wBL/ZiL/ba11xzzYPvu+++W7nqqquuuuqqq/4zULnqqquuuuqqq/7Hecd3fMfPep3XeZ33vuaaax4McO7cOX72Z3+WJz7xiTzpSU8CQBIPJIkHksRz+6M/+iPud+rUKQAe+chH8shHPpJXeZVXefA7vdM7fTbAfffdd+tv/dZvffeP/uiPfg5XXXXVf7mzZ88C8LjHPY7HPvaxvPmbvzlf9VVfxb/ENv9bnD9/nic96Uk88pGPfPA7vuM7ftbXf/3Xvw9XXXXVVVddddV/BipXXXXVVVddddX/GC/2Yi/22h/+4R/+Xddcc82Dz507x8/8zM/wsz/7s0gCQBIAkrifJJ6bJF4QSQBcuHABgD/+4z/mj//4j/mFX/gFAN7szd6MV3mVV3nwO73TO33267zO67z3b/3Wb333j/7oj34OV1111X+6a6655sE8wO/+7u/yWq/1Wpw6dYoXhST+rWzzX+17vud7+IIv+AJe7MVe7LWvueaaB9933323ctVVV1111VVX/UejctVVV1111VVX/be75pprHvzhH/7h3/ViL/Zir/2EJzyBL/uyL+P8+fNIQhIAkgCQxP0k8UCSeEEk8cKcP38egO/93u/lF37hF3jkIx/JK7/yKz/4nd7pnT77dV7ndd77R3/0Rz/nt37rt76bq6666j/d2bNnATh79ixnz57lsY99LI985CN50pOexH8WSfxr2ebf4/z58zzpSU/ikY985IPf8R3f8bO+/uu//n246qqrrrrqqqv+oxFc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uuqqq6666qqr/oPcd999t/JMkpCEJGwjCQDbANjGNgC2sY1tbHM/29jGNraxjW1sA2Ab29jGNraxjW0AbGMb29jGNraxDYBtbGMb29jGNrYBsI1tbGMbANvYxjb3s41tbANgG9sA2MY297MNgG0AbGMbANtcddVVV1111X8wKlddddVVV1111VVXXXXVVf9Bzp49+4x/+Id/+O0Xe7EXe21JlFK46l/vH/7hH36bq6666qqrrvqPgR70oAdx1VVXXXXVVVddddVVV131H+kd3/EdP+t1Xud13pur/tX+4R/+4be//uu//n246qqrrrrqqv8Y6EEPehBXXXXVVVddddVVV1111VVXXXXVVVddddX/SVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/Ff8Iv8z1O0aqcs4AAAAASUVORK5CYII=) diff --git a/docs/kcl/std.json b/docs/kcl/std.json index 678b4dfb2..660d10f58 100644 --- a/docs/kcl/std.json +++ b/docs/kcl/std.json @@ -253490,7 +253490,7 @@ { "name": "rotate", "summary": "Rotate a solid or a sketch.", - "description": "### Using Roll, Pitch, and Yaw\n\nWhen rotating a part in 3D space, \"roll,\" \"pitch,\" and \"yaw\" refer to the three rotational axes used to describe its orientation: roll is rotation around the longitudinal axis (front-to-back), pitch is rotation around the lateral axis (wing-to-wing), and yaw is rotation around the vertical axis (up-down); essentially, it's like tilting the part on its side (roll), tipping the nose up or down (pitch), and turning it left or right (yaw).\n\nSo, in the context of a 3D model:\n\n- **Roll**: Imagine spinning a pencil on its tip - that's a roll movement.\n\n- **Pitch**: Think of a seesaw motion, where the object tilts up or down along its side axis.\n\n- **Yaw**: Like turning your head left or right, this is a rotation around the vertical axis\n\n### Using an Axis and Angle\n\nWhen rotating a part around an axis, you specify the axis of rotation and the angle of rotation.", + "description": "This is really useful for assembling parts together. You can create a part and then rotate it to the correct orientation.\n\nFor sketches, you can use this to rotate a sketch and then loft it with another sketch.\n\n### Using Roll, Pitch, and Yaw\n\nWhen rotating a part in 3D space, \"roll,\" \"pitch,\" and \"yaw\" refer to the three rotational axes used to describe its orientation: roll is rotation around the longitudinal axis (front-to-back), pitch is rotation around the lateral axis (wing-to-wing), and yaw is rotation around the vertical axis (up-down); essentially, it's like tilting the part on its side (roll), tipping the nose up or down (pitch), and turning it left or right (yaw).\n\nSo, in the context of a 3D model:\n\n- **Roll**: Imagine spinning a pencil on its tip - that's a roll movement.\n\n- **Pitch**: Think of a seesaw motion, where the object tilts up or down along its side axis.\n\n- **Yaw**: Like turning your head left or right, this is a rotation around the vertical axis\n\n### Using an Axis and Angle\n\nWhen rotating a part around an axis, you specify the axis of rotation and the angle of rotation.", "tags": [], "keywordArguments": true, "args": [ @@ -266424,7 +266424,7 @@ "// Rotate a pipe about an axis with an angle.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> rotate(axis = [0, 0, 1.0], angle = 90)", "// Rotate an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> rotate(axis = [0, 0, 1.0], angle = 90)", "// Sweep two sketches along the same path.\n\n\nsketch001 = startSketchOn(XY)\nrectangleSketch = startProfileAt([-200, 23.86], sketch001)\n |> angledLine([0, 73.47], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 50.61\n ], %)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n\ncircleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)\n\nsketch002 = startSketchOn(YZ)\nsweepPath = startProfileAt([0, 0], sketch002)\n |> yLine(length = 231.81)\n |> tangentialArc({ radius = 80, offset = -90 }, %)\n |> xLine(length = 384.93)\n\nparts = sweep([rectangleSketch, circleSketch], path = sweepPath)\n\n// Rotate the sweeps.\nrotate(parts, axis = [0, 0, 1.0], angle = 90)", - "// Translate and rotate a sketch to create a loft.\nsketch001 = startSketchOn(XY)\n\nfn square() {\n return startProfileAt([-10, 10], sketch001)\n |> xLine(length = 20)\n |> yLine(length = -20)\n |> xLine(length = -20)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n}\n\nprofile001 = square()\n\nprofile002 = square()\n |> translate(translate = [0, 0, 20])\n |> rotate(axis = [0, 0, 1.0], angle = 45)\n\nloft([profile001, profile002])" + "// Translate and rotate a sketch to create a loft.\nsketch001 = startSketchOn(XY)\n\nfn square() {\n return startProfileAt([-10, 10], sketch001)\n |> xLine(length = 20)\n |> yLine(length = -20)\n |> xLine(length = -20)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n}\n\nprofile001 = square()\n\nprofile002 = square()\n |> translate(x = 0, y = 0, z = 20)\n |> rotate(axis = [0, 0, 1.0], angle = 45)\n\nloft([profile001, profile002])" ] }, { @@ -266472,7 +266472,7 @@ { "name": "scale", "summary": "Scale a solid or a sketch.", - "description": "By default the transform is applied in local sketch axis, therefore the origin will not move.\n\nIf you want to apply the transform in global space, set `global` to `true`. The origin of the model will move. If the model is not centered on origin and you scale globally it will look like the model moves and gets bigger at the same time. Say you have a square `(1,1) - (1,2) - (2,2) - (2,1)` and you scale by 2 globally it will become `(2,2) - (2,4)`...etc so the origin has moved from `(1.5, 1.5)` to `(2,2)`.", + "description": "This is really useful for resizing parts. You can create a part and then scale it to the correct size.\n\nFor sketches, you can use this to scale a sketch and then loft it with another sketch.\n\nBy default the transform is applied in local sketch axis, therefore the origin will not move.\n\nIf you want to apply the transform in global space, set `global` to `true`. The origin of the model will move. If the model is not centered on origin and you scale globally it will look like the model moves and gets bigger at the same time. Say you have a square `(1,1) - (1,2) - (2,2) - (2,1)` and you scale by 2 globally it will become `(2,2) - (2,4)`...etc so the origin has moved from `(1.5, 1.5)` to `(2,2)`.", "tags": [], "keywordArguments": true, "args": [ @@ -268144,18 +268144,13 @@ "labelRequired": false }, { - "name": "scale", - "type": "[number]", + "name": "x", + "type": "number", "schema": { "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema", - "title": "Array_size_3_of_double", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 3, - "minItems": 3, + "title": "double", + "type": "number", + "format": "double", "definitions": { "Solid": { "type": "object", @@ -269742,7 +269737,3201 @@ }, "required": true, "includeInSnippet": true, - "description": "The scale factor for the x, y, and z axes.", + "description": "The scale factor for the x axis.", + "labelRequired": true + }, + { + "name": "y", + "type": "number", + "schema": { + "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema", + "title": "double", + "type": "number", + "format": "double", + "definitions": { + "Solid": { + "type": "object", + "required": [ + "artifactId", + "height", + "id", + "sketch", + "units", + "value" + ], + "properties": { + "id": { + "description": "The id of the solid.", + "type": "string", + "format": "uuid" + }, + "artifactId": { + "description": "The artifact ID of the solid. Unlike `id`, this doesn't change.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "value": { + "description": "The extrude surfaces.", + "type": "array", + "items": { + "$ref": "#/components/schemas/ExtrudeSurface" + } + }, + "sketch": { + "description": "The sketch.", + "allOf": [ + { + "$ref": "#/components/schemas/Sketch" + } + ] + }, + "height": { + "description": "The height of the solid.", + "type": "number", + "format": "double" + }, + "startCapId": { + "description": "The id of the extrusion start cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "endCapId": { + "description": "The id of the extrusion end cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "edgeCuts": { + "description": "Chamfers or fillets on this solid.", + "type": "array", + "items": { + "$ref": "#/components/schemas/EdgeCut" + } + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + }, + "ArtifactId": { + "type": "string", + "format": "uuid" + }, + "ExtrudeSurface": { + "description": "An extrude surface.", + "oneOf": [ + { + "description": "An extrude plane.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "extrudePlane" + ] + }, + "faceId": { + "description": "The face id for the extrude plane.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + { + "description": "An extruded arc.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "extrudeArc" + ] + }, + "faceId": { + "description": "The face id for the extrude plane.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + { + "description": "Geometry metadata.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "chamfer" + ] + }, + "faceId": { + "description": "The id for the chamfer surface.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + { + "description": "Geometry metadata.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "fillet" + ] + }, + "faceId": { + "description": "The id for the fillet surface.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + } + ] + }, + "TagDeclarator": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "string" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + "SourceRange": { + "description": "The first two items are the start and end points (byte offsets from the start of the file). The third item is whether the source range belongs to the 'main' file, i.e., the file currently being rendered/displayed in the editor.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 3, + "minItems": 3 + }, + "Sketch": { + "type": "object", + "required": [ + "artifactId", + "id", + "on", + "originalId", + "paths", + "start", + "units" + ], + "properties": { + "id": { + "description": "The id of the sketch (this will change when the engine's reference to it changes).", + "type": "string", + "format": "uuid" + }, + "paths": { + "description": "The paths in the sketch.", + "type": "array", + "items": { + "$ref": "#/components/schemas/Path" + } + }, + "on": { + "description": "What the sketch is on (can be a plane or a face).", + "allOf": [ + { + "$ref": "#/components/schemas/SketchSurface" + } + ] + }, + "start": { + "description": "The starting path.", + "allOf": [ + { + "$ref": "#/components/schemas/BasePath" + } + ] + }, + "tags": { + "description": "Tag identifiers that have been declared in this sketch.", + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/TagIdentifier" + } + }, + "artifactId": { + "description": "The original id of the sketch. This stays the same even if the sketch is is sketched on face etc.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "originalId": { + "type": "string", + "format": "uuid" + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + }, + "Path": { + "description": "A path.", + "oneOf": [ + { + "description": "A path that goes to a point.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "ToPoint" + ] + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A arc that is tangential to the last path segment that goes to a point", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "TangentialArcTo" + ] + }, + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "ccw": { + "description": "arc's direction", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A arc that is tangential to the last path segment", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "TangentialArc" + ] + }, + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "ccw": { + "description": "arc's direction", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "a complete arc", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "radius", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Circle" + ] + }, + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "radius": { + "description": "the arc's radius", + "type": "number", + "format": "double" + }, + "ccw": { + "description": "arc's direction This is used to compute the tangential angle.", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "p1", + "p2", + "p3", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "CircleThreePoint" + ] + }, + "p1": { + "description": "Point 1 of the circle", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p2": { + "description": "Point 2 of the circle", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p3": { + "description": "Point 3 of the circle", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "p1", + "p2", + "p3", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "ArcThreePoint" + ] + }, + "p1": { + "description": "Point 1 of the arc (base on the end of previous segment)", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p2": { + "description": "Point 2 of the arc (interior kwarg)", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p3": { + "description": "Point 3 of the arc (end kwarg)", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A path that is horizontal.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units", + "x" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Horizontal" + ] + }, + "x": { + "description": "The x coordinate.", + "type": "number", + "format": "double" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "An angled line to.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "AngledLineTo" + ] + }, + "x": { + "description": "The x coordinate.", + "type": "number", + "format": "double", + "nullable": true + }, + "y": { + "description": "The y coordinate.", + "type": "number", + "format": "double", + "nullable": true + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Base" + ] + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A circular arc, not necessarily tangential to the current point.", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "radius", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Arc" + ] + }, + "center": { + "description": "Center of the circle that this arc is drawn on.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "radius": { + "description": "Radius of the circle that this arc is drawn on.", + "type": "number", + "format": "double" + }, + "ccw": { + "description": "True if the arc is counterclockwise.", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + } + ] + }, + "UnitLen": { + "description": "A unit of length.", + "oneOf": [ + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Mm" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Cm" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "M" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Inches" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Feet" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Yards" + ] + } + } + } + ] + }, + "GeoMeta": { + "description": "Geometry metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + "SketchSurface": { + "description": "A sketch type.", + "oneOf": [ + { + "type": "object", + "required": [ + "artifactId", + "id", + "origin", + "type", + "units", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "plane" + ] + }, + "id": { + "description": "The id of the plane.", + "type": "string", + "format": "uuid" + }, + "artifactId": { + "description": "The artifact ID.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "value": { + "$ref": "#/components/schemas/PlaneType" + }, + "origin": { + "description": "Origin of the plane.", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "xAxis": { + "description": "What should the plane's X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "yAxis": { + "description": "What should the plane's Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + }, + { + "description": "A face.", + "type": "object", + "required": [ + "artifactId", + "id", + "solid", + "type", + "units", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "face" + ] + }, + "id": { + "description": "The id of the face.", + "type": "string", + "format": "uuid" + }, + "artifactId": { + "description": "The artifact ID.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "value": { + "description": "The tag of the face.", + "type": "string" + }, + "xAxis": { + "description": "What should the face's X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "yAxis": { + "description": "What should the face's Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "solid": { + "description": "The solid the face is on.", + "allOf": [ + { + "$ref": "#/components/schemas/Solid" + } + ] + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + } + ] + }, + "PlaneType": { + "description": "Type for a plane.", + "oneOf": [ + { + "type": "string", + "enum": [ + "XY", + "XZ", + "YZ" + ] + }, + { + "description": "A custom plane.", + "type": "string", + "enum": [ + "Custom" + ] + }, + { + "description": "A custom plane which has not been sent to the engine. It must be sent before it is used.", + "type": "string", + "enum": [ + "Uninit" + ] + } + ] + }, + "Point3d": { + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } + } + }, + "BasePath": { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "units" + ], + "properties": { + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + "TagIdentifier": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "string" + } + } + }, + "EdgeCut": { + "description": "A fillet or a chamfer.", + "oneOf": [ + { + "description": "A fillet.", + "type": "object", + "required": [ + "edgeId", + "id", + "radius", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "fillet" + ] + }, + "id": { + "description": "The id of the engine command that called this fillet.", + "type": "string", + "format": "uuid" + }, + "radius": { + "type": "number", + "format": "double" + }, + "edgeId": { + "description": "The engine id of the edge to fillet.", + "type": "string", + "format": "uuid" + }, + "tag": { + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + } + } + }, + { + "description": "A chamfer.", + "type": "object", + "required": [ + "edgeId", + "id", + "length", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "chamfer" + ] + }, + "id": { + "description": "The id of the engine command that called this chamfer.", + "type": "string", + "format": "uuid" + }, + "length": { + "type": "number", + "format": "double" + }, + "edgeId": { + "description": "The engine id of the edge to chamfer.", + "type": "string", + "format": "uuid" + }, + "tag": { + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + } + } + } + ] + } + } + }, + "required": true, + "includeInSnippet": true, + "description": "The scale factor for the y axis.", + "labelRequired": true + }, + { + "name": "z", + "type": "number", + "schema": { + "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema", + "title": "double", + "type": "number", + "format": "double", + "definitions": { + "Solid": { + "type": "object", + "required": [ + "artifactId", + "height", + "id", + "sketch", + "units", + "value" + ], + "properties": { + "id": { + "description": "The id of the solid.", + "type": "string", + "format": "uuid" + }, + "artifactId": { + "description": "The artifact ID of the solid. Unlike `id`, this doesn't change.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "value": { + "description": "The extrude surfaces.", + "type": "array", + "items": { + "$ref": "#/components/schemas/ExtrudeSurface" + } + }, + "sketch": { + "description": "The sketch.", + "allOf": [ + { + "$ref": "#/components/schemas/Sketch" + } + ] + }, + "height": { + "description": "The height of the solid.", + "type": "number", + "format": "double" + }, + "startCapId": { + "description": "The id of the extrusion start cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "endCapId": { + "description": "The id of the extrusion end cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "edgeCuts": { + "description": "Chamfers or fillets on this solid.", + "type": "array", + "items": { + "$ref": "#/components/schemas/EdgeCut" + } + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + }, + "ArtifactId": { + "type": "string", + "format": "uuid" + }, + "ExtrudeSurface": { + "description": "An extrude surface.", + "oneOf": [ + { + "description": "An extrude plane.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "extrudePlane" + ] + }, + "faceId": { + "description": "The face id for the extrude plane.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + { + "description": "An extruded arc.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "extrudeArc" + ] + }, + "faceId": { + "description": "The face id for the extrude plane.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + { + "description": "Geometry metadata.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "chamfer" + ] + }, + "faceId": { + "description": "The id for the chamfer surface.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + { + "description": "Geometry metadata.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "fillet" + ] + }, + "faceId": { + "description": "The id for the fillet surface.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + } + ] + }, + "TagDeclarator": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "string" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + "SourceRange": { + "description": "The first two items are the start and end points (byte offsets from the start of the file). The third item is whether the source range belongs to the 'main' file, i.e., the file currently being rendered/displayed in the editor.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 3, + "minItems": 3 + }, + "Sketch": { + "type": "object", + "required": [ + "artifactId", + "id", + "on", + "originalId", + "paths", + "start", + "units" + ], + "properties": { + "id": { + "description": "The id of the sketch (this will change when the engine's reference to it changes).", + "type": "string", + "format": "uuid" + }, + "paths": { + "description": "The paths in the sketch.", + "type": "array", + "items": { + "$ref": "#/components/schemas/Path" + } + }, + "on": { + "description": "What the sketch is on (can be a plane or a face).", + "allOf": [ + { + "$ref": "#/components/schemas/SketchSurface" + } + ] + }, + "start": { + "description": "The starting path.", + "allOf": [ + { + "$ref": "#/components/schemas/BasePath" + } + ] + }, + "tags": { + "description": "Tag identifiers that have been declared in this sketch.", + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/TagIdentifier" + } + }, + "artifactId": { + "description": "The original id of the sketch. This stays the same even if the sketch is is sketched on face etc.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "originalId": { + "type": "string", + "format": "uuid" + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + }, + "Path": { + "description": "A path.", + "oneOf": [ + { + "description": "A path that goes to a point.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "ToPoint" + ] + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A arc that is tangential to the last path segment that goes to a point", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "TangentialArcTo" + ] + }, + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "ccw": { + "description": "arc's direction", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A arc that is tangential to the last path segment", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "TangentialArc" + ] + }, + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "ccw": { + "description": "arc's direction", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "a complete arc", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "radius", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Circle" + ] + }, + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "radius": { + "description": "the arc's radius", + "type": "number", + "format": "double" + }, + "ccw": { + "description": "arc's direction This is used to compute the tangential angle.", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "p1", + "p2", + "p3", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "CircleThreePoint" + ] + }, + "p1": { + "description": "Point 1 of the circle", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p2": { + "description": "Point 2 of the circle", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p3": { + "description": "Point 3 of the circle", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "p1", + "p2", + "p3", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "ArcThreePoint" + ] + }, + "p1": { + "description": "Point 1 of the arc (base on the end of previous segment)", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p2": { + "description": "Point 2 of the arc (interior kwarg)", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p3": { + "description": "Point 3 of the arc (end kwarg)", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A path that is horizontal.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units", + "x" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Horizontal" + ] + }, + "x": { + "description": "The x coordinate.", + "type": "number", + "format": "double" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "An angled line to.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "AngledLineTo" + ] + }, + "x": { + "description": "The x coordinate.", + "type": "number", + "format": "double", + "nullable": true + }, + "y": { + "description": "The y coordinate.", + "type": "number", + "format": "double", + "nullable": true + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Base" + ] + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A circular arc, not necessarily tangential to the current point.", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "radius", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Arc" + ] + }, + "center": { + "description": "Center of the circle that this arc is drawn on.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "radius": { + "description": "Radius of the circle that this arc is drawn on.", + "type": "number", + "format": "double" + }, + "ccw": { + "description": "True if the arc is counterclockwise.", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + } + ] + }, + "UnitLen": { + "description": "A unit of length.", + "oneOf": [ + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Mm" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Cm" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "M" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Inches" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Feet" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Yards" + ] + } + } + } + ] + }, + "GeoMeta": { + "description": "Geometry metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + "SketchSurface": { + "description": "A sketch type.", + "oneOf": [ + { + "type": "object", + "required": [ + "artifactId", + "id", + "origin", + "type", + "units", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "plane" + ] + }, + "id": { + "description": "The id of the plane.", + "type": "string", + "format": "uuid" + }, + "artifactId": { + "description": "The artifact ID.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "value": { + "$ref": "#/components/schemas/PlaneType" + }, + "origin": { + "description": "Origin of the plane.", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "xAxis": { + "description": "What should the plane's X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "yAxis": { + "description": "What should the plane's Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + }, + { + "description": "A face.", + "type": "object", + "required": [ + "artifactId", + "id", + "solid", + "type", + "units", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "face" + ] + }, + "id": { + "description": "The id of the face.", + "type": "string", + "format": "uuid" + }, + "artifactId": { + "description": "The artifact ID.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "value": { + "description": "The tag of the face.", + "type": "string" + }, + "xAxis": { + "description": "What should the face's X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "yAxis": { + "description": "What should the face's Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "solid": { + "description": "The solid the face is on.", + "allOf": [ + { + "$ref": "#/components/schemas/Solid" + } + ] + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + } + ] + }, + "PlaneType": { + "description": "Type for a plane.", + "oneOf": [ + { + "type": "string", + "enum": [ + "XY", + "XZ", + "YZ" + ] + }, + { + "description": "A custom plane.", + "type": "string", + "enum": [ + "Custom" + ] + }, + { + "description": "A custom plane which has not been sent to the engine. It must be sent before it is used.", + "type": "string", + "enum": [ + "Uninit" + ] + } + ] + }, + "Point3d": { + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } + } + }, + "BasePath": { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "units" + ], + "properties": { + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + "TagIdentifier": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "string" + } + } + }, + "EdgeCut": { + "description": "A fillet or a chamfer.", + "oneOf": [ + { + "description": "A fillet.", + "type": "object", + "required": [ + "edgeId", + "id", + "radius", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "fillet" + ] + }, + "id": { + "description": "The id of the engine command that called this fillet.", + "type": "string", + "format": "uuid" + }, + "radius": { + "type": "number", + "format": "double" + }, + "edgeId": { + "description": "The engine id of the edge to fillet.", + "type": "string", + "format": "uuid" + }, + "tag": { + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + } + } + }, + { + "description": "A chamfer.", + "type": "object", + "required": [ + "edgeId", + "id", + "length", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "chamfer" + ] + }, + "id": { + "description": "The id of the engine command that called this chamfer.", + "type": "string", + "format": "uuid" + }, + "length": { + "type": "number", + "format": "double" + }, + "edgeId": { + "description": "The engine id of the edge to chamfer.", + "type": "string", + "format": "uuid" + }, + "tag": { + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + } + } + } + ] + } + } + }, + "required": true, + "includeInSnippet": true, + "description": "The scale factor for the z axis.", "labelRequired": true }, { @@ -273011,9 +276200,9 @@ "unpublished": false, "deprecated": false, "examples": [ - "// Scale a pipe.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> scale(scale = [1.0, 1.0, 2.5])", - "// Scale an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> scale(scale = [1.0, 1.0, 2.5])", - "// Sweep two sketches along the same path.\n\n\nsketch001 = startSketchOn(XY)\nrectangleSketch = startProfileAt([-200, 23.86], sketch001)\n |> angledLine([0, 73.47], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 50.61\n ], %)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n\ncircleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)\n\nsketch002 = startSketchOn(YZ)\nsweepPath = startProfileAt([0, 0], sketch002)\n |> yLine(length = 231.81)\n |> tangentialArc({ radius = 80, offset = -90 }, %)\n |> xLine(length = 384.93)\n\nparts = sweep([rectangleSketch, circleSketch], path = sweepPath)\n\n// Scale the sweep.\nscale(parts, scale = [1.0, 1.0, 0.5])" + "// Scale a pipe.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> scale(x = 1.0, y = 1.0, z = 2.5)", + "// Scale an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> scale(x = 1.0, y = 1.0, z = 2.5)", + "// Sweep two sketches along the same path.\n\n\nsketch001 = startSketchOn(XY)\nrectangleSketch = startProfileAt([-200, 23.86], sketch001)\n |> angledLine([0, 73.47], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 50.61\n ], %)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n\ncircleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)\n\nsketch002 = startSketchOn(YZ)\nsweepPath = startProfileAt([0, 0], sketch002)\n |> yLine(length = 231.81)\n |> tangentialArc({ radius = 80, offset = -90 }, %)\n |> xLine(length = 384.93)\n\nparts = sweep([rectangleSketch, circleSketch], path = sweepPath)\n\n// Scale the sweep.\nscale(\n parts,\n x = 1.0,\n y = 1.0,\n z = 0.5,\n)" ] }, { @@ -321550,7 +324739,7 @@ { "name": "translate", "summary": "Move a solid or a sketch.", - "description": "", + "description": "This is really useful for assembling parts together. You can create a part and then move it to the correct location.\n\nTranslate is really useful for sketches if you want to move a sketch and then rotate it using the `rotate` function to create a loft.", "tags": [], "keywordArguments": true, "args": [ @@ -323222,18 +326411,13 @@ "labelRequired": false }, { - "name": "translate", - "type": "[number]", + "name": "x", + "type": "number", "schema": { "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema", - "title": "Array_size_3_of_double", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 3, - "minItems": 3, + "title": "double", + "type": "number", + "format": "double", "definitions": { "Solid": { "type": "object", @@ -324820,7 +328004,3201 @@ }, "required": true, "includeInSnippet": true, - "description": "The amount to move the solid or sketch in all three axes.", + "description": "The amount to move the solid or sketch along the x axis.", + "labelRequired": true + }, + { + "name": "y", + "type": "number", + "schema": { + "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema", + "title": "double", + "type": "number", + "format": "double", + "definitions": { + "Solid": { + "type": "object", + "required": [ + "artifactId", + "height", + "id", + "sketch", + "units", + "value" + ], + "properties": { + "id": { + "description": "The id of the solid.", + "type": "string", + "format": "uuid" + }, + "artifactId": { + "description": "The artifact ID of the solid. Unlike `id`, this doesn't change.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "value": { + "description": "The extrude surfaces.", + "type": "array", + "items": { + "$ref": "#/components/schemas/ExtrudeSurface" + } + }, + "sketch": { + "description": "The sketch.", + "allOf": [ + { + "$ref": "#/components/schemas/Sketch" + } + ] + }, + "height": { + "description": "The height of the solid.", + "type": "number", + "format": "double" + }, + "startCapId": { + "description": "The id of the extrusion start cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "endCapId": { + "description": "The id of the extrusion end cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "edgeCuts": { + "description": "Chamfers or fillets on this solid.", + "type": "array", + "items": { + "$ref": "#/components/schemas/EdgeCut" + } + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + }, + "ArtifactId": { + "type": "string", + "format": "uuid" + }, + "ExtrudeSurface": { + "description": "An extrude surface.", + "oneOf": [ + { + "description": "An extrude plane.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "extrudePlane" + ] + }, + "faceId": { + "description": "The face id for the extrude plane.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + { + "description": "An extruded arc.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "extrudeArc" + ] + }, + "faceId": { + "description": "The face id for the extrude plane.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + { + "description": "Geometry metadata.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "chamfer" + ] + }, + "faceId": { + "description": "The id for the chamfer surface.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + { + "description": "Geometry metadata.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "fillet" + ] + }, + "faceId": { + "description": "The id for the fillet surface.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + } + ] + }, + "TagDeclarator": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "string" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + "SourceRange": { + "description": "The first two items are the start and end points (byte offsets from the start of the file). The third item is whether the source range belongs to the 'main' file, i.e., the file currently being rendered/displayed in the editor.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 3, + "minItems": 3 + }, + "Sketch": { + "type": "object", + "required": [ + "artifactId", + "id", + "on", + "originalId", + "paths", + "start", + "units" + ], + "properties": { + "id": { + "description": "The id of the sketch (this will change when the engine's reference to it changes).", + "type": "string", + "format": "uuid" + }, + "paths": { + "description": "The paths in the sketch.", + "type": "array", + "items": { + "$ref": "#/components/schemas/Path" + } + }, + "on": { + "description": "What the sketch is on (can be a plane or a face).", + "allOf": [ + { + "$ref": "#/components/schemas/SketchSurface" + } + ] + }, + "start": { + "description": "The starting path.", + "allOf": [ + { + "$ref": "#/components/schemas/BasePath" + } + ] + }, + "tags": { + "description": "Tag identifiers that have been declared in this sketch.", + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/TagIdentifier" + } + }, + "artifactId": { + "description": "The original id of the sketch. This stays the same even if the sketch is is sketched on face etc.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "originalId": { + "type": "string", + "format": "uuid" + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + }, + "Path": { + "description": "A path.", + "oneOf": [ + { + "description": "A path that goes to a point.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "ToPoint" + ] + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A arc that is tangential to the last path segment that goes to a point", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "TangentialArcTo" + ] + }, + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "ccw": { + "description": "arc's direction", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A arc that is tangential to the last path segment", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "TangentialArc" + ] + }, + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "ccw": { + "description": "arc's direction", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "a complete arc", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "radius", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Circle" + ] + }, + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "radius": { + "description": "the arc's radius", + "type": "number", + "format": "double" + }, + "ccw": { + "description": "arc's direction This is used to compute the tangential angle.", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "p1", + "p2", + "p3", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "CircleThreePoint" + ] + }, + "p1": { + "description": "Point 1 of the circle", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p2": { + "description": "Point 2 of the circle", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p3": { + "description": "Point 3 of the circle", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "p1", + "p2", + "p3", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "ArcThreePoint" + ] + }, + "p1": { + "description": "Point 1 of the arc (base on the end of previous segment)", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p2": { + "description": "Point 2 of the arc (interior kwarg)", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p3": { + "description": "Point 3 of the arc (end kwarg)", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A path that is horizontal.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units", + "x" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Horizontal" + ] + }, + "x": { + "description": "The x coordinate.", + "type": "number", + "format": "double" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "An angled line to.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "AngledLineTo" + ] + }, + "x": { + "description": "The x coordinate.", + "type": "number", + "format": "double", + "nullable": true + }, + "y": { + "description": "The y coordinate.", + "type": "number", + "format": "double", + "nullable": true + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Base" + ] + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A circular arc, not necessarily tangential to the current point.", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "radius", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Arc" + ] + }, + "center": { + "description": "Center of the circle that this arc is drawn on.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "radius": { + "description": "Radius of the circle that this arc is drawn on.", + "type": "number", + "format": "double" + }, + "ccw": { + "description": "True if the arc is counterclockwise.", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + } + ] + }, + "UnitLen": { + "description": "A unit of length.", + "oneOf": [ + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Mm" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Cm" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "M" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Inches" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Feet" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Yards" + ] + } + } + } + ] + }, + "GeoMeta": { + "description": "Geometry metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + "SketchSurface": { + "description": "A sketch type.", + "oneOf": [ + { + "type": "object", + "required": [ + "artifactId", + "id", + "origin", + "type", + "units", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "plane" + ] + }, + "id": { + "description": "The id of the plane.", + "type": "string", + "format": "uuid" + }, + "artifactId": { + "description": "The artifact ID.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "value": { + "$ref": "#/components/schemas/PlaneType" + }, + "origin": { + "description": "Origin of the plane.", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "xAxis": { + "description": "What should the plane's X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "yAxis": { + "description": "What should the plane's Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + }, + { + "description": "A face.", + "type": "object", + "required": [ + "artifactId", + "id", + "solid", + "type", + "units", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "face" + ] + }, + "id": { + "description": "The id of the face.", + "type": "string", + "format": "uuid" + }, + "artifactId": { + "description": "The artifact ID.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "value": { + "description": "The tag of the face.", + "type": "string" + }, + "xAxis": { + "description": "What should the face's X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "yAxis": { + "description": "What should the face's Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "solid": { + "description": "The solid the face is on.", + "allOf": [ + { + "$ref": "#/components/schemas/Solid" + } + ] + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + } + ] + }, + "PlaneType": { + "description": "Type for a plane.", + "oneOf": [ + { + "type": "string", + "enum": [ + "XY", + "XZ", + "YZ" + ] + }, + { + "description": "A custom plane.", + "type": "string", + "enum": [ + "Custom" + ] + }, + { + "description": "A custom plane which has not been sent to the engine. It must be sent before it is used.", + "type": "string", + "enum": [ + "Uninit" + ] + } + ] + }, + "Point3d": { + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } + } + }, + "BasePath": { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "units" + ], + "properties": { + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + "TagIdentifier": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "string" + } + } + }, + "EdgeCut": { + "description": "A fillet or a chamfer.", + "oneOf": [ + { + "description": "A fillet.", + "type": "object", + "required": [ + "edgeId", + "id", + "radius", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "fillet" + ] + }, + "id": { + "description": "The id of the engine command that called this fillet.", + "type": "string", + "format": "uuid" + }, + "radius": { + "type": "number", + "format": "double" + }, + "edgeId": { + "description": "The engine id of the edge to fillet.", + "type": "string", + "format": "uuid" + }, + "tag": { + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + } + } + }, + { + "description": "A chamfer.", + "type": "object", + "required": [ + "edgeId", + "id", + "length", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "chamfer" + ] + }, + "id": { + "description": "The id of the engine command that called this chamfer.", + "type": "string", + "format": "uuid" + }, + "length": { + "type": "number", + "format": "double" + }, + "edgeId": { + "description": "The engine id of the edge to chamfer.", + "type": "string", + "format": "uuid" + }, + "tag": { + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + } + } + } + ] + } + } + }, + "required": true, + "includeInSnippet": true, + "description": "The amount to move the solid or sketch along the y axis.", + "labelRequired": true + }, + { + "name": "z", + "type": "number", + "schema": { + "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema", + "title": "double", + "type": "number", + "format": "double", + "definitions": { + "Solid": { + "type": "object", + "required": [ + "artifactId", + "height", + "id", + "sketch", + "units", + "value" + ], + "properties": { + "id": { + "description": "The id of the solid.", + "type": "string", + "format": "uuid" + }, + "artifactId": { + "description": "The artifact ID of the solid. Unlike `id`, this doesn't change.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "value": { + "description": "The extrude surfaces.", + "type": "array", + "items": { + "$ref": "#/components/schemas/ExtrudeSurface" + } + }, + "sketch": { + "description": "The sketch.", + "allOf": [ + { + "$ref": "#/components/schemas/Sketch" + } + ] + }, + "height": { + "description": "The height of the solid.", + "type": "number", + "format": "double" + }, + "startCapId": { + "description": "The id of the extrusion start cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "endCapId": { + "description": "The id of the extrusion end cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "edgeCuts": { + "description": "Chamfers or fillets on this solid.", + "type": "array", + "items": { + "$ref": "#/components/schemas/EdgeCut" + } + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + }, + "ArtifactId": { + "type": "string", + "format": "uuid" + }, + "ExtrudeSurface": { + "description": "An extrude surface.", + "oneOf": [ + { + "description": "An extrude plane.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "extrudePlane" + ] + }, + "faceId": { + "description": "The face id for the extrude plane.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + { + "description": "An extruded arc.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "extrudeArc" + ] + }, + "faceId": { + "description": "The face id for the extrude plane.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + { + "description": "Geometry metadata.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "chamfer" + ] + }, + "faceId": { + "description": "The id for the chamfer surface.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + { + "description": "Geometry metadata.", + "type": "object", + "required": [ + "faceId", + "id", + "sourceRange", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "fillet" + ] + }, + "faceId": { + "description": "The id for the fillet surface.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + } + ] + }, + "TagDeclarator": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "string" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + "SourceRange": { + "description": "The first two items are the start and end points (byte offsets from the start of the file). The third item is whether the source range belongs to the 'main' file, i.e., the file currently being rendered/displayed in the editor.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 3, + "minItems": 3 + }, + "Sketch": { + "type": "object", + "required": [ + "artifactId", + "id", + "on", + "originalId", + "paths", + "start", + "units" + ], + "properties": { + "id": { + "description": "The id of the sketch (this will change when the engine's reference to it changes).", + "type": "string", + "format": "uuid" + }, + "paths": { + "description": "The paths in the sketch.", + "type": "array", + "items": { + "$ref": "#/components/schemas/Path" + } + }, + "on": { + "description": "What the sketch is on (can be a plane or a face).", + "allOf": [ + { + "$ref": "#/components/schemas/SketchSurface" + } + ] + }, + "start": { + "description": "The starting path.", + "allOf": [ + { + "$ref": "#/components/schemas/BasePath" + } + ] + }, + "tags": { + "description": "Tag identifiers that have been declared in this sketch.", + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/TagIdentifier" + } + }, + "artifactId": { + "description": "The original id of the sketch. This stays the same even if the sketch is is sketched on face etc.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "originalId": { + "type": "string", + "format": "uuid" + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + }, + "Path": { + "description": "A path.", + "oneOf": [ + { + "description": "A path that goes to a point.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "ToPoint" + ] + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A arc that is tangential to the last path segment that goes to a point", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "TangentialArcTo" + ] + }, + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "ccw": { + "description": "arc's direction", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A arc that is tangential to the last path segment", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "TangentialArc" + ] + }, + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "ccw": { + "description": "arc's direction", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "a complete arc", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "radius", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Circle" + ] + }, + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "radius": { + "description": "the arc's radius", + "type": "number", + "format": "double" + }, + "ccw": { + "description": "arc's direction This is used to compute the tangential angle.", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "p1", + "p2", + "p3", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "CircleThreePoint" + ] + }, + "p1": { + "description": "Point 1 of the circle", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p2": { + "description": "Point 2 of the circle", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p3": { + "description": "Point 3 of the circle", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "p1", + "p2", + "p3", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "ArcThreePoint" + ] + }, + "p1": { + "description": "Point 1 of the arc (base on the end of previous segment)", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p2": { + "description": "Point 2 of the arc (interior kwarg)", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "p3": { + "description": "Point 3 of the arc (end kwarg)", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A path that is horizontal.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units", + "x" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Horizontal" + ] + }, + "x": { + "description": "The x coordinate.", + "type": "number", + "format": "double" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "An angled line to.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "AngledLineTo" + ] + }, + "x": { + "description": "The x coordinate.", + "type": "number", + "format": "double", + "nullable": true + }, + "y": { + "description": "The y coordinate.", + "type": "number", + "format": "double", + "nullable": true + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Base" + ] + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + { + "description": "A circular arc, not necessarily tangential to the current point.", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "radius", + "to", + "type", + "units" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Arc" + ] + }, + "center": { + "description": "Center of the circle that this arc is drawn on.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "radius": { + "description": "Radius of the circle that this arc is drawn on.", + "type": "number", + "format": "double" + }, + "ccw": { + "description": "True if the arc is counterclockwise.", + "type": "boolean" + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + } + ] + }, + "UnitLen": { + "description": "A unit of length.", + "oneOf": [ + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Mm" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Cm" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "M" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Inches" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Feet" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Yards" + ] + } + } + } + ] + }, + "GeoMeta": { + "description": "Geometry metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + "SketchSurface": { + "description": "A sketch type.", + "oneOf": [ + { + "type": "object", + "required": [ + "artifactId", + "id", + "origin", + "type", + "units", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "plane" + ] + }, + "id": { + "description": "The id of the plane.", + "type": "string", + "format": "uuid" + }, + "artifactId": { + "description": "The artifact ID.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "value": { + "$ref": "#/components/schemas/PlaneType" + }, + "origin": { + "description": "Origin of the plane.", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "xAxis": { + "description": "What should the plane's X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "yAxis": { + "description": "What should the plane's Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + }, + { + "description": "A face.", + "type": "object", + "required": [ + "artifactId", + "id", + "solid", + "type", + "units", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "face" + ] + }, + "id": { + "description": "The id of the face.", + "type": "string", + "format": "uuid" + }, + "artifactId": { + "description": "The artifact ID.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactId" + } + ] + }, + "value": { + "description": "The tag of the face.", + "type": "string" + }, + "xAxis": { + "description": "What should the face's X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "yAxis": { + "description": "What should the face's Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "solid": { + "description": "The solid the face is on.", + "allOf": [ + { + "$ref": "#/components/schemas/Solid" + } + ] + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + } + } + } + ] + }, + "PlaneType": { + "description": "Type for a plane.", + "oneOf": [ + { + "type": "string", + "enum": [ + "XY", + "XZ", + "YZ" + ] + }, + { + "description": "A custom plane.", + "type": "string", + "enum": [ + "Custom" + ] + }, + { + "description": "A custom plane which has not been sent to the engine. It must be sent before it is used.", + "type": "string", + "enum": [ + "Uninit" + ] + } + ] + }, + "Point3d": { + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } + } + }, + "BasePath": { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to", + "units" + ], + "properties": { + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "units": { + "$ref": "#/components/schemas/UnitLen" + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + "TagIdentifier": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "string" + } + } + }, + "EdgeCut": { + "description": "A fillet or a chamfer.", + "oneOf": [ + { + "description": "A fillet.", + "type": "object", + "required": [ + "edgeId", + "id", + "radius", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "fillet" + ] + }, + "id": { + "description": "The id of the engine command that called this fillet.", + "type": "string", + "format": "uuid" + }, + "radius": { + "type": "number", + "format": "double" + }, + "edgeId": { + "description": "The engine id of the edge to fillet.", + "type": "string", + "format": "uuid" + }, + "tag": { + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + } + } + }, + { + "description": "A chamfer.", + "type": "object", + "required": [ + "edgeId", + "id", + "length", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "chamfer" + ] + }, + "id": { + "description": "The id of the engine command that called this chamfer.", + "type": "string", + "format": "uuid" + }, + "length": { + "type": "number", + "format": "double" + }, + "edgeId": { + "description": "The engine id of the edge to chamfer.", + "type": "string", + "format": "uuid" + }, + "tag": { + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + } + } + } + ] + } + } + }, + "required": true, + "includeInSnippet": true, + "description": "The amount to move the solid or sketch along the z axis.", "labelRequired": true }, { @@ -328089,11 +334467,11 @@ "unpublished": false, "deprecated": false, "examples": [ - "// Move a pipe.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> translate(translate = [1.0, 1.0, 2.5])", - "// Move an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> translate(translate = [1.0, 1.0, 2.5])", - "// Sweep two sketches along the same path.\n\n\nsketch001 = startSketchOn(XY)\nrectangleSketch = startProfileAt([-200, 23.86], sketch001)\n |> angledLine([0, 73.47], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 50.61\n ], %)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n\ncircleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)\n\nsketch002 = startSketchOn(YZ)\nsweepPath = startProfileAt([0, 0], sketch002)\n |> yLine(length = 231.81)\n |> tangentialArc({ radius = 80, offset = -90 }, %)\n |> xLine(length = 384.93)\n\nparts = sweep([rectangleSketch, circleSketch], path = sweepPath)\n\n// Move the sweeps.\ntranslate(parts, translate = [1.0, 1.0, 2.5])", - "// Move a sketch.\n\n\nfn square(length) {\n l = length / 2\n p0 = [-l, -l]\n p1 = [-l, l]\n p2 = [l, l]\n p3 = [l, -l]\n\n return startSketchOn(XY)\n |> startProfileAt(p0, %)\n |> line(endAbsolute = p1)\n |> line(endAbsolute = p2)\n |> line(endAbsolute = p3)\n |> close()\n}\n\nsquare(10)\n |> translate(translate = [5, 5, 0])\n |> extrude(length = 10)", - "// Translate and rotate a sketch to create a loft.\nsketch001 = startSketchOn(XY)\n\nfn square() {\n return startProfileAt([-10, 10], sketch001)\n |> xLine(length = 20)\n |> yLine(length = -20)\n |> xLine(length = -20)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n}\n\nprofile001 = square()\n\nprofile002 = square()\n |> translate(translate = [0, 0, 20])\n |> rotate(axis = [0, 0, 1.0], angle = 45)\n\nloft([profile001, profile002])" + "// Move a pipe.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> translate(x = 1.0, y = 1.0, z = 2.5)", + "// Move an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> translate(x = 1.0, y = 1.0, z = 2.5)", + "// Sweep two sketches along the same path.\n\n\nsketch001 = startSketchOn(XY)\nrectangleSketch = startProfileAt([-200, 23.86], sketch001)\n |> angledLine([0, 73.47], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 50.61\n ], %)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n\ncircleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)\n\nsketch002 = startSketchOn(YZ)\nsweepPath = startProfileAt([0, 0], sketch002)\n |> yLine(length = 231.81)\n |> tangentialArc({ radius = 80, offset = -90 }, %)\n |> xLine(length = 384.93)\n\nparts = sweep([rectangleSketch, circleSketch], path = sweepPath)\n\n// Move the sweeps.\ntranslate(\n parts,\n x = 1.0,\n y = 1.0,\n z = 2.5,\n)", + "// Move a sketch.\n\n\nfn square(length) {\n l = length / 2\n p0 = [-l, -l]\n p1 = [-l, l]\n p2 = [l, l]\n p3 = [l, -l]\n\n return startSketchOn(XY)\n |> startProfileAt(p0, %)\n |> line(endAbsolute = p1)\n |> line(endAbsolute = p2)\n |> line(endAbsolute = p3)\n |> close()\n}\n\nsquare(10)\n |> translate(x = 5, y = 5, z = 0)\n |> extrude(length = 10)", + "// Translate and rotate a sketch to create a loft.\nsketch001 = startSketchOn(XY)\n\nfn square() {\n return startProfileAt([-10, 10], sketch001)\n |> xLine(length = 20)\n |> yLine(length = -20)\n |> xLine(length = -20)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n}\n\nprofile001 = square()\n\nprofile002 = square()\n |> translate(x = 0, y = 0, z = 20)\n |> rotate(axis = [0, 0, 1.0], angle = 45)\n\nloft([profile001, profile002])" ] }, { diff --git a/docs/kcl/translate.md b/docs/kcl/translate.md index 7fbb197a8..bcba20fc5 100644 --- a/docs/kcl/translate.md +++ b/docs/kcl/translate.md @@ -6,12 +6,16 @@ layout: manual Move a solid or a sketch. +This is really useful for assembling parts together. You can create a part and then move it to the correct location. +Translate is really useful for sketches if you want to move a sketch and then rotate it using the `rotate` function to create a loft. ```js translate( objects: SolidOrSketchOrImportedGeometry, - translate: [number], + x: number, + y: number, + z: number, global?: bool, ): SolidOrSketchOrImportedGeometry ``` @@ -22,7 +26,9 @@ translate( | Name | Type | Description | Required | |----------|------|-------------|----------| | `objects` | [`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) | The solid, sketch, or set of solids or sketches to move. | Yes | -| `translate` | [`[number]`](/docs/kcl/types/number) | The amount to move the solid or sketch in all three axes. | Yes | +| `x` | [`number`](/docs/kcl/types/number) | The amount to move the solid or sketch along the x axis. | Yes | +| `y` | [`number`](/docs/kcl/types/number) | The amount to move the solid or sketch along the y axis. | Yes | +| `z` | [`number`](/docs/kcl/types/number) | The amount to move the solid or sketch along the z axis. | Yes | | `global` | [`bool`](/docs/kcl/types/bool) | If true, the transform is applied in global space. The origin of the model will move. By default, the transform is applied in local sketch axis, therefore the origin will not move. | No | ### Returns @@ -52,7 +58,7 @@ sweepSketch = startSketchOn(XY) |> circle(center = [0, 0], radius = 2) |> hole(pipeHole, %) |> sweep(path = sweepPath) - |> translate(translate = [1.0, 1.0, 2.5]) + |> translate(x = 1.0, y = 1.0, z = 2.5) ``` ![Rendered example of translate 0](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAADPfd1WAAEs6UlEQVR4Ae3AA6AkWZbG8f937o3IzKdyS2Oubdu2bdu2bdu2bWmMnpZKr54yMyLu+Xa3anqmhztr1a8+6EEP4qqrrrrqqquuuuqqq6666qqrrrrqqquu+j+JylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqf5NrrrnmwQBnzpx5MMA111zzYIAzZ848iGe65pprHgxwzTXXPJhnOnPmzIN5gGuuuebB/Dvcd999t15zzTUPvu+++27luZw9e/ZWgPvuu+9Wnum+++67FeDs2bPPALjvvvtuBTh79uyt9913361cddVVV1111VVXXXXVVf+XoAc96EFcddVVV1111VVXXHPNNQ8GOHPmzINf7MVe7LV4phd/8Rd/bYAzZ848+JprrnkwL8B99913a9/3Dwa49dZbefCDH8zu7i7Hjx8H4Pjx4+zu7vKiOH78OAC7u7sA7O7uAnD8+HGe2+7uLs9td3eX++3u7nL8+HEAjh8/DsCDH/xgnp/77rvv1rNnz95633333QrwD//wD79z33333Xr27Nlb77vvvlu56qqrrrrqqquuuuqqq/43QQ960IO46qqrrrrqqv9PrrnmmgefOXPmwS/2Yi/2WgAv/uIv/toAL/ZiL/baPJdbb72V3d1ddnd3OX78OPc7fvw4u7u7ABw/fpzjx49z/Phxnp/d3V3ut7u7y/0e/OAH8x/p1ltv5X7Hjx/n+PHj3G93d5fjx4+zu7vL7u4uu7u7ANx6663s7u6yu7sLwIkTJzh+/DgAD3rQgwA4fvw4D37wgwH4h3/4h98GuO+++279rd/6re/5h3/4h9/mqquuuuqqq6666qqrrvqfDD3oQQ/iqquuuuqqq/6vuuaaax78Yi/2Yq995syZB734i7/4a7/Yi73Ya/MAf/3Xf83u7i4At956KwC7u7u89Eu/NAAPfvCDOX78OMePH+d+u7u77O7uslgsuPbaa3luR0dHAEhiuVwSEQzDQESQmdRaqbVSayUiKKUgCUlkJq01pmlitVoxDAPr9Zr1ek1EMI4jrTVaa0zTRGaSmWxsbJCZbG5uAmCbra0tALa3t9nZ2eG5/fVf/zXHjx/nwQ9+MAC7u7vceuutPOMZz+Cv//qveW7Hjx/nwQ9+MAAv9VIvxYMf/GDuu+++W//hH/7ht3/0R3/0c+67775bueqqq6666qqrrrrqqqv+p0EPetCDuOqqq6666qr/S6655poHv/Zrv/Z7vdM7vdNn80y33nort956K894xjO49dZbeaAHP/jBPOhBD+LBD34wD37wgwHY3d3l+PHjPNDBwQH7+/scHh5ycHCAJA4PDzk6OmK5XLJcLokISimUUiil0HUdXdfRdR2z2Yz5fM58Pmc+nzOfz5nNZnRdRykFgMxkmibW6zXr9ZrlcslyuWS5XLJarViv1wzDwDiOjOPINE201mit0VqjtUZmkpnYJjPJTGyztbVFZrKzs8P29ja2uemmmzh27BgPetCDeKDd3V1+53d+h7/5m7/hBTl+/DjHjh3jpV/6pbn++utv/dEf/dHP+a3f+q3v5qqrrrrqqquuuuqqq676n4TKVVddddVVV/0f8WIv9mKv/eEf/uHfdc011zz41ltv5bd/+7f5nd/5HV6Q13qt1+K1X/u12d3dZXd3lwc/+MEA7O3t8aQnPQlJ3H333RweHnJwcEBEIImIQBIRgSQigoggIgCwjW0AbGOb+9nGNraxjW1sYxtJ3E8SDyQJSUji32pvb4/M5NKlS2Qmmcnf/M3f0Fqjtcb29ja33HILL/MyL8PDHvYwXuu1XotnPOMZ7O7u8twkcenSJS5dusRtt93GS73USz34dV7ndd7rH/7hH377vvvuu5Wrrrrqqquuuuqqq6666n8KKlddddVVV131f8A7vuM7ftYbvdEbffbf/M3f8M3f/M3cTxLPz0u91Evx4Ac/GABJ3HXXXfzZn/0Zd911FxFBRBARSCIikMS/h21sYxvbANjGNi+MJCTxQJIAkIQkHkgS/x4XL17kwoULPOxhD+MZz3gGly5dQhIvyPHjx3nJl3xJXuu1Xot/+Id/4L777ruVq6666qqrrrrqqquuuup/EipXXXXVVVdd9X/Ay77sy773M57xDH7nd36HF8Xx48eRxN/8zd/wh3/4hxweHlJKISJ4UdlGEgC2sc0D2cY2tgGwjW1sY5v72cY2/xqS+LeQhG0Ajh07xk033cTOzg633HILD37wgwH43d/9Xb7+67+e3d1dJPFAx48f59ixYzzoQQ/iJV/yJTl+/Dj3e7EXe7HX5qqrrrrqqquuuuqqq676n4bKVVddddVVV/0vd8011zx4tVrxUi/1Ujzo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wja2sY1tAGxjGwDb2MY297PNv5VtXhjb2AbANgC2sY1tHsg2trENgG3+rSTxgkjiP8vFixe55pprHsxVV1111VVXXXXVVVdd9T8JwVVXXXXVVVf9HxERt9rGNgC2+beyzXOzzf1sA2Cb+9kGwDa2uZ9tAGxjG9vYxja2sc0D2eaFkcSLShL/USTx3CRxP0lcddVVV1111VVXXXXVVf/jEFx11VVXXXXV/xERcattbGObB7LNc7PNA9nm+bHNA9nmudkGwDb3s41tbGMb29jmfraxjW1sY5sXRhKSeCBJAEjigSTxryGJfy1J3E8SFy9e5JprrnkwV1111VVXXXXVVVddddX/JARXXXXVVVdd9X/IOI638ky2sY1tXhjbPD+2eVHY5oFsY5sHso1tAGxjG9s8N9u8KCTxL5HE/STxryWJq6666qqrrrrqqquuuup/PYKrrrrqqquu+j+ktXarbWzz3GxzP9s8P7Z5fmwDYJsXxDYPZBvb2OZ+trGNbQBsYxvb2AbANi8KSQBIAkASkvivJgkASVx11VVXXXXVVVddddVV/+MQXHXVVVddddX/Ia01bPOC2MY297MNgG2eH9u8ILaxDYBtAGzz/NjGNraxjW1sYxvb2AbANgC2sc39JPEfRRLPjyT+PS5evMiZM2cezFVXXXXVVVddddVVV131PwnBVVddddVVV/0f0lq71Ta2sY1tAGzzorLNv8Q297PNA9nGNraxjW0AbGOb+9nGNvezzf9UknhhJCGJq6666qqrrrrqqquuuup/HIKrrrrqqquu+j+ktXarbWxzP9s8P7b517ANgG1eVLaxjW3uZxvb2AbANraxjW1scz/bPDdJ/HeShCQAJHG/ixcvctVVV1111VVXXXXVVVf9j0Nw1VVXXXXVVf+HtNawDYBtbHM/2zw/tgGwzf1scz/b/EtsYxvbANjGNvezjW1sYxvbANjGNs/NNv8dJPFAknhRSeKaa655MFddddVVV1111VVXXXXV/yQEV1111VVXXfV/iKTfsY1tnh/b2MY2/xa2uZ9tbPPcbHM/29gGwDa2sY1tbGMbANvYBsA2L4gkHkgSAJL415DEv4UknpskJHHVVVddddVVV1111VVX/Y9EcNVVV1111VX/x2QmtrENgG1s86Kwzf1scz/bvCC2eW62sc39bPPcbGMb29gGwDYvCkm8IJJ4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be5nmxeVbZ6bbQBsYxvbPJBtbGMbANvYxja2sY1tAGwDYJv72ea5SeJfQxIPJInnRxJXXXXVVVddddVVV1111f8JBFddddVVV131/4RtbPOisM39bHM/2zyQbR7INg9kG9vY5oFsYxvb2AbANraxzXOzzYtCEs+PJP6zSWJ3dxeAM2fOPJirrrrqqquuuuqqq6666n8Cgquuuuqqq676Pygibs1MbGMb27wwtvnPZhvb2MY2D2SbB7KNbQBs859JEv8SSQBI4rlJQhIAkrjqqquuuuqqq6666qqr/kchuOqqq6666qr/o6ZputU297MNgG1eENvczzb3s839bANgm/vZ5n62sY1tAGxjGwDb2AbANraxjW1sYxvb/GtJ4j+aJP4tLl68yFVXXXXVVVddddVVV131PwbBVVddddVVV/0fNU3TrbaxjW0AbPPcbPPvYRsA2zw329zPNvezjW1sYxsA29jmfraxzQsiCQBJ/HtJ4j/SNddc82Cuuuqqq6666qqrrrrqqv8JCK666qqrrrrq/6jMxDbPj21sY5v72QbANvezzf1scz/bPD+2eW62sQ2AbWxjG9vczzb3s41t/j0k8YJI4t9LEpJ4fi5evMhVV1111VVXXXXVVVdd9T8GwVVXXXXVVVf9HzVN0622sY1tbPMfzTbPj21sY5v72ea52cY2trGNbWzzH0kS/1kkcT9JSALgzJkzD+Kqq6666qqrrrrqqquu+p+A4Kqrrrrqqqv+j8rMW23zQLaxzb/ENvezzf1s8y+xzXOzDYBtbGMb29jGNgC2uZ9tbGMb29jmP5sknpskrrrqqquuuuqqq6666qr/1Qiuuuqqq6666v+oaZqwjW1s88LYBsA2Lyrb3M82tnl+bANgGwDb2MY2trGNbQBsY5v/CJKQxH8USbwgkrjqqquuuuqqq6666qqr/kciuOqqq6666qr/oyLid2xjGwDb3M82tgGwzb/ENvezzQPZ5n62AbCNbWwDYBsA2zw/trGNbQBsYxvbPD+SeG6SeGEkcT9J/FtJ4oEkcT9J7O7ucs011zyYq6666qqrrrrqqquuuup/AoKrrrrqqquu+j/MNg9kG9vczzYviG3+LWzzQLYBsA2AbWxjG9vYxja2AbCNbe5nGwDb2OZfIol/K0n8R7jmmmsezFVXXXXVVVddddVVV131PwHBVVddddVV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17ANgG3uZxsA29jGNvezjW0AbPNAtvmPJIl/K0k80JkzZx7MVVddddVVV1111VVXXfVfjeCqq6666qqr/h9rrd1qG9sA2AbANi8q2zw329zPNvezjW1sY5v72eZ+tgGwzQPZxjb/0SQhCUlI4l8iCQBJvCCSuN+lS5e46qqrrrrqqquuuuqqq/7bEFx11VVXXXXV/2OZiW0AbANgm+dmmweyzQPZ5l9im+dmmweyDYBtAGxjG9v8d5PE8yOJF0QSV1111VVXXXXVVVddddV/K4Krrrrqqquu+n/M9jNsY5vnZhvb2OZ+tnlR2eZ+tnlBbANgGwDbANjmgWxjG9vYxjb3s82/hSSemyT+o128eJFrrrnmwVx11VVXXXXVVVddddVV/9UIrrrqqquuuur/MUm32gbANrZ5UdnmgWzz3GzzorANgG0AbANgG9vY5vmxjW0eyDb/XpK4nySuuuqqq6666qqrrrrqqv+1CK666qqrrrrq/zFJt9rGNvezjW2em20AbHM/2zyQbV4Y29jGNraxzf1s80C2eX5s8x9BEv/RJCGJB5LE7u4uZ86ceRBXXXXVVVddddVVV1111X81gquuuuqqq676f842trHNfwTbPJBtAGzz/NjmgWxzP9vczza2AbCNbR7INv+RJPHcJAEgCQBJ3E8SDySJq6666qqrrrrqqquuuuq/HcFVV1111VVX/T8WEbfa5n62uZ9t7mebF8Q2z802/xq2AbANgG3uZxvb/HeSxL+FJK666qqrrrrqqquuuuqq/1YEV1111VVXXfX/3DRNt9rGNs/NNra5n20AbPNAtnlutrmfbR7INraxzf1sA2AbANs8kG0AbHM/2wDY5l9DEi8KSfxbSOJ+ktjd3eWaa655MFddddVVV1111VVXXXXVfzWCq6666qqrrvp/rrV2q23uZxvb/GewjW0eyDb3sw2AbQBsYxvbANgGwDa2AbDNc7PNv4YkJCGJfwtJXHXVVVddddVVV1111VX/IxFcddVVV1111f9zmQmAbWzzorLNA9nmudnmRWGb52abB7LNv8Q2/16SeH4kASAJAEn8a1xzzTUP5qqrrrrqqquuuuqqq676r0Zw1VVXXXXVVf/PtdZutc1zs80D2QbANi+IbV4Q27wwtgGwzf1sYxvbANjGNvezzQtjm3+JJJ6bJO4niX+v3d1drrrqqquu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IQlJSEISAJKQxP0k8dxs88JI4r777ruVq6666qqrrrrqvwqVq6666qqrrrrqqquuuurfTNKD+R9MEveThCTuJwlJSEISkpCEJCQhCUlI4oEkIYl/i62tLa666qqrrrrqqv9SBFddddVVV1111VVXXXXVv5kkJPGCSOLfwjYviCT+tSRxP0lIQhKSkIQkJCEJSUhCEpKQBIAkJPFAkvjXODo6upWrrrrqqquuuuq/EsFVV1111VVXXXXVVVdd9W8mif8otnlBbPPCSOIFkcQLIwlJSEISEUFEIAlJAEhCEgCS+Lc6Ojq6lauuuuqqq6666r8SwVVXXXXVVVddddVVV131bxYRD+bfwDYvCtv8W0nigSQhCQBJSEISkpCEJCQhCUlIQhKSkASAJJ4f29jmX3LffffdylVXXXXVVVdd9V+JylVXXXXVVVddddVVV1317yIJSbwobCOJfy9JPDdJ3E8SL4gkACQhCUlIQhKSkIQkJCEJSQBI4n6S+NeyzebmJlddddVVV1111X8pgquuuuqqq6666qqrrrrq3ywiHsy/km3+s0hCEveTBIAkACQBIAkASQBIIiKQhCQkIQlJSAJAEpKQBIAkXhDbPD+r1epWrrrqqquuuuqq/0pUrrrqqquuuuqqq6666qr/0yQBIAkASUhCEgCSkIQkJCEJSUgCQBL/Ue65555ncNVVV1111VVX/VeictVVV1111VVXXXXVVVf9h5DEfyVJ/HtIQhKSkIQkJCEJSUhCEpIAkIQk/j26rruVq6666qqrrrrqvxKVq6666qqrrrrqqquuuurfrNb6YEk8kCT+J5DE/SQBIAlJSAJAEpKQhCQkIQlJSEISz00SkvjXsA3AfffddytXXXXVVVddddV/JYKrrrrqqquuuuqqq6666t/kdV7ndd7bNv/RbPOiksSLShIPJAlJSEISkogIIgJJSEISkpCEJCTxbyEJgGPHjnHVVVddddVVV/2XIrjqqquuuuqqq6666qqr/k1e53Ve5714Jkk8kCT+NWzzH0kSAJKQxP0kIQlJSEISkpCEJCQhCUlIQhKSkIQk/q1sA3DffffdylVXXXXVVVdd9V+J4Kqrrrrqqquuuuqqq676Nzl9+vRrA0jiP4NtAGzzwkjiX0sSkgCQhCQkIQlJSEISkpCEJAAk8W+1tbXFVVddddVVV131X47gqquuuuqqq6666qqrrvpXO3PmzIMAJPFAkvjvIIn7SeK5SUISkpDE/SQhCUlIQhKSkIQkJCEJAEkASOLf4ty5c7/NVVddddVVV131X43KVVddddVVV1111VVXXfWvds011zyY/2EkIYn7SQJAEg8kCUlIQhKSkIQkJCGJiEASkgCQxL/XfffddytXXXXVVVddddV/NSpXXXXVVVddddVVV1111b+ZJP4nk8T9JCEJAElIQhKSkIQkJCEJSUhCEgC2kYQkACTxgtjm+dna2uKqq6666qqrrvovR+Wqq6666qqrrrrqqquu+le77777br322mv530IS95MEgCQkIQlJRASSkIQkJCEJAEn8ex0dHd3KVVddddVVV131X43gqquuuuqqq6666qqrrvpXO3v27DMAHv3oR/M/kSReGEkASEISkpBERCAJSUgCQBKSkASAJF4Q27wgmclVV1111VVXXfVfjuCqq6666qqrrrrqqquu+jf5h3/4h99+zGMegyT+PWxzP9u8MJL415KEJCQhCUlIQhKSkIQkJCGJiEASkpDEA0niBbHNC/PKr/zKr81VV1111VVXXfVfjeCqq6666qqrrrrqqquu+jd7jdd4DQAkIYn/CpKQxAsiCQBJSOIFkQSAJCQhCUlIQhKSkIQkJCGJF8Q2z802D/Swhz3swVx11VVXXXXVVf/VCK666qqrrrrqqquuuuqqf5Mf+ZEf+ZzMvPVRj3oU/xUk8UCS+NeQhCQkIQlJSEISkpCEJCQhCUlIQhIviG1s86I4c+bMg7nqqquuuuqqq/6rEVx11VVXXXXVVVddddVV/yZnz5699ezZs7e+z/u8D//RbANgGwBJPD+SkMT9JPHcJCGJ+0lCEpKQhCQiAklIQhKSkIQkACQBIIl/q52dHa666qqrrrrqqv9yBFddddVVV1111VVXXXXVv8l9991364/8yI98zqlTp3izN3sz/jtJQhL3kwSAJO4nCUk8kCQkIQlJSEISkpCEJCQhCUkASOJFIYn7XXvttfzDP/zDb3PVVVddddVVV/1XI7jqqquuuuqqq6666qqr/s3Onj176z/8wz/89qu8yqvwiEc8gv9JJPH8SEISkpCEJCQREUhCEpKQBIAk/i1sc7/NzU3+/u///re56qqrrrrqqqv+qxFcddVVV1111VVXXXXVVf9m9913360/8iM/8jmnTp3iPd7jPTh58iT/00hCEpKQBIAkJCEJSUhCEhGBJCQhCUkASEISkvi3eNjDHsZVV1111VVXXfXfguCqq6666qqrrrrqqquu+nf5h3/4h9/+kR/5kc8+efIkH/mRH8l/N0m8IJKQBIAkJCEJSUhCEpKQBIAkJPHvcc0113Ddddfx27/929/DVVddddVVV131X43gqquuuuqqq6666qqrrvp3++3f/u3v+fu///vfPnnyJJ/5mZ/Ji8o297PNfzRJAEjifpKQhCQkIQlJSEISkpCEJCQhCUn8W73ES7wE//AP//Db9913361cddVVV1111VX/1Qiuuuqqq6666qqrrrrqqn+3++6779av//qvf+/77rvv1pMnT/Iu7/Iu/HeQBIAkJAEgCQBJSAJAEpKQhCQkIQlJSEISknggSbwgtnl+rrnmGq699lp+67d+63u46qqrrrrqqqv+OxBcddVVV1111VVXXXXVVf8hzp49+4zP+qzPep1/+Id/+O1XeIVX4NM+7dP4rySJF4UkJAEgCUlIQhKSkIQkJCEJSUjiX2tzc5PXeZ3X4b777rv1t37rt76bq6666qqrrrrqvwPBVVddddVVV1111VVXXfUf5r777rv167/+69/nvvvuu/XkyZN86qd+KidOnOBfwzYAtnlRSeKFkYQkJCEJAElIQhIRgSQkIQlJSEISDySJ52YbANvcb2Njgzd5kzfhvvvuu/Xrv/7r34errrrqqquuuuq/C8FVV1111VVXXXXVVVdd9R/qvvvuu/WzPuuzXue+++679cSJE3zwB38wr//6r89/JElIQhKSeCBJ3E8SknhukpCEJCQhCUlIQhIAkgCQBIAknpttnttiseAN3/ANAfit3/qt7/6Hf/iH3+aqq6666qqrrvrvQjl+/DhXXXXVVVddddVVV1111X+sw8PD3T/7sz/7mcPDw92Xf/mXf+2HPexhnDhxgrvvvpvVaoUkJAEgCUkASAJAEgCSkIQkJCGJiEASkpCEJCQhCUlEBBFBRBARRASlFEop1FqptdJ1HV3X0fc9fd/T9z1939N1HbVWSilEBJIAsE1rjWmamKaJcRwZhoFxHJmmiWmaaK1x/PhxXv3VXx2A3/qt3/ru7/qu7/oYrrrqqquuuuqq/06U48ePc9VVV1111VVXXXXVVVf9xzs8PNz9h3/4h98BePEXf/HXvuGGG3jsYx/LYrHg6U9/OpIAkIQkACQBIAkASUhCEpKICCQhCUlIQhKSkEREIImIICKICCKCUgqlFGqt1Frpuo6u6+j7nr7v6fuevu/puo5aK6UUIgJJ2CYzaa0xTRPTNDGOI+M4Mo4j0zQxTRPb29u8/Mu/PAC/9Vu/9d1f//Vf/z5cddVVV1111VX/3SjHjx/nqquuuuqqq6666qqrrvrP8w//8A+/89u//dvfs7m5efwxj3nMSz/0oQ/lZV/2ZVmtVtxzzz1IQhIAkgCQBIAkJCGJiEASkpCEJCQhCUlIIiKQREQQEZRSKKUQEdRaKaVQa6XrOrquo+97+r6n73v6vqfrOmqtlFKICO5nm8xkmiamaWIcR8ZxZBxHpmni+uuv59GPfjT33XffrX/6p3/601//9V//Plx11VVXXXXVVf8TUI4fP85VV1111VVXXXXVVVdd9Z/r8PBw90//9E9/5h/+4R9+58Ve7MVe+/Tp08cf+9jH8jIv8zKsVivuvvtuJCEJAEkASEISkogIJCEJSUhCEpKQREQgiYhAEqUUIoKIoJRCKYVaK7VWuq6j6zr6vmc2m9H3PX3f03UdtVZKKUQEkrBNZtJao7XGOI6M48g4jnRdx2Mf+1iOHTsGwM///M9/9Xd913d9DFddddVVV1111f8UlOPHj3PVVVddddVVV1111VVX/dc4e/bsrX/6p3/604eHh7vXXHPNg0+fPn38MY95DC/7si/LfD7n1ltvBUASAJKQhCQiAklIQhKSkIQkJBERSCIiiAgigoiglEJEUGullELXddRa6fuevu/p+56+7+n7nr7vqbVSSkESkgDITFprTNPEOI5kJidOnOD06dMA3Hfffbd+/Md//Mv86Z/+6c9w1VVXXXXVVVf9T0I5fvw4V1111VVXXXXVVVddddV/naOjo0v/8A//8Dt/9md/9jOHh4e711xzzYNPnTp1/CEPeQgv8zIvw/XXX898Pueee+5BEpKQREQgCUlIQhKSkEREIAlJRAQRQURQSiEiKKVQSqHWSq2Vruvo+56+7+n7nr7v6fueruuotVJKISIAsI1tpmmitUatlY2NDWqt3Hfffbd+13d918d8/dd//fscHh7uctVVV1111VVX/U+DHvSgB3HVVVddddVVV1111VVX/fe55pprHvxiL/Zir/U6r/M67/1iL/Zir80z7e7ucuutt/KMZzyD/f19br/9diKCiCAiiAgiglIKEUFEUEohIiilUEqh1kqtla7r6Pue2WzGbDZjsViwsbHBxsYGm5ubbG5uslgsWCwW9H1PrZVSCq01pmlitVqxXq+533333Xfrb/3Wb333j/7oj34OV1111VVXXXXV/2ToQQ96EFddddVVV1111VVXXXXV/ww/8RM/YYB/+Id/+O0Xe7EXe20e4NKlS9x+++3cfvvt7O/vc+edd1JKISKICCKCUgoRQSmFWiulFLquo+s6uq5jNpsxn89ZLBZsbGywsbHB5uYmm5ubLBYL5vM5pRQyk3EcGceRB7rvvvtu/a3f+q3v/tEf/dHP4aqrrrrqqquu+t+AylVXXXXVVVddddVVV131P8I111zzYID77rvv1s/8zM98nTNnzjzoxV/8xV/nxV7sxV7rdV7ndd772LFjHDt2jBd/8Rfnfnt7e+zv77O/v8/dd99NRHB4eEgphaOjI2qtlFLouo6u6+j7np2dHWazGdvb2ywWC/q+p+97bLNcLnmg++6771aAH/3RH/3sf/iHf/id++6771auuuqqq6666qr/TahcddVVV1111VVXXXXVVf8jnDlz5sEAZ8+evRXg7Nmzz/it3/qt7/6t3/qt7/7RH/3RzwF4sRd7sdd6sRd7sde+5pprHvxiL/Zir72zs8POzg4Aj370o/n3uu+++249e/bsM/7+7//+t/7hH/7hd/7hH/7ht7nqqquuuuqqq/43o3LVVVddddVVV1111VVX/Y9333333Qpw33333fpbv/Vb3wNwzTXXPBjgxV7sxV4L0Iu92Iu9FsA111zz4Pvuu+8Z11xzzYPOnDnzYJ6Ps2fP3nrffffd+g//8A+/febMmQf/wz/8w++cPXv21vvuu+9Wrrrqqquuuuqq/0uoXHXVVVddddVVV1111VX/I1xzzTUPBrjvvvtu5UVw33333Qpw33333QrwW7/1W9/NVVddddVVV1111XOictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV131P8KZM2ceBHDffffdylVXXXXVVVddddV/DCpXXXXVVVddddVVV1111f8I11xzzYMBzp49+wyuuuqqq6666qqr/mNQueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq676H+Gaa655MMB99913K1ddddVVV1111VX/MahcddVVV1111VVXXXXVVf8jnDlz5sEAZ8+evZWrrrrqqquuuuqq/xhUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VX/I1xzzTUPBrjvvvtu5aqrrrrqqquuuuo/BpWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqv92Z86ceRDAfffddytXXXXVVVddddVV/3GoXHXVVVddddVVV1111VX/7a655poHA5w9e/ZWrrrqqquuuuqqq/7jULnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVX/be75pprHgxw33333cpVV1111VVXXXXVfxwqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qr/dmfOnHkwV1111VVXXXXVVf/xqFx11VVXXXXVVVddddVV/2Pcd999t3LVVVddddVVV131H4fKVVddddVVV1111VVXXfXf5pprrnkwwDXXXPNgnumaa6558H333XcrV1111VVXXXXVVf9+6EEPehBXXXXVVVddddVVV1111X+Pz/3cz/2tF3uxF3ttnstnfuZnvs4//MM//DZXXXXVVVddddVV/z5Urrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq676b3PffffdeubMmVu56qqrrrrqqquu+s+BHvSgB3HVVVddddVVV1111VVXXXXVVVddddVVV/2fROWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q/hHxnvfrjXTaKAAAAAASUVORK5CYII=) @@ -64,7 +70,7 @@ sweepSketch = startSketchOn(XY) import "tests/inputs/cube.sldprt" as cube cube - |> translate(translate = [1.0, 1.0, 2.5]) + |> translate(x = 1.0, y = 1.0, z = 2.5) ``` ![Rendered example of translate 1](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAADPfd1WAAEoMUlEQVR4Ae3AA6AkWZbG8f937o3IzKdyS2Oubdu2bdu2bdu2bWmMnpZKr54yMyLu+Xa3anqmhztr1a8+6EEP4qqrrrrqqquuuuqqq6666qqrrrrqqquu+j+JylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispV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7yIJSUhCEpKQhCQkIQlJSEISkpCEJCQhCUlIQhKSkIQkJCEJSUhCEpKQxFX/dSQhCUlIQhKSkIQkJCEJSUhCEpKQhCQk8a+xWq245557uO6667jpppuOv+IrvuJb/9mf/dnPHB4e7nLVVVddddVV/7Uox48f56qrrrrqqqv+q334h3/4d73O67zOewN893d/N894xjOQhCQkIQlJSEISkpCEJCQhCUlIQhKSkIQkJHHVVVdd9b+BJCQhCUlIQhKSkIQkJCEJSUhCEpKQhCQkIQlJSEISkpCEJCRx1X8MSUhCEpKQhCQkIQlJSEISkliv19x6661cf/313Hjjjcdf8RVf8a3/7M/+7GcODw93ueqqq6666qr/OpTjx49z1VVXXXXVVf+V3vEd3/Gz3vzN3/yjAb77u7+bW2+9lauuuuqqq/7zSEISkpCEJCQhCUlIQhKSkIQkJCEJSUhCEpKQhCQkcdW/bLVaceutt3L99ddz4403Hn/FV3zFt/6zP/uznzk8PNzlqquuuuqqq/5roAc96EFcddVVV1111X+V13md13nvD//wD/8ugO/+7u/m1ltv5ar/vSRx1f8/trnqqv8Mtvm/6vjx47zN27wND37wg7nvvvtu/azP+qzXue+++27lqquuuuqqq/7zoQc96EFcddVVV1111X+F13md13nvD//wD/8ugO/+7u/m1ltv5SqQxFVXXfWfzzZX/f9gm/+Jjh8/zvu8z/tw/Phx7rvvvls/67M+63Xuu+++W7nqqquuuuqq/1zoQQ96EFddddVVV131n+11Xud13vvDP/zDvwvgu7/7u7n11lv5n0ISV1111VX/2Wxz1f8etvnPcPz4cd7nfd6H48ePc9999936IR/yIQ/hqquuuuqqq/5zoQc96EFcddVVV1111X+mF3uxF3vtz/3cz/0tgJ/+6Z/mr//6r/mXSOKqq6666qp/Pdtc9d/PNi/I8ePHeZ/3eR+OHz/Offfdd+uHfMiHPISrrrrqqquu+s+DHvSgB3HVVVddddVV/1le7MVe7LU/93M/97cAfuZnfoa//uu/5qqrrrrqqv99bHPVf5zjx4/z3u/93hw/fpz77rvv1g/5kA95CFddddVVV131nwM96EEP4qqrrrrqqqv+M7zYi73Ya3/u537ubwH8zM/8DH/913/NVVfdTxJX/c9im6uu+q9im//v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6qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxX/CLxmtEtY/1t9AAAAAElFTkSuQmCC) @@ -98,7 +104,12 @@ sweepPath = startProfileAt([0, 0], sketch002) parts = sweep([rectangleSketch, circleSketch], path = sweepPath) // Move the sweeps. -translate(parts, translate = [1.0, 1.0, 2.5]) +translate( + parts, + x = 1.0, + y = 1.0, + z = 2.5, +) ``` ![Rendered example of translate 2](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAADPfd1WAAFhlUlEQVR4Ae3AA6AkWZbG8f937o3IzKdyS2Oubdu2bdu2bdu2bWmMnpZKr54yMyLu+Xa3anqmhztr1a8+6EEP4qqrrrrqqquuuuqqq6666qqrrrrqqquu+j+JylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXfU/3ju+4zt+1jXXXPNg/g/70R/9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vCC2eSDb2MY2trGNbWxjGwBJSCIiiAgigohAEpKICCQhCUlIQhKSAJCEJCQxm80ezFVXXXXV/zHXXHPNgy9cuMCL6uTJkwAcHh7yopLEi0IS/988/OEPB+Af/uEffpurrrrqqquuejaCq6666qqrrvpPEBG3ttZutY1t/iW2AbDN82Ob+9nmudnGNraxzb+GbQBsYxsA29jGNs9NEpKICCKCiCAikIQkJCEJSdxPEg/U9/2Dueqqq676P+bMmTMP5l9gm/udOHECgMPDQyRx1XOyzb/FfffddytXXXXVVVdd9WwEV1111VVXXfWfpLV2a2ZiG9vYxja2eSDbPJBt/iW2+deyjW3uZxvbANjmfrYBsI1tbGMbAElIIiKICCKCiCAiiAgkIYn7SUISAJKQhCQkcdVVV131f9GFCxe46oWzzX8k2wBcf/31ANx33323ctVVV1111VXPRnDVVVddddVV/0laa7faxja2eSDb2MY297PN/WxjmweyzQPZ5kVhG9vczzbPj21sYxvb2MY2trmfJCQhiYggIogIIgJJSEISkpDECzKbzR7MVVddddX/Mddcc82DL1y4wIvCNidPngTg8PAQAEm8KCTxH0US/9ecPXv2GVx11VVXXXXVsxFcddVVV1111X+S1tqtmYltAGxjG9s8N9sA2OaBbGOb+9nmgWxjm+fHNrZ5fmxzP9vczza2sY1tbGObB5JERBARRAQRgSQiAklIQhIAkpCEJO4nicVi8WCuuuqqq/4Pueaaax7Mv8KJEye46j/WddddB8A//MM//DZXXXXVVVdd9WwEV1111VVXXfWfJDOfYRvb2MY297PNv4Zt7meb52Yb29jGNrb517CNbQBsYxvb2AbANveThCQigoggIogIJBERSEISknggSUgCwDallAdz1VVXXfV/xJkzZx4McP78eV4UJ0+eBOC+++7jP4sk/qNI4n+6ra0trrrqqquuuur5ILjqqquuuuqq/yS2b81MbGMbANvYBsA2trENgG0AbPP82OZ+tvn3so1tHsg2ALaxjW1scz9JSCIikEREEBFEBBGBJCQhCUlIQhKSuJ8kJFFKeTBXXXXVVf9HXHPNNQ/mX+HkyZMAHB4e8kCSeFFI4iqwzXO77777buWqq6666qqrno3gqquuuuqqq/6TRMSttrENgG1eVLb5l9jmRWUb29jGNg9kG9vYxja2sY1tbGMb29xPEpKICCKCiCAikIQkJPGCSAJAEhHBVVddddX/JRcuXOA/giT+v7PNv8Z1110HwD/8wz/8NlddddVVV131nAiuuuqqq6666j9JRNxqG9vYBsA2ALZ5INsA2OZ+trHNA9nmgWxjmxfENrZ5brZ5QWxjG9vYxja2sc39JBERRAQRQUQQEUQEkpCEJCQBIAlJAEgCoOu6B3PVVVdd9X/I+fPneVGdOHECgMPDQ/6tJPEvkcT/B1tbWwDcd999t3LVVVddddVVz4ngqquuuuqqq/4TjeP427axjW0AbANgG9vY5oFs80C2sc39bPPcbGMb29jGNrb5l9gGwDa2sY1tbGMb29jmgSQhCUlEBBFBRBARSEISkpAEgCTuJwkASfR9/yCuuuqqq/6POHPmzIMuXLgAgG3+JSdPngTg8PCQ50cS/1Uk8b/d1tYWAPfdd9+tXHXVVVddddVzIrjqqquuuuqq/0SZSWZiG9vYBsA2z802L4xt7mebfy/bANjmfrYBsI1tbGMb2zyQJCICSUQEEUFEEBFEBJKQhCTuJwkASUgiIrjqqv+NrrnmmgcD3Hfffbdy1VXPdM011zyYq/7bbG9vA3D27NlncNVVV1111VXPieCqq6666qqr/hO11n7bNra5n22em20eyDa2eW62uZ9t/iPZBsA2ALaxjW1sYxsASUhCEhFBRBARRASSkIQkACQhCUk8t/l8/mCuuuqqq/4POX/+PA9kmxfkxIkTABweHvKCSOJfIol/iST+L7LN/a677joA/uEf/uG3ueqqq6666qrnRHDVVVddddVV/4nGcSQzsY1tbHM/29jGNvezzQPZ5oWxzYvCNraxjW1sA2AbANsA2MY2trGNbWxjmweSREQQEZRSiAgkERFIQhKSAJAEgCQkIQlJ9H3/YK666qqr/o94sRd7sde+cOECz49tntvJkycBODw85IWRxFX/sq2tLa666qqrrrrqBSC46qqrrrrqqv9EEfE7trGNbQBsY5vnZhsA2zyQbWxjGwDbPJBtbGObB7KNbWzzwtgGwDYAtrGNbWxjG9vYBkASkpBERBARRAQRQUQQEUhCEpIAkMQDSUISV1111VX/X508eRKAw8ND/r0k8e8liX+JJP6nu++++27lqquuuuqqq54TwVVXXXXVVVf957o1M7ENgG3uZ5sXxDYv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/ujn/PZv//b3vNiLvdhrv87rvM57vdiLvdhrv8zLvAwv8zIvw9u8zduwu7vLM57xDJ7xjGdw6dIl9vb22N/fxzaSsI0kAGwjifttb2+zs7PDjTfeiCRuuOEGbrjhBp7bfffdd+tv/dZvffdv//Zvf8999913K1dd9X/U537u5/7WmTNnHswzfe7nfu5vA/7Mz/zM1+Gq/3f+4R/+4Xde//Vfn+d26tQpAGwjCUnY5kUhCdv8S2wjiedmG0k8N9tI4oFsI4n72UYSALYBkIRtACRhGwBJ2EYSALaRhG0kYRtJ2AZAEraRhG0eSBK2OX36NAD/8A//8DtcddVVV1111X88KlddddVVV131v9h9991363333ffdv/Vbv/XdZ86cedCLv/iLv87rvM7rvNeLvdiLvfbx48c5fvw4L/VSL8UDXbp0iftJ4oF2dnZ4Ye67775bf+u3fuu7AX70R3/0c7jqqv8Hzpw586AXe7EXe22e6ZprrnnwNddc8+D77rvvVq76f+ns2bO3njp1ikc+8pE86UlPwjaSuJ8kJHE/SdjmP5ttJPHcbCOJB7KNJO5nG0nczzaSALCNJABsIwnbSALANpKwjSRsIwkA20jCNpKwjSRsc9VVV1111VX/RahcddVVV1111f8RZ8+efcZv/dZvffdv/dZvffc111zzYIAXe7EXe60Xe7EXe+1rrrnmwWfOnHnwNddc8+Bjx44BcN999916zTXXPPi+++679ZprrnkwD/AP//APv33ffffdCnDffffd+g//8A+/8w//8A+/zVVXXXXVVdx33323/sM//MNvA6/NA5w6dQqAzEQSz00StgGQhG1eEEnY5l/LNpJ4braRxAPZRhL3s40k7mcbSQDYRhIAtpGEbQAkYRtJ2EYStgGQhG0kYRtJ2EYStpHEqVOnAPiHf/iH3+aqq6666qqr/uNRueqqq6666qr/g+67775bAe67775bf+u3fut7eIAzZ848SJJ4ANuWpPvuu+9WrrrqqquuepE88pGP5ElPehIAp06dAiAzkYQkbCMJ27wwkrDNfxTbSOK52QZAEvezDYAkAGwDIAkA20gCwDaSALCNJABsIwnbSMI2AJKwjSRsIwnbSMI2krDNYrEA4L777ruVq6666qqrrvqPR+Wqq6666qqr/p85e/bsM7jqqquuuurf5e///u9/+/Vf//Vf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XXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V/FPwJhlSKfKyi8AQAAAABJRU5ErkJggg==) @@ -123,7 +134,7 @@ fn square(length) { } square(10) - |> translate(translate = [5, 5, 0]) + |> translate(x = 5, y = 5, z = 0) |> extrude(length = 10) ``` @@ -145,7 +156,7 @@ fn square() { profile001 = square() profile002 = square() - |> translate(translate = [0, 0, 20]) + |> translate(x = 0, y = 0, z = 20) |> rotate(axis = [0, 0, 1.0], angle = 45) loft([profile001, profile002]) diff --git a/e2e/playwright/basic-sketch.spec.ts b/e2e/playwright/basic-sketch.spec.ts index 192b8a41b..3cb1e78fb 100644 --- a/e2e/playwright/basic-sketch.spec.ts +++ b/e2e/playwright/basic-sketch.spec.ts @@ -85,7 +85,7 @@ async function doBasicSketch( await page.mouse.click(startXPx, 500 - PUR * 20) if (openPanes.includes('code')) { await expect(u.codeLocator) - .toHaveText(`sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${ + .toHaveText(`@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${ commonPoints.startAt }, sketch001) |> xLine(length = ${commonPoints.num1}) @@ -119,10 +119,7 @@ async function doBasicSketch( await page.waitForTimeout(100) if (openPanes.includes('code')) { - await expect( - await u.getGreatestPixDiff(line1, TEST_COLORS.BLUE) - ).toBeLessThan(3) - await expect(await u.getGreatestPixDiff(line1, [0, 0, 255])).toBeLessThan(3) + expect(await u.getGreatestPixDiff(line1, TEST_COLORS.BLUE)).toBeLessThan(3) } // hold down shift @@ -145,7 +142,7 @@ async function doBasicSketch( // Open the code pane. await u.openKclCodePanel() await expect(u.codeLocator) - .toHaveText(`sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${ + .toHaveText(`@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${ commonPoints.startAt }, sketch001) |> xLine(length = ${commonPoints.num1}, tag = $seg01) diff --git a/e2e/playwright/can-create-sketches-on-all-planes-and-their-back-sides.spec.ts b/e2e/playwright/can-create-sketches-on-all-planes-and-their-back-sides.spec.ts index bb87b7a31..b8e1b9ff0 100644 --- a/e2e/playwright/can-create-sketches-on-all-planes-and-their-back-sides.spec.ts +++ b/e2e/playwright/can-create-sketches-on-all-planes-and-their-back-sides.spec.ts @@ -46,7 +46,7 @@ test.describe( }, } - const code = `sketch001 = startSketchOn(${plane})profile001 = startProfileAt([0.91, -1.22], sketch001)` + const code = `@settings(defaultLengthUnit = in)sketch001 = startSketchOn(${plane})profile001 = startProfileAt([0.91, -1.22], sketch001)` await u.openDebugPanel() diff --git a/e2e/playwright/code-pane-and-errors.spec.ts b/e2e/playwright/code-pane-and-errors.spec.ts index daa21d20d..1908ab38d 100644 --- a/e2e/playwright/code-pane-and-errors.spec.ts +++ b/e2e/playwright/code-pane-and-errors.spec.ts @@ -251,11 +251,11 @@ test( ]) await Promise.all([ fsp.copyFile( - executorInputPath('router-template-slate.kcl'), + executorInputPath('cylinder-inches.kcl'), join(routerTemplateDir, 'main.kcl') ), fsp.copyFile( - executorInputPath('focusrite_scarlett_mounting_braket.kcl'), + executorInputPath('e2e-can-sketch-on-chamfer.kcl'), join(bracketDir, 'main.kcl') ), ]) diff --git a/e2e/playwright/desktop-export.spec.ts b/e2e/playwright/desktop-export.spec.ts index 91e340907..c4d32ccd1 100644 --- a/e2e/playwright/desktop-export.spec.ts +++ b/e2e/playwright/desktop-export.spec.ts @@ -20,11 +20,11 @@ test( await Promise.all([fsp.mkdir(bracketDir, { recursive: true })]) await Promise.all([ fsp.copyFile( - executorInputPath('router-template-slate.kcl'), + executorInputPath('cylinder-inches.kcl'), path.join(bracketDir, 'other.kcl') ), fsp.copyFile( - executorInputPath('focusrite_scarlett_mounting_braket.kcl'), + executorInputPath('e2e-can-sketch-on-chamfer.kcl'), path.join(bracketDir, 'main.kcl') ), ]) @@ -107,7 +107,7 @@ test( }, { timeout: 15_000 } ) - .toBeGreaterThan(300_000) + .toBeGreaterThan(30_000) }) }) @@ -187,7 +187,7 @@ test( }, { timeout: 15_000 } ) - .toBeGreaterThan(70_000) + .toBeGreaterThan(50_000) }) }) } diff --git a/e2e/playwright/editor-tests.spec.ts b/e2e/playwright/editor-tests.spec.ts index 6b8f0c50a..739236857 100644 --- a/e2e/playwright/editor-tests.spec.ts +++ b/e2e/playwright/editor-tests.spec.ts @@ -32,26 +32,30 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => { await page.keyboard.press('/') await page.keyboard.up('ControlOrMeta') - await expect(page.locator('.cm-content')) - .toHaveText(`sketch001 = startSketchOn(XY) + await expect(page.locator('.cm-content')).toHaveText( + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XY) |> startProfileAt([-10, -10], %) |> line(end = [20, 0]) |> line(end = [0, 20]) |> line(end = [-20, 0]) - // |> close()`) + // |> close()`.replaceAll('\n', '') + ) // uncomment the code await page.keyboard.down('ControlOrMeta') await page.keyboard.press('/') await page.keyboard.up('ControlOrMeta') - await expect(page.locator('.cm-content')) - .toHaveText(`sketch001 = startSketchOn(XY) + await expect(page.locator('.cm-content')).toHaveText( + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XY) |> startProfileAt([-10, -10], %) |> line(end = [20, 0]) |> line(end = [0, 20]) |> line(end = [-20, 0]) - |> close()`) + |> close()`.replaceAll('\n', '') + ) }) test('ensure we use the cache, and do not re-execute', async ({ @@ -178,13 +182,15 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => { await page.locator('#code-pane button:first-child').click() await page.locator('button:has-text("Format code")').click() - await expect(page.locator('.cm-content')) - .toHaveText(`sketch001 = startSketchOn(XY) + await expect(page.locator('.cm-content')).toHaveText( + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XY) |> startProfileAt([-10, -10], %) |> line(end = [20, 0]) |> line(end = [0, 20]) |> line(end = [-20, 0]) - |> close()`) + |> close()`.replaceAll('\n', '') + ) }) test('if you click the format button it formats your code and executes so lints are still there', async ({ @@ -227,13 +233,15 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => { await u.expectCmdLog('[data-message-type="execution-done"]') await u.closeDebugPanel() - await expect(page.locator('.cm-content')) - .toHaveText(`sketch_001 = startSketchOn(XY) + await expect(page.locator('.cm-content')).toHaveText( + `@settings(defaultLengthUnit = in) +sketch_001 = startSketchOn(XY) |> startProfileAt([-10, -10], %) |> line(end = [20, 0]) |> line(end = [0, 20]) |> line(end = [-20, 0]) - |> close()`) + |> close()`.replaceAll('\n', '') + ) // error in guter await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible() @@ -471,6 +479,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => { test('if you write kcl with lint errors you get lints', async ({ page, homePage, + scene, }) => { const u = await getUtils(page) await page.setBodyDimensions({ width: 1000, height: 500 }) @@ -490,10 +499,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => { await page.keyboard.press('ArrowLeft') await page.keyboard.press('ArrowRight') - // FIXME: lsp errors do not propagate to the frontend until engine is connected and code is executed - // This timeout is to wait for engine connection. LSP and code execution errors should be handled differently - // LSP can emit errors as fast as it waits and show them in the editor - await page.waitForTimeout(10000) + await scene.waitForExecutionDone() // error in guter await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible() @@ -815,10 +821,12 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => { // there shouldn't be any auto complete options for 'lin' in the comment await expect(page.locator('.cm-completionLabel')).not.toBeVisible() - await expect(page.locator('.cm-content')) - .toHaveText(`sketch001 = startSketchOn(XZ) + await expect(page.locator('.cm-content')).toHaveText( + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) |> startProfileAt([3.14, 12], %) - |> xLine(%, length = 5) // lin`) + |> xLine(%, length = 5) // lin`.replaceAll('\n', '') + ) // expect there to be no KCL errors await expect(page.locator('.cm-lint-marker-error')).toHaveCount(0) @@ -888,10 +896,12 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => { // there shouldn't be any auto complete options for 'lin' in the comment await expect(page.locator('.cm-completionLabel')).not.toBeVisible() - await expect(page.locator('.cm-content')) - .toHaveText(`sketch001 = startSketchOn(XZ) + await expect(page.locator('.cm-content')).toHaveText( + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) |> startProfileAt([3.14, 12], %) - |> xLine(%, length = 5) // lin`) + |> xLine(%, length = 5) // lin`.replaceAll('\n', '') + ) }) }) test('Can undo a click and point extrude with ctrl+z', async ({ @@ -1206,4 +1216,55 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => { }) } ) + + test('Rectangle tool panning with middle click', async ({ + page, + homePage, + toolbar, + scene, + cmdBar, + editor, + }) => { + await page.setBodyDimensions({ width: 1200, height: 900 }) + await homePage.goToModelingScene() + + // wait until scene is ready to be interacted with + await scene.connectionEstablished() + await scene.settled(cmdBar) + + await page.getByRole('button', { name: 'Start Sketch' }).click() + + // select an axis plane + await page.mouse.click(700, 200) + + // Needed as we don't yet have a way to get a signal from the engine that the camera has animated to the sketch plane + await page.waitForTimeout(1000) + + const middleMousePan = async ( + startX: number, + startY: number, + endX: number, + endY: number + ) => { + const initialCode = await editor.getCurrentCode() + + await page.mouse.click(startX, startY, { button: 'middle' }) + await page.mouse.move(endX, endY, { + steps: 10, + }) + + // We expect the code to be the same, middle mouse click should not modify the code, only do panning + await editor.expectEditor.toBe(initialCode) + } + + await test.step(`Verify corner rectangle panning`, async () => { + await page.getByTestId('corner-rectangle').click() + await middleMousePan(800, 500, 900, 600) + }) + + await test.step(`Verify center rectangle panning`, async () => { + await toolbar.selectCenterRectangle() + await middleMousePan(800, 200, 900, 300) + }) + }) }) diff --git a/e2e/playwright/fixtures/editorFixture.ts b/e2e/playwright/fixtures/editorFixture.ts index ea393c26a..3304a8a66 100644 --- a/e2e/playwright/fixtures/editorFixture.ts +++ b/e2e/playwright/fixtures/editorFixture.ts @@ -81,6 +81,13 @@ export class EditorFixture { expectEditor = { toContain: this._expectEditorToContain(), not: { toContain: this._expectEditorToContain(true) }, + toBe: async (code: string) => { + const currentCode = await this.getCurrentCode() + return expect(currentCode).toBe(code) + }, + } + getCurrentCode = async () => { + return await this.codeContent.innerText() } snapshot = async (options?: { timeout?: number; name?: string }) => { const wasPaneOpen = await this.checkIfPaneIsOpen() diff --git a/e2e/playwright/fixtures/sceneFixture.ts b/e2e/playwright/fixtures/sceneFixture.ts index d7189a672..b47538345 100644 --- a/e2e/playwright/fixtures/sceneFixture.ts +++ b/e2e/playwright/fixtures/sceneFixture.ts @@ -310,7 +310,9 @@ export async function expectPixelColor( .toBeTruthy() .catch((cause) => { throw new Error( - `ExpectPixelColor: expecting ${colour} got ${finalValue}`, + `ExpectPixelColor: point ${JSON.stringify( + coords + )} was expecting ${colour} but got ${finalValue}`, { cause } ) }) diff --git a/e2e/playwright/lib/console-error-whitelist.ts b/e2e/playwright/lib/console-error-whitelist.ts index 8fa83cec5..c5b396274 100644 --- a/e2e/playwright/lib/console-error-whitelist.ts +++ b/e2e/playwright/lib/console-error-whitelist.ts @@ -258,14 +258,6 @@ export const isErrorWhitelisted = (exception: Error) => { foundInSpec: 'e2e/playwright/testing-settings.spec.ts', }, // TODO: fix this error in the code - { - name: 'TypeError', - message: "Cannot read properties of undefined (reading 'length')", - stack: '', - project: 'Google Chrome', - foundInSpec: '', // many tests are impacted by this error - }, - // TODO: fix this error in the code { name: 'ReferenceError', message: '_testUtils is not defined', diff --git a/e2e/playwright/machines.spec.ts b/e2e/playwright/machines.spec.ts index 097e522de..113f59ffc 100644 --- a/e2e/playwright/machines.spec.ts +++ b/e2e/playwright/machines.spec.ts @@ -11,7 +11,7 @@ test( const bracketDir = join(dir, 'bracket') await fsp.mkdir(bracketDir, { recursive: true }) await fsp.copyFile( - executorInputPath('focusrite_scarlett_mounting_braket.kcl'), + executorInputPath('cylinder-inches.kcl'), join(bracketDir, 'main.kcl') ) }) @@ -51,7 +51,7 @@ test( const bracketDir = join(dir, 'bracket') await fsp.mkdir(bracketDir, { recursive: true }) await fsp.copyFile( - executorInputPath('focusrite_scarlett_mounting_braket.kcl'), + executorInputPath('cylinder-inches.kcl'), join(bracketDir, 'main.kcl') ) }) diff --git a/e2e/playwright/point-click.spec.ts b/e2e/playwright/point-click.spec.ts index edfb181c5..4be3ac008 100644 --- a/e2e/playwright/point-click.spec.ts +++ b/e2e/playwright/point-click.spec.ts @@ -137,7 +137,7 @@ test.describe('Point-and-click tests', () => { await scene.moveCameraTo(cameraPos, cameraTarget) - await test.step('check chamfer selection changes cursor positon', async () => { + await test.step('check chamfer selection changes cursor position', async () => { await expect(async () => { // sometimes initial click doesn't register await clickChamfer() @@ -173,7 +173,7 @@ test.describe('Point-and-click tests', () => { }) await test.step('Check there is no errors after code created in previous steps executes', async () => { await editor.expectState({ - activeLines: ['sketch001 = startSketchOn(XZ)'], + activeLines: ['@settings(defaultLengthUnit = in)'], highlightedCode: '', diagnostics: [], }) @@ -299,7 +299,8 @@ test.describe('Point-and-click tests', () => { await test.step('verify at the end of the test that final code is what is expected', async () => { await editor.expectEditor.toContain( - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) |> startProfileAt([75.8, 317.2], %) // [$startCapTag, $EndCapTag] |> angledLine([0, 268.43], %, $rectangleSegmentA001) |> angledLine([ @@ -369,7 +370,7 @@ profile001 = startProfileAt([205.96, 254.59], sketch002) }) }) - test('Works on chamfers that are non in a pipeExpression can break up multi edges in a chamfer array', async ({ + test('Works on chamfers that are not in a pipeExpression can break up multi edges in a chamfer array', async ({ context, page, homePage, @@ -418,7 +419,8 @@ profile001 = startProfileAt([205.96, 254.59], sketch002) |>close()`, }) await editor.expectEditor.toContain( - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) |> startProfileAt([75.8, 317.2], %) |> angledLine([0, 268.43], %, $rectangleSegmentA001) |> angledLine([ @@ -1639,9 +1641,10 @@ loft001 = loft([sketch001, sketch002]) { targetType: 'circle', testPoint: { x: 700, y: 250 }, - initialCode: `sketch001 = startSketchOn('YZ') + initialCode: `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(YZ) profile001 = circle(sketch001, center = [0, 0], radius = 500) -sketch002 = startSketchOn('XZ') +sketch002 = startSketchOn(XZ) |> startProfileAt([0, 0], %) |> xLine(length = -500) |> tangentialArcTo([-2000, 500], %)`, @@ -1649,7 +1652,8 @@ sketch002 = startSketchOn('XZ') { targetType: 'rectangle', testPoint: { x: 710, y: 255 }, - initialCode: `sketch001 = startSketchOn('YZ') + initialCode: `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(YZ) profile001 = startProfileAt([-400, -400], sketch001) |> angledLine([0, 800], %, $rectangleSegmentA001) |> angledLine([ @@ -1662,7 +1666,7 @@ profile001 = startProfileAt([-400, -400], sketch001) ], %) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() -sketch002 = startSketchOn('XZ') +sketch002 = startSketchOn(XZ) |> startProfileAt([0, 0], %) |> xLine(length = -500) |> tangentialArcTo([-2000, 500], %)`, @@ -1806,7 +1810,8 @@ sketch002 = startSketchOn('XZ') toolbar, cmdBar, }) => { - const initialCode = `sketch001 = startSketchOn(YZ) + const initialCode = `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(YZ) |> circle( center = [0, 0], radius = 500 @@ -2475,7 +2480,8 @@ extrude001 = extrude(profile001, length = 5) cmdBar, }) => { // Code samples - const initialCode = `sketch001 = startSketchOn(XY) + const initialCode = `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XY) |> startProfileAt([-12, -6], %) |> line(end = [0, 12]) |> line(end = [24, 0]) @@ -2767,7 +2773,8 @@ extrude001 = extrude(sketch001, length = -12) toolbar, }) => { // Code samples - const initialCode = `sketch001 = startSketchOn(XY) + const initialCode = `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XY) |> startProfileAt([-12, -6], %) |> line(end = [0, 12]) |> line(end = [24, 0], tag = $seg02) @@ -2921,7 +2928,8 @@ chamfer04 = chamfer(extrude001, length = 5, tags = [getOppositeEdge(seg02)]) toolbar, cmdBar, }) => { - const initialCode = `sketch001 = startSketchOn(XZ) + const initialCode = `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) |> circle(center = [0, 0], radius = 30) extrude001 = extrude(sketch001, length = 30) ` @@ -3056,7 +3064,8 @@ extrude001 = extrude(sketch001, length = 30) toolbar, cmdBar, }) => { - const initialCode = `sketch001 = startSketchOn(XY) + const initialCode = `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XY) |> startProfileAt([-20, 20], %) |> xLine(length = 40) |> yLine(length = -60) @@ -3174,7 +3183,8 @@ extrude001 = extrude(sketch001, length = 40) }) const shellSketchOnFacesCases = [ - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) |> circle(center = [0, 0], radius = 100) |> extrude(length = 100) @@ -3182,7 +3192,8 @@ sketch002 = startSketchOn(sketch001, 'END') |> circle(center = [0, 0], radius = 50) |> extrude(length = 50) `, - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) |> circle(center = [0, 0], radius = 100) extrude001 = extrude(sketch001, length = 100) @@ -3578,7 +3589,8 @@ radius = 8.69 toolbar, cmdBar, }) => { - const initialCode = `sketch001 = startSketchOn(XZ) + const initialCode = `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) profile001 = circle( sketch001, center = [0, 0], diff --git a/e2e/playwright/projects.spec.ts b/e2e/playwright/projects.spec.ts index c8d57b112..425fd9d2b 100644 --- a/e2e/playwright/projects.spec.ts +++ b/e2e/playwright/projects.spec.ts @@ -87,7 +87,7 @@ test( const bracketDir = path.join(dir, 'bracket') await fsp.mkdir(bracketDir, { recursive: true }) await fsp.copyFile( - executorInputPath('focusrite_scarlett_mounting_braket.kcl'), + executorInputPath('cylinder-inches.kcl'), path.join(bracketDir, 'main.kcl') ) }) @@ -124,7 +124,7 @@ test( const bracketDir = path.join(dir, 'bracket') await fsp.mkdir(bracketDir, { recursive: true }) await fsp.copyFile( - executorInputPath('focusrite_scarlett_mounting_braket.kcl'), + executorInputPath('cylinder-inches.kcl'), path.join(bracketDir, 'main.kcl') ) const errorDir = path.join(dir, 'broken-code') @@ -162,7 +162,7 @@ test( // gray at this pixel means the stream has loaded in the most // user way we can verify it (pixel color) await expect - .poll(() => u.getGreatestPixDiff(pointOnModel, [85, 85, 85]), { + .poll(() => u.getGreatestPixDiff(pointOnModel, [110, 110, 110]), { timeout: 10_000, }) .toBeLessThan(20) @@ -213,7 +213,7 @@ test( const bracketDir = path.join(dir, 'bracket') await fsp.mkdir(bracketDir, { recursive: true }) await fsp.copyFile( - executorInputPath('focusrite_scarlett_mounting_braket.kcl'), + executorInputPath('cylinder-inches.kcl'), path.join(bracketDir, 'main.kcl') ) const emptyDir = path.join(dir, 'empty') @@ -248,7 +248,7 @@ test( // gray at this pixel means the stream has loaded in the most // user way we can verify it (pixel color) await expect - .poll(() => u.getGreatestPixDiff(pointOnModel, [85, 85, 85]), { + .poll(() => u.getGreatestPixDiff(pointOnModel, [125, 125, 125]), { timeout: 10_000, }) .toBeLessThan(15) @@ -290,7 +290,7 @@ test( const bracketDir = path.join(dir, 'bracket') await fsp.mkdir(bracketDir, { recursive: true }) await fsp.copyFile( - executorInputPath('focusrite_scarlett_mounting_braket.kcl'), + executorInputPath('cylinder-inches.kcl'), path.join(bracketDir, 'main.kcl') ) @@ -319,7 +319,7 @@ test( // gray at this pixel means the stream has loaded in the most // user way we can verify it (pixel color) await expect - .poll(() => u.getGreatestPixDiff(pointOnModel, [85, 85, 85]), { + .poll(() => u.getGreatestPixDiff(pointOnModel, [125, 125, 125]), { timeout: 10_000, }) .toBeLessThan(15) @@ -359,7 +359,7 @@ test( const bracketDir = path.join(dir, 'bracket') await fsp.mkdir(bracketDir, { recursive: true }) await fsp.copyFile( - executorInputPath('focusrite_scarlett_mounting_braket.kcl'), + executorInputPath('cylinder-inches.kcl'), path.join(bracketDir, 'main.kcl') ) await fsp.copyFile( @@ -393,7 +393,7 @@ test( // gray at this pixel means the stream has loaded in the most // user way we can verify it (pixel color) await expect - .poll(() => u.getGreatestPixDiff(pointOnModel, [85, 85, 85]), { + .poll(() => u.getGreatestPixDiff(pointOnModel, [125, 125, 125]), { timeout: 10_000, }) .toBeLessThan(15) @@ -443,7 +443,6 @@ test( await page.getByText('broken-code').click() // Gotcha: You can not use scene.waitForExecutionDone() since the KCL code is going to fail - await expect(page.getByTestId('loading')).toBeAttached() await expect(page.getByTestId('loading')).not.toBeAttached({ timeout: 20_000, }) @@ -481,7 +480,7 @@ test.describe('Can export from electron app', () => { const bracketDir = path.join(dir, 'bracket') await fsp.mkdir(bracketDir, { recursive: true }) await fsp.copyFile( - executorInputPath('focusrite_scarlett_mounting_braket.kcl'), + executorInputPath('cylinder-inches.kcl'), path.join(bracketDir, 'main.kcl') ) }) @@ -513,7 +512,7 @@ test.describe('Can export from electron app', () => { // gray at this pixel means the stream has loaded in the most // user way we can verify it (pixel color) await expect - .poll(() => u.getGreatestPixDiff(pointOnModel, [85, 85, 85]), { + .poll(() => u.getGreatestPixDiff(pointOnModel, [125, 125, 125]), { timeout: 10_000, }) .toBeLessThan(15) @@ -554,7 +553,7 @@ test.describe('Can export from electron app', () => { }, { timeout: 15_000 } ) - .toBeGreaterThan(300_000) + .toBeGreaterThan(50_000) // clean up exported file await fsp.rm(filepath) @@ -1507,7 +1506,12 @@ test( await u.waitForPageLoad() - await page.locator('.cm-content').fill(`sketch001 = startSketchOn(XZ) + // The file should be prepopulated with the user's unit settings. + await expect(page.locator('.cm-content')).toHaveText( + '@settings(defaultLengthUnit = in)' + ) + + await page.locator('.cm-content').fill(`sketch001 = startSketchOn('XZ') |> startProfileAt([-87.4, 282.92], %) |> line(end = [324.07, 27.199], tag = $seg01) |> line(end = [118.328, -291.754]) diff --git a/e2e/playwright/regression-tests.spec.ts b/e2e/playwright/regression-tests.spec.ts index deb17303f..c261120c6 100644 --- a/e2e/playwright/regression-tests.spec.ts +++ b/e2e/playwright/regression-tests.spec.ts @@ -4,9 +4,9 @@ import path from 'path' import * as fsp from 'fs/promises' import { getUtils, - executorInputPath, TEST_COLORS, TestColor, + executorInputPath, orRunWhenFullSuiteEnabled, } from './test-utils' import { TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR } from './storageStates' @@ -331,7 +331,7 @@ extrude001 = extrude(sketch001, length = 50) localStorage.setItem( 'persistCode', `@settings(defaultLengthUnit = mm) -sketch002 = startSketchOn('XY') +sketch002 = startSketchOn(XY) profile002 = startProfileAt([72.24, -52.05], sketch002) |> angledLine([0, 181.26], %, $rectangleSegmentA001) |> angledLine([ @@ -582,7 +582,7 @@ extrude002 = extrude(profile002, length = 150) const bracketDir = path.join(dir, 'bracket') await fsp.mkdir(bracketDir, { recursive: true }) await fsp.copyFile( - executorInputPath('focusrite_scarlett_mounting_braket.kcl'), + executorInputPath('cylinder-inches.kcl'), path.join(bracketDir, 'main.kcl') ) }) @@ -619,6 +619,7 @@ extrude002 = extrude(profile002, length = 150) test(`View gizmo stays visible even when zoomed out all the way`, async ({ page, homePage, + scene, }) => { const u = await getUtils(page) @@ -632,7 +633,7 @@ extrude002 = extrude(profile002, length = 150) await test.step(`Load an empty file`, async () => { await page.addInitScript(async () => { - localStorage.setItem('persistCode', '') + localStorage.setItem('persistCode', '@settings(defaultLengthUnit = in)') }) await page.setBodyDimensions({ width: 1200, height: 500 }) await homePage.goToModelingScene() @@ -646,22 +647,31 @@ extrude002 = extrude(profile002, length = 150) timeout: 5000, message: 'Plane color is visible', }) - .toBeLessThanOrEqual(15) + .toBeLessThanOrEqual(20) + await expect(scene.startEditSketchBtn).toBeEnabled() let maxZoomOuts = 10 let middlePixelIsBackgroundColor = (await middlePixelIsColor(bgColor)) < 10 + + console.time('pressing control') + await page.keyboard.down('Control') + while (!middlePixelIsBackgroundColor && maxZoomOuts > 0) { - await page.keyboard.down('Control') - await page.mouse.move(600, 460) - await page.mouse.down({ button: 'right' }) - await page.mouse.move(600, 50, { steps: 20 }) - await page.mouse.up({ button: 'right' }) - await page.keyboard.up('Control') await page.waitForTimeout(100) + await page.mouse.move(650, 460) + console.time('moved to start point') + await page.mouse.down({ button: 'right' }) + console.time('moused down') + await page.mouse.move(650, 50, { steps: 20 }) + console.time('moved to end point') + await page.waitForTimeout(100) + await page.mouse.up({ button: 'right' }) + console.time('moused up') maxZoomOuts-- - middlePixelIsBackgroundColor = (await middlePixelIsColor(bgColor)) < 10 + middlePixelIsBackgroundColor = (await middlePixelIsColor(bgColor)) < 15 } + await page.keyboard.up('Control') expect(middlePixelIsBackgroundColor, { message: 'We should not see the default planes', @@ -678,13 +688,12 @@ extrude002 = extrude(profile002, length = 150) homePage, scene, toolbar, - viewport, }) => { await context.folderSetupFn(async (dir) => { const legoDir = path.join(dir, 'lego') await fsp.mkdir(legoDir, { recursive: true }) await fsp.copyFile( - executorInputPath('lego.kcl'), + executorInputPath('e2e-can-sketch-on-chamfer.kcl'), path.join(legoDir, 'main.kcl') ) }) @@ -697,11 +706,8 @@ extrude002 = extrude(profile002, length = 150) await scene.loadingIndicator.waitFor({ state: 'detached' }) }) await test.step(`The part should start loading quickly, not waiting until execution is complete`, async () => { - await scene.expectPixelColor( - [143, 143, 143], - { x: (viewport?.width ?? 1200) / 2, y: (viewport?.height ?? 500) / 2 }, - 15 - ) + // TODO: use the viewport size to pick the center point, but the `viewport` fixture's values were wrong. + await scene.expectPixelColor([116, 116, 116], { x: 500, y: 250 }, 15) }) }) diff --git a/e2e/playwright/sketch-tests.spec.ts b/e2e/playwright/sketch-tests.spec.ts index 40d5eafb8..628f55bca 100644 --- a/e2e/playwright/sketch-tests.spec.ts +++ b/e2e/playwright/sketch-tests.spec.ts @@ -113,7 +113,8 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) |> startProfileAt([2.61, -4.01], %) |> xLine(length = 8.73) |> tangentialArcTo([8.33, -1.31], %)` @@ -159,7 +160,10 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => { await page.mouse.click(700, 200) await expect.poll(u.normalisedEditorCode, { timeout: 1000 }) - .toBe(`sketch002 = startSketchOn(XZ) + .toBe(`@settings(defaultLengthUnit = in) + + +sketch002 = startSketchOn(XZ) sketch001 = startProfileAt([12.34, -12.34], sketch002) |> yLine(length = 12.34) @@ -789,7 +793,8 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002) 200 ) - let codeStr = 'sketch001 = startSketchOn(XY)' + let codeStr = + '@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XY)' await page.mouse.click(center.x, viewportSize.height * 0.55) await expect(u.codeLocator).toHaveText(codeStr) @@ -868,7 +873,8 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002) await u.openDebugPanel() - const code = `sketch001 = startSketchOn(-XZ) + const code = `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(-XZ) profile001 = startProfileAt([${roundOff(scale * 69.6)}, ${roundOff( scale * 34.8 )}], sketch001) @@ -898,7 +904,7 @@ profile001 = startProfileAt([${roundOff(scale * 69.6)}, ${roundOff( await page.mouse.move(700, 200, { steps: 10 }) await page.mouse.click(700, 200, { delay: 200 }) await expect(page.locator('.cm-content')).toHaveText( - `sketch001 = startSketchOn(-XZ)` + `@settings(defaultLengthUnit = in)sketch001 = startSketchOn(-XZ)` ) let prevContent = await page.locator('.cm-content').innerText() @@ -1426,7 +1432,8 @@ test.describe(`Sketching with offset planes`, () => { await context.addInitScript(() => { localStorage.setItem( 'persistCode', - `offsetPlane001 = offsetPlane(XY, offset = 10)` + `@settings(defaultLengthUnit = in) +offsetPlane001 = offsetPlane(XY, offset = 10)` ) }) @@ -1440,7 +1447,7 @@ test.describe(`Sketching with offset planes`, () => { await test.step(`Hovering should highlight code`, async () => { await planeHover() await editor.expectState({ - activeLines: [`offsetPlane001=offsetPlane(XY,offset=10)`], + activeLines: [`@settings(defaultLengthUnit = in)`], diagnostics: [], highlightedCode: 'offsetPlane(XY, offset = 10)', }) @@ -1453,7 +1460,7 @@ test.describe(`Sketching with offset planes`, () => { await expect(toolbar.lineBtn).toBeEnabled() await editor.expectEditor.toContain('startSketchOn(offsetPlane001)') await editor.expectState({ - activeLines: [`offsetPlane001=offsetPlane(XY,offset=10)`], + activeLines: [`@settings(defaultLengthUnit = in)`], diagnostics: [], highlightedCode: '', }) @@ -1604,7 +1611,8 @@ profile002 = startProfileAt([117.2, 56.08], sketch001) await context.addInitScript(() => { localStorage.setItem( 'persistCode', - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) profile002 = startProfileAt([40.68, 87.67], sketch001) |> xLine(length = 239.17) profile003 = startProfileAt([206.63, -56.73], sketch001) @@ -2172,7 +2180,8 @@ profile003 = startProfileAt([206.63, -56.73], sketch001) await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) profile001 = startProfileAt([6.24, 4.54], sketch001) |> line(end = [-0.41, 6.99]) |> line(end = [8.61, 0.74]) @@ -2317,7 +2326,8 @@ profile004 = circleThreePoint(sketch001, p1 = [13.44, -6.8], p2 = [13.39, -2.07] await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) profile001 = startProfileAt([6.24, 4.54], sketch001) |> line(end = [-0.41, 6.99]) |> line(end = [8.61, 0.74]) @@ -2422,7 +2432,8 @@ profile003 = circle(sketch001, center = [6.92, -4.2], radius = 3.16) await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) profile001 = startProfileAt([-63.43, 193.08], sketch001) |> line(end = [168.52, 149.87]) |> line(end = [190.29, -39.18]) @@ -2486,7 +2497,11 @@ extrude001 = extrude(profile003, length = 5) page, }) => { await page.addInitScript(async () => { - localStorage.setItem('persistCode', `myVar = 5`) + localStorage.setItem( + 'persistCode', + `@settings(defaultLengthUnit = in) + myVar = 5` + ) }) await page.setBodyDimensions({ width: 1000, height: 500 }) @@ -2533,7 +2548,8 @@ extrude001 = extrude(profile003, length = 5) await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) profile001 = startProfileAt([85.19, 338.59], sketch001) |> line(end = [213.3, -94.52]) |> line(end = [-230.09, -55.34]) @@ -2575,7 +2591,8 @@ profile002 = startProfileAt([85.81, 52.55], sketch002) await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `thePart = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +thePart = startSketchOn(XZ) |> startProfileAt([7.53, 10.51], %) |> line(end = [12.54, 1.83]) |> line(end = [6.65, -6.91]) @@ -2636,7 +2653,8 @@ extrude001 = extrude(thePart, length = 75) await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) profile001 = startProfileAt([6.71, -3.66], sketch001) |> line(end = [2.65, 9.02], tag = $seg02) |> line(end = [3.73, -9.36], tag = $seg01) @@ -2809,7 +2827,8 @@ extrude003 = extrude(profile011, length = 2.5) await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) profile001 = startProfileAt([34, 42.66], sketch001) |> line(end = [102.65, 151.99]) |> line(end = [76, -138.66]) diff --git a/e2e/playwright/snapshot-tests.spec.ts b/e2e/playwright/snapshot-tests.spec.ts index 8e2171696..67d40bb6a 100644 --- a/e2e/playwright/snapshot-tests.spec.ts +++ b/e2e/playwright/snapshot-tests.spec.ts @@ -76,11 +76,11 @@ part001 = startSketchOn(-XZ) |> xLine(endAbsolute = totalLen, tag = $seg03) |> yLine(length = -armThick, tag = $seg01) |> angledLineThatIntersects({ - angle = HALF_TURN, + angle = turns::HALF_TURN, offset = -armThick, intersectTag = seg04 }, %) - |> angledLineToY([segAng(seg04, %) + 180, ZERO], %) + |> angledLineToY([segAng(seg04, %) + 180, turns::ZERO], %) |> angledLineToY({ angle = -bottomAng, to = -totalHeightHalf - armThick, @@ -88,12 +88,12 @@ part001 = startSketchOn(-XZ) |> xLine(length = endAbsolute = segEndX(seg03) + 0) |> yLine(length = -segLen(seg01, %)) |> angledLineThatIntersects({ - angle = HALF_TURN, + angle = turns::HALF_TURN, offset = -armThick, intersectTag = seg02 }, %) |> angledLineToY([segAng(seg02, %) + 180, -baseHeight], %) - |> xLine(endAbsolute = ZERO) + |> xLine(endAbsolute = turns::ZERO) |> close() |> extrude(length = 4)` ) diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Client-side-scene-scale-should-match-engine-scale-Inch-scale-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Client-side-scene-scale-should-match-engine-scale-Inch-scale-1-Google-Chrome-linux.png index bafda85ec..6c1e7328f 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Client-side-scene-scale-should-match-engine-scale-Inch-scale-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Client-side-scene-scale-should-match-engine-scale-Inch-scale-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Client-side-scene-scale-should-match-engine-scale-Inch-scale-2-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Client-side-scene-scale-should-match-engine-scale-Inch-scale-2-Google-Chrome-linux.png index a9b804037..c296a47dd 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Client-side-scene-scale-should-match-engine-scale-Inch-scale-2-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Client-side-scene-scale-should-match-engine-scale-Inch-scale-2-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-circle-should-look-right-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-circle-should-look-right-1-Google-Chrome-linux.png index b76e1d372..f9ccdb768 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-circle-should-look-right-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-circle-should-look-right-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-rectangles-should-look-right-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-rectangles-should-look-right-1-Google-Chrome-linux.png index 4639dd176..ae548a4c7 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-rectangles-should-look-right-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-rectangles-should-look-right-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-1-Google-Chrome-linux.png index 67be72dda..1982b8e27 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-2-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-2-Google-Chrome-linux.png index 54f4245f4..bf368ba0d 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-2-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-2-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-3-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-3-Google-Chrome-linux.png index 99c8f10b7..d7eef465c 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-3-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-3-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-4-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-4-Google-Chrome-linux.png index 50f96a32c..3b65cf723 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-4-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Draft-segments-should-look-right-4-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Grid-visibility-Grid-turned-off-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Grid-visibility-Grid-turned-off-1-Google-Chrome-linux.png index 810142ea3..d2a9c2f82 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Grid-visibility-Grid-turned-off-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Grid-visibility-Grid-turned-off-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Grid-visibility-Grid-turned-off-to-on-via-command-bar-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Grid-visibility-Grid-turned-off-to-on-via-command-bar-1-Google-Chrome-linux.png index ab06182d5..1335cd834 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Grid-visibility-Grid-turned-off-to-on-via-command-bar-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Grid-visibility-Grid-turned-off-to-on-via-command-bar-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Sketch-on-face-with-none-z-up-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Sketch-on-face-with-none-z-up-1-Google-Chrome-linux.png index ab57f9878..0b8272eec 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Sketch-on-face-with-none-z-up-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Sketch-on-face-with-none-z-up-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Zoom-to-fit-on-load---solid-3d-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Zoom-to-fit-on-load---solid-3d-1-Google-Chrome-linux.png index b5d4021ed..89360c26b 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/Zoom-to-fit-on-load---solid-3d-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/Zoom-to-fit-on-load---solid-3d-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/code-color-goober-code-color-goober-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/code-color-goober-code-color-goober-1-Google-Chrome-linux.png index 64eca362c..448f90c91 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/code-color-goober-code-color-goober-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/code-color-goober-code-color-goober-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/code-color-goober-code-color-goober-opening-window-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/code-color-goober-code-color-goober-opening-window-1-Google-Chrome-linux.png index 6108c993e..194f2f225 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/code-color-goober-code-color-goober-opening-window-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/code-color-goober-code-color-goober-opening-window-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--XY-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--XY-1-Google-Chrome-linux.png index 8d2141c5b..e83edbcd2 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--XY-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--XY-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--XZ-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--XZ-1-Google-Chrome-linux.png index 318b7e38a..d519fa0d7 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--XZ-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--XZ-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--YZ-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--YZ-1-Google-Chrome-linux.png index 13796e571..0f3146fd6 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--YZ-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable--YZ-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-XY-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-XY-1-Google-Chrome-linux.png index 9359b7a8a..be1d17822 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-XY-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-XY-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-XZ-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-XZ-1-Google-Chrome-linux.png index 08c79298d..1ddd4a57a 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-XZ-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-XZ-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-YZ-1-Google-Chrome-linux.png b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-YZ-1-Google-Chrome-linux.png index e3bd750ff..c19e3f422 100644 Binary files a/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-YZ-1-Google-Chrome-linux.png and b/e2e/playwright/snapshot-tests.spec.ts-snapshots/extrude-on-default-planes-should-be-stable-YZ-1-Google-Chrome-linux.png differ diff --git a/e2e/playwright/snapshots/prompt-to-edit/prompt-to-edit-snapshot-tests-spec-ts--change-colour.snap.json b/e2e/playwright/snapshots/prompt-to-edit/prompt-to-edit-snapshot-tests-spec-ts--change-colour.snap.json index 5058c2c40..00de798d1 100644 --- a/e2e/playwright/snapshots/prompt-to-edit/prompt-to-edit-snapshot-tests-spec-ts--change-colour.snap.json +++ b/e2e/playwright/snapshots/prompt-to-edit/prompt-to-edit-snapshot-tests-spec-ts--change-colour.snap.json @@ -1,5 +1,5 @@ { - "original_source_code": "sketch001 = startSketchOn('XZ')\nprofile001 = startProfileAt([57.81, 250.51], sketch001)\n |> line(end = [121.13, 56.63], tag = $seg02)\n |> line(end = [83.37, -34.61], tag = $seg01)\n |> line(end = [19.66, -116.4])\n |> line(end = [-221.8, -41.69])\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\nextrude001 = extrude(profile001, length = 200)\nsketch002 = startSketchOn('XZ')\n |> startProfileAt([-73.64, -42.89], %)\n |> xLine(length = 173.71)\n |> line(end = [-22.12, -94.4])\n |> xLine(length = -156.98)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\nextrude002 = extrude(sketch002, length = 50)\nsketch003 = startSketchOn('XY')\n |> startProfileAt([52.92, 157.81], %)\n |> angledLine([0, 176.4], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 53.4\n ], %, $rectangleSegmentB001)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %, $rectangleSegmentC001)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\nextrude003 = extrude(sketch003, length = 20)\n", + "original_source_code": "sketch001 = startSketchOn('XZ')\nprofile001 = startProfileAt([57.81, 250.51], sketch001)\n |> line(end = [121.13, 56.63], tag = $seg02)\n |> line(end = [83.37, -34.61], tag = $seg01)\n |> line(end = [19.66, -116.4])\n |> line(end = [-221.8, -41.69])\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\nextrude001 = extrude(profile001, length = 200)\nsketch002 = startSketchOn('XZ')\n |> startProfileAt([-73.64, -42.89], %)\n |> xLine(length = 173.71)\n |> line(end = [-22.12, -94.4])\n |> xLine(length = -156.98)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\nextrude002 = extrude(sketch002, length = 50)\nsketch003 = startSketchOn(XY)\n |> startProfileAt([52.92, 157.81], %)\n |> angledLine([0, 176.4], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 53.4\n ], %, $rectangleSegmentB001)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %, $rectangleSegmentC001)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\nextrude003 = extrude(sketch003, length = 20)\n", "prompt": "make this neon green please, use #39FF14", "source_ranges": [ { @@ -30,4 +30,4 @@ } ], "kcl_version": "0.2.48" -} \ No newline at end of file +} diff --git a/e2e/playwright/testing-constraints.spec.ts b/e2e/playwright/testing-constraints.spec.ts index 57ae5e8da..c1bcb2bb7 100644 --- a/e2e/playwright/testing-constraints.spec.ts +++ b/e2e/playwright/testing-constraints.spec.ts @@ -4,7 +4,6 @@ import { getUtils, TEST_COLORS, pollEditorLinesSelectedLength, - executorInputPath, orRunWhenFullSuiteEnabled, } from './test-utils' import { XOR } from 'lib/utils' @@ -81,7 +80,8 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `yo = 79 + `@settings(defaultLengthUnit = in) + yo = 79 part001 = startSketchOn(XZ) |> startProfileAt([-7.54, -26.74], %) |> line(end = [74.36, 130.4], tag = $seg01) @@ -145,7 +145,8 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `yo = 5 + `@settings(defaultLengthUnit = in) + yo = 5 part001 = startSketchOn(XZ) |> startProfileAt([-7.54, -26.74], %) |> line(end = [74.36, 130.4], tag = $seg01) @@ -277,7 +278,8 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `yo = 5 + `@settings(defaultLengthUnit = in) + yo = 5 part001 = startSketchOn(XZ) |> startProfileAt([-7.54, -26.74], %) |> line(end = [74.36, 130.4]) @@ -387,7 +389,8 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `yo = 5 + `@settings(defaultLengthUnit = in) + yo = 5 part001 = startSketchOn(XZ) |> startProfileAt([-7.54, -26.74], %) |> line(end = [74.36, 130.4]) @@ -486,13 +489,13 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => { testName: 'Add variable, selecting axis', addVariable: true, axisSelect: true, - value: 'QUARTER_TURN - angle001', + value: 'turns::QUARTER_TURN - angle001', }, { testName: 'No variable, selecting axis', addVariable: false, axisSelect: true, - value: 'QUARTER_TURN - 7', + value: 'turns::QUARTER_TURN - 7', }, ] as const for (const { testName, addVariable, value, axisSelect } of cases) { @@ -500,7 +503,8 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `yo = 5 + `@settings(defaultLengthUnit = in) + yo = 5 part001 = startSketchOn(XZ) |> startProfileAt([-7.54, -26.74], %) |> line(end = [74.36, 130.4]) @@ -602,7 +606,8 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `yo = 5 + `@settings(defaultLengthUnit = in) + yo = 5 part001 = startSketchOn(XZ) |> startProfileAt([-7.54, -26.74], %) |> line(end = [74.36, 130.4]) @@ -688,7 +693,8 @@ test.describe('Testing constraints', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `yo = 5 + `@settings(defaultLengthUnit = in) +yo = 5 part001 = startSketchOn(XZ) |> startProfileAt([-7.54, -26.74], %) |> line(end = [74.36, 130.4]) @@ -768,7 +774,8 @@ part002 = startSketchOn(XZ) await page.addInitScript(async (customCode) => { localStorage.setItem( 'persistCode', - `yo = 5 + `@settings(defaultLengthUnit = in) + yo = 5 part001 = startSketchOn(XZ) |> startProfileAt([-7.54, -26.74], %) |> line(end = [74.36, 130.4]) @@ -869,7 +876,8 @@ part002 = startSketchOn(XZ) await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `yo = 5 + `@settings(defaultLengthUnit = in) + yo = 5 part001 = startSketchOn(XZ) |> startProfileAt([-7.54, -26.74], %) |> line(end = [74.36, 130.4]) @@ -935,12 +943,12 @@ part002 = startSketchOn(XZ) test.describe('Axis & segment - no modal constraints', () => { const cases = [ { - codeAfter: `|> line(endAbsolute = [154.9, ZERO])`, + codeAfter: `|> line(endAbsolute = [154.9, turns::ZERO])`, axisClick: { x: 950, y: 250 }, constraintName: 'Snap To X', }, { - codeAfter: `|> line(endAbsolute = [ZERO, 61.34])`, + codeAfter: `|> line(endAbsolute = [turns::ZERO, 61.34])`, axisClick: { x: 600, y: 150 }, constraintName: 'Snap To Y', }, @@ -950,7 +958,8 @@ part002 = startSketchOn(XZ) await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `yo = 5 + `@settings(defaultLengthUnit = in) + yo = 5 part001 = startSketchOn(XZ) |> startProfileAt([-7.54, -26.74], %) |> line(end = [74.36, 130.4]) @@ -1117,9 +1126,19 @@ test.describe('Electron constraint tests', () => { await context.folderSetupFn(async (dir) => { const bracketDir = path.join(dir, 'test-sample') await fsp.mkdir(bracketDir, { recursive: true }) - await fsp.copyFile( - executorInputPath('angled_line.kcl'), - path.join(bracketDir, 'main.kcl') + await fsp.writeFile( + path.join(bracketDir, 'main.kcl'), + `@settings(defaultLengthUnit = in) + const part001 = startSketchOn(XY) + |> startProfileAt([4.83, 12.56], %) + |> line(end = [15.1, 2.48]) + |> line(end = [3.15, -9.85], tag = $seg01) + |> line(end = [-15.17, -4.1]) + |> angledLine([segAng(seg01), 12.35], %) + |> line(end = [-13.02, 10.03]) + |> close() + |> extrude(length = 4)`, + 'utf-8' ) }) diff --git a/e2e/playwright/testing-gizmo.spec.ts b/e2e/playwright/testing-gizmo.spec.ts index a08382412..75b222b32 100644 --- a/e2e/playwright/testing-gizmo.spec.ts +++ b/e2e/playwright/testing-gizmo.spec.ts @@ -255,7 +255,7 @@ test.describe(`Testing gizmo, fixture-based`, () => { await context.addInitScript(() => { localStorage.setItem( 'persistCode', - ` + `@settings(defaultLengthUnit = in) const sketch002 = startSketchOn(XZ) |> startProfileAt([-108.83, -57.48], %) |> angledLine([0, 105.13], %, $rectangleSegmentA001) diff --git a/e2e/playwright/testing-samples-loading.spec.ts b/e2e/playwright/testing-samples-loading.spec.ts index c894547d4..182925fe9 100644 --- a/e2e/playwright/testing-samples-loading.spec.ts +++ b/e2e/playwright/testing-samples-loading.spec.ts @@ -46,7 +46,7 @@ test.describe('Testing in-app sample loading', () => { page.getByRole('option', { name, }) - const warningText = page.getByText('Overwrite current file and units?') + const warningText = page.getByText('Overwrite current file with sample?') const confirmButton = page.getByRole('button', { name: 'Submit command' }) await test.step(`Precondition: check the initial code`, async () => { @@ -110,11 +110,9 @@ test.describe('Testing in-app sample loading', () => { const commandMethodOption = page.getByRole('option', { name: 'Overwrite', }) - const newFileWarning = page.getByText( - 'Create a new file, overwrite project units?' - ) + const newFileWarning = page.getByText('Create a new file from sample?') const overwriteWarning = page.getByText( - 'Overwrite current file and units?' + 'Overwrite current file with sample?' ) const confirmButton = page.getByRole('button', { name: 'Submit command' }) const projectMenuButton = page.getByTestId('project-sidebar-toggle') diff --git a/e2e/playwright/testing-segment-overlays.spec.ts b/e2e/playwright/testing-segment-overlays.spec.ts index f888909f9..809ad55bb 100644 --- a/e2e/playwright/testing-segment-overlays.spec.ts +++ b/e2e/playwright/testing-segment-overlays.spec.ts @@ -210,7 +210,8 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `part001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) + part001 = startSketchOn(XZ) |> startProfileAt([5 + 0, 20 + 0], %) |> line(end = [0.5, -14 + 0]) |> angledLine({ angle = 3 + 0, length = 32 + 0 }, %) @@ -380,7 +381,8 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `yRel001 = -14 + `@settings(defaultLengthUnit = in) + yRel001 = -14 xRel001 = 0.5 angle001 = 3 len001 = 32 @@ -459,7 +461,8 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `part001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) + part001 = startSketchOn(XZ) |> startProfileAt([0, 0], %) |> line(end = [0.5, -14 + 0]) |> angledLine({ angle = 3 + 0, length = 32 + 0 }, %) @@ -590,7 +593,8 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `part001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) + part001 = startSketchOn(XZ) |> startProfileAt([0, 0], %) |> line(end = [0.5, -14 + 0]) |> angledLine({ angle = 3 + 0, length = 32 + 0 }, %) @@ -751,7 +755,8 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `part001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) + part001 = startSketchOn(XZ) |> startProfileAt([0, 0], %) |> line(end = [0.5, -14 + 0]) |> angledLine({ angle = 3 + 0, length = 32 + 0 }, %) @@ -831,7 +836,8 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) profile001 = startProfileAt([56.37, 120.33], sketch001) |> line(end = [162.86, 106.48]) |> arcTo({ @@ -957,7 +963,8 @@ profile001 = startProfileAt([56.37, 120.33], sketch001) await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `part001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +part001 = startSketchOn(XZ) |> circle(center = [1 + 0, 0], radius = 8) ` ) @@ -1077,7 +1084,8 @@ profile001 = startProfileAt([56.37, 120.33], sketch001) await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `part001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +part001 = startSketchOn(XZ) |>startProfileAt([0, 0], %) |> line(end = [0.5, -14 + 0]) |> angledLine({ angle = 3 + 0, length = 32 + 0 }, %) @@ -1351,7 +1359,8 @@ profile001 = startProfileAt([56.37, 120.33], sketch001) async ({ lineToBeDeleted, extraLine }) => { localStorage.setItem( 'persistCode', - `part001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) + part001 = startSketchOn(XZ) |> startProfileAt([5, 6], %) |> ${lineToBeDeleted} |> line(end = [-10, -15]) @@ -1516,7 +1525,8 @@ profile001 = startProfileAt([56.37, 120.33], sketch001) async ({ lineToBeDeleted }) => { localStorage.setItem( 'persistCode', - `part001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) + part001 = startSketchOn(XZ) |> startProfileAt([5, 6], %) |> ${lineToBeDeleted} |> line(end = [-10, -15]) diff --git a/e2e/playwright/testing-selections.spec.ts b/e2e/playwright/testing-selections.spec.ts index 3db4e7f43..0b1ded979 100644 --- a/e2e/playwright/testing-selections.spec.ts +++ b/e2e/playwright/testing-selections.spec.ts @@ -68,20 +68,20 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => { await u.closeDebugPanel() await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10) await expect(page.locator('.cm-content')).toHaveText( - `sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${commonPoints.startAt}, sketch001)` + `@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${commonPoints.startAt}, sketch001)` ) await page.waitForTimeout(100) await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10) await expect(page.locator('.cm-content')) - .toHaveText(`sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${commonPoints.startAt}, sketch001) + .toHaveText(`@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${commonPoints.startAt}, sketch001) |> xLine(length = ${commonPoints.num1})`) await page.waitForTimeout(100) await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20) await expect(page.locator('.cm-content')) - .toHaveText(`sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${ + .toHaveText(`@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${ commonPoints.startAt }, sketch001) |> xLine(length = ${commonPoints.num1}) @@ -89,7 +89,7 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => { await page.waitForTimeout(100) await page.mouse.click(startXPx, 500 - PUR * 20) await expect(page.locator('.cm-content')) - .toHaveText(`sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${ + .toHaveText(`@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${ commonPoints.startAt }, sketch001) |> xLine(length = ${commonPoints.num1}) @@ -260,7 +260,8 @@ test.describe('Testing selections', { tag: ['@skipWin'] }, () => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) |> startProfileAt([-79.26, 95.04], %) |> line(end = [112.54, 127.64], tag = $seg02) |> line(end = [170.36, -121.61], tag = $seg01) @@ -528,7 +529,8 @@ profile001 = startProfileAt([7.49, 9.96], sketch001) await page.addInitScript(async (KCL_DEFAULT_LENGTH) => { localStorage.setItem( 'persistCode', - `part001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +part001 = startSketchOn(XZ) |> startProfileAt([20, 0], %) |> line(end = [7.13, 4 + 0]) |> angledLine({ angle = 3 + 0, length = 3.14 + 0 }, %) @@ -747,7 +749,8 @@ profile001 = startProfileAt([7.49, 9.96], sketch001) await page.waitForTimeout(200) await u.removeCurrentCode() - await u.codeLocator.fill(`sketch001 = startSketchOn(XZ) + await u.codeLocator.fill(`@settings(defaultLengthUnit = in) + sketch001 = startSketchOn(XZ) |> startProfileAt([75.8, 317.2], %) // [$startCapTag, $EndCapTag] |> angledLine([0, 268.43], %, $rectangleSegmentA001) |> angledLine([ @@ -965,7 +968,8 @@ profile001 = startProfileAt([7.49, 9.96], sketch001) async ({ cases }) => { localStorage.setItem( 'persistCode', - `yo = 79 + `@settings(defaultLengthUnit = in) + yo = 79 part001 = startSketchOn(XZ) |> startProfileAt([-7.54, -26.74], %) |> ${cases[0].expectedCode} @@ -1020,7 +1024,8 @@ profile001 = startProfileAt([7.49, 9.96], sketch001) await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) + sketch001 = startSketchOn(XZ) |> startProfileAt([-79.26, 95.04], %) |> line(end = [112.54, 127.64]) |> line(end = [170.36, -121.61], tag = $seg01) @@ -1253,7 +1258,7 @@ profile001 = startProfileAt([7.49, 9.96], sketch001) await page.mouse.click(700, 200) await expect(page.locator('.cm-content')).toHaveText( - `sketch001 = startSketchOn(XZ)` + `@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)` ) await page.waitForTimeout(600) diff --git a/e2e/playwright/testing-settings.spec.ts b/e2e/playwright/testing-settings.spec.ts index 4c24644e8..c57eccf23 100644 --- a/e2e/playwright/testing-settings.spec.ts +++ b/e2e/playwright/testing-settings.spec.ts @@ -271,7 +271,7 @@ test.describe('Testing settings', () => { const bracketDir = join(dir, projectName) await fsp.mkdir(bracketDir, { recursive: true }) await fsp.copyFile( - executorInputPath('focusrite_scarlett_mounting_braket.kcl'), + executorInputPath('cylinder-inches.kcl'), join(bracketDir, 'main.kcl') ) } @@ -699,19 +699,19 @@ test.describe('Testing settings', () => { name: 'Current units are: ', }) await gizmo.click() - const button = page.getByRole('button', { + const button = page.locator('ul').getByRole('button', { name: copy, exact: true, }) await button.click() const toastMessage = page.getByText( - `Set default unit to "${unitOfMeasure}" for this project` + `Updated per-file units to ${unitOfMeasure}` ) await expect(toastMessage).toBeVisible() } - await changeUnitOfMeasureInGizmo('in', 'Inches') await changeUnitOfMeasureInGizmo('ft', 'Feet') + await changeUnitOfMeasureInGizmo('in', 'Inches') await changeUnitOfMeasureInGizmo('yd', 'Yards') await changeUnitOfMeasureInGizmo('mm', 'Millimeters') await changeUnitOfMeasureInGizmo('cm', 'Centimeters') @@ -951,9 +951,9 @@ test.describe('Testing settings', () => { ) }) - await test.step(`Initial units from settings`, async () => { + await test.step(`Initial units from settings are ignored`, async () => { await homePage.openProject('project-000') - await expect(unitsIndicator).toHaveText('Current units are: in') + await expect(unitsIndicator).toHaveText('Current units are: mm') }) await test.step(`Manually write inline settings`, async () => { diff --git a/e2e/playwright/various.spec.ts b/e2e/playwright/various.spec.ts index 3591a6f7d..d49ff9514 100644 --- a/e2e/playwright/various.spec.ts +++ b/e2e/playwright/various.spec.ts @@ -67,11 +67,11 @@ part001 = startSketchOn(-XZ) |> xLine(endAbsolute = totalLen, tag = $seg03) |> yLine(length = -armThick, tag = $seg01) |> angledLineThatIntersects({ - angle = HALF_TURN, + angle = turns::HALF_TURN, offset = -armThick, intersectTag = seg04 }, %) -|> angledLineToY([segAng(seg04) + 180, ZERO], %) +|> angledLineToY([segAng(seg04) + 180, turns::ZERO], %) |> angledLineToY({ angle = -bottomAng, to = -totalHeightHalf - armThick, @@ -79,12 +79,12 @@ part001 = startSketchOn(-XZ) |> xLine(endAbsolute = segEndX(seg03) + 0) |> yLine(length = -segLen(seg01)) |> angledLineThatIntersects({ - angle = HALF_TURN, + angle = turns::HALF_TURN, offset = -armThick, intersectTag = seg02 }, %) |> angledLineToY([segAng(seg02) + 180, -baseHeight], %) -|> xLine(endAbsolute = ZERO) +|> xLine(endAbsolute = turns::ZERO) |> close() |> extrude(length = 4)` ) @@ -483,7 +483,8 @@ test('Sketch on face', async ({ page, homePage, scene, cmdBar, toolbar }) => { await page.addInitScript(async () => { localStorage.setItem( 'persistCode', - `sketch001 = startSketchOn(XZ) + `@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) |> startProfileAt([3.29, 7.86], %) |> line(end = [2.48, 2.44]) |> line(end = [2.66, 1.17]) diff --git a/package.json b/package.json index 658b9d649..fe5c1a0ad 100644 --- a/package.json +++ b/package.json @@ -13,20 +13,20 @@ "license": "MIT", "dependencies": { "@codemirror/autocomplete": "^6.18.6", - "@codemirror/commands": "^6.8.0", + "@codemirror/commands": "^6.8.1", "@codemirror/language": "^6.11.0", - "@codemirror/lint": "^6.8.4", + "@codemirror/lint": "^6.8.5", "@codemirror/search": "^6.5.10", - "@codemirror/state": "^6.4.1", + "@codemirror/state": "^6.5.2", "@codemirror/theme-one-dark": "^6.1.2", - "@csstools/postcss-oklab-function": "^4.0.7", + "@csstools/postcss-oklab-function": "^4.0.8", "@fortawesome/fontawesome-svg-core": "^6.7.2", "@fortawesome/free-brands-svg-icons": "^6.7.2", "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/react-fontawesome": "^0.2.0", "@headlessui/react": "^1.7.19", - "@headlessui/tailwindcss": "^0.2.0", - "@kittycad/lib": "2.0.21", + "@headlessui/tailwindcss": "^0.2.2", + "@kittycad/lib": "2.0.23", "@lezer/highlight": "^1.2.1", "@lezer/lr": "^1.4.1", "@react-hook/resize-observer": "^2.0.1", @@ -37,11 +37,11 @@ "@xstate/react": "^4.1.1", "bonjour-service": "^1.3.0", "bson": "^6.10.3", - "chokidar": "^4.0.1", + "chokidar": "^4.0.3", "codemirror": "^6.0.1", "decamelize": "^6.0.0", "diff": "^7.0.0", - "electron-updater": "^6.6.0", + "electron-updater": "^6.6.2", "fuse.js": "^7.1.0", "html2canvas-pro": "^1.5.8", "isomorphic-fetch": "^3.0.0", @@ -164,15 +164,15 @@ "@iarna/toml": "^2.2.5", "@lezer/generator": "^1.7.2", "@nabla/vite-plugin-eslint": "^2.0.5", - "@playwright/test": "^1.51.0", + "@playwright/test": "^1.51.1", "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^15.0.2", - "@types/diff": "^7.0.1", + "@types/diff": "^7.0.2", "@types/electron": "^1.6.10", "@types/isomorphic-fetch": "^0.0.39", "@types/minimist": "^1.2.5", "@types/mocha": "^10.0.10", - "@types/node": "^22.13.9", + "@types/node": "^22.13.14", "@types/pixelmatch": "^5.2.6", "@types/pngjs": "^6.0.4", "@types/react": "^18.3.4", @@ -182,13 +182,13 @@ "@types/ua-parser-js": "^0.7.39", "@types/uuid": "^9.0.8", "@types/wicg-file-system-access": "^2023.10.5", - "@types/ws": "^8.5.13", - "@vitejs/plugin-react": "^4.3.0", + "@types/ws": "^8.18.0", + "@vitejs/plugin-react": "^4.3.4", "@vitest/web-worker": "^1.5.0", "@xstate/cli": "^0.5.17", - "autoprefixer": "^10.4.19", + "autoprefixer": "^10.4.21", "electron": "^34.1.1", - "electron-builder": "^26.0.6", + "electron-builder": "^26.0.12", "eslint": "^8.0.1", "eslint-plugin-css-modules": "^2.12.0", "eslint-plugin-import": "^2.31.0", @@ -220,7 +220,7 @@ "vite-tsconfig-paths": "^4.3.2", "vitest": "^1.6.1", "vitest-webgl-canvas-mock": "^1.1.0", - "ws": "^8.17.0", + "ws": "^8.18.1", "yarn": "^1.22.22" }, "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" diff --git a/public/kcl-samples/car-wheel-assembly/main.kcl b/public/kcl-samples/car-wheel-assembly/main.kcl index ab22ee318..d4c0e165e 100644 --- a/public/kcl-samples/car-wheel-assembly/main.kcl +++ b/public/kcl-samples/car-wheel-assembly/main.kcl @@ -12,7 +12,7 @@ import "car-tire.kcl" as carTire import lugCount from "globals.kcl" carRotor - |> translate(translate = [0, 0.5, 0]) + |> translate(x = 0, y = 0.5, z = 0) carWheel lugNut |> patternCircular3d( @@ -23,5 +23,5 @@ lugNut rotateDuplicates = false, ) brakeCaliper - |> translate(translate = [0, 0.5, 0]) + |> translate(x = 0, y = 0.5, z = 0) carTire diff --git a/public/kcl-samples/dual-basin-utility-sink/main.kcl b/public/kcl-samples/dual-basin-utility-sink/main.kcl index 686928e12..4485f540f 100644 --- a/public/kcl-samples/dual-basin-utility-sink/main.kcl +++ b/public/kcl-samples/dual-basin-utility-sink/main.kcl @@ -1,6 +1,7 @@ // Dual-Basin Utility Sink // A stainless steel sink unit with dual rectangular basins and six under-counter storage compartments. +// set units @settings(defaultLengthUnit = mm) // globals @@ -12,7 +13,7 @@ profileThickness = 13 metalThickness = 2 blockCount = 3 -blockWidth = (tableWidth-profileThickness) / 3 +blockWidth = (tableWidth - profileThickness) / 3 blockHeight = tableHeight - metalThickness - 0.5 blockDepth = tableDepth - profileThickness @@ -27,9 +28,9 @@ legHeight = blockHeight - profileThickness legCount = blockCount + 1 legBody = startProfileAt([0, 0], floorPlane) - |> yLine(length=profileThickness) - |> xLine(length=profileThickness) - |> yLine(length=-profileThickness) + |> yLine(length = profileThickness) + |> xLine(length = profileThickness) + |> yLine(length = -profileThickness) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() |> patternLinear2d(axis = [1, 0], instances = legCount, distance = blockWidth) @@ -42,9 +43,9 @@ lowerBeltLengthX = blockWidth - profileThickness lowerBeltPlane = startSketchOn(offsetPlane(XY, offset = lowerBeltHeightAboveTheFloor)) lowerBeltBodyX = startProfileAt([profileThickness, 0], lowerBeltPlane) - |> yLine(length=profileThickness) - |> xLine(length=lowerBeltLengthX) - |> yLine(length=-profileThickness) + |> yLine(length = profileThickness) + |> xLine(length = lowerBeltLengthX) + |> yLine(length = -profileThickness) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() |> patternLinear2d(axis = [1, 0], instances = blockCount, distance = blockWidth) @@ -53,12 +54,12 @@ lowerBeltBodyX = startProfileAt([profileThickness, 0], lowerBeltPlane) lowerBeltLengthY = blockDepth - profileThickness lowerBeltBodyY = startProfileAt([0, profileThickness], lowerBeltPlane) - |> yLine(length=lowerBeltLengthY) - |> xLine(length=profileThickness) - |> yLine(length=-lowerBeltLengthY) + |> yLine(length = lowerBeltLengthY) + |> xLine(length = profileThickness) + |> yLine(length = -lowerBeltLengthY) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() - |> patternLinear2d(axis = [1, 0], instances = 2, distance = tableWidth-profileThickness) + |> patternLinear2d(axis = [1, 0], instances = 2, distance = tableWidth - profileThickness) |> extrude(length = profileThickness) // pillars @@ -67,9 +68,9 @@ pillarPlane = startSketchOn(offsetPlane(XY, offset = pillarHeightAboveTheFloor)) pillarTotalHeight = blockHeight - profileThickness - pillarHeightAboveTheFloor pillarBody = startProfileAt([blockSubdivisionWidth, 0], pillarPlane) - |> yLine(length=profileThickness) - |> xLine(length=profileThickness) - |> yLine(length=-profileThickness) + |> yLine(length = profileThickness) + |> xLine(length = profileThickness) + |> yLine(length = -profileThickness) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() |> patternLinear2d(axis = [1, 0], instances = blockCount, distance = blockWidth) @@ -80,9 +81,9 @@ pillarBody = startProfileAt([blockSubdivisionWidth, 0], pillarPlane) upperBeltPlane = startSketchOn(offsetPlane(XY, offset = blockHeight)) upperBeltBodyX = startProfileAt([0, 0], upperBeltPlane) - |> yLine(length=profileThickness) - |> xLine(length=tableWidth) - |> yLine(length=-profileThickness) + |> yLine(length = profileThickness) + |> xLine(length = tableWidth) + |> yLine(length = -profileThickness) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() |> patternLinear2d(axis = [0, 1], instances = 2, distance = blockDepth) @@ -90,20 +91,20 @@ upperBeltBodyX = startProfileAt([0, 0], upperBeltPlane) upperBeltLengthY = blockDepth - profileThickness upperBeltBodyY = startProfileAt([0, profileThickness], upperBeltPlane) - |> yLine(length=upperBeltLengthY) - |> xLine(length=profileThickness) - |> yLine(length=-upperBeltLengthY) + |> yLine(length = upperBeltLengthY) + |> xLine(length = profileThickness) + |> yLine(length = -upperBeltLengthY) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() - |> patternLinear2d(axis = [1, 0], instances = 2, distance = tableWidth-profileThickness) + |> patternLinear2d(axis = [1, 0], instances = 2, distance = tableWidth - profileThickness) |> extrude(length = -profileThickness) // sink tableTopPlane = startSketchOn(offsetPlane(XY, offset = tableHeight)) tableTopBody = startProfileAt([0, 0], tableTopPlane) - |> yLine(length=tableDepth) - |> xLine(length=tableWidth) - |> yLine(length=-tableDepth) + |> yLine(length = tableDepth) + |> xLine(length = tableWidth) + |> yLine(length = -tableDepth) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() |> extrude(length = -metalThickness) @@ -114,59 +115,62 @@ sinkLength = 250 sinkDepth = 200 sinkOffsetFront = 40 sinkOffsetLeft = 350 -sinkSpacing = tableWidth - sinkWidth - sinkOffsetLeft*2 +sinkSpacing = tableWidth - sinkWidth - (sinkOffsetLeft * 2) sinkPlaneOutside = startSketchOn(tableTopBody, 'START') sinkBodyOutside = startProfileAt([-sinkOffsetLeft, sinkOffsetFront], sinkPlaneOutside) - |> yLine(length=sinkLength) - |> xLine(length=-sinkWidth) - |> yLine(length=-sinkLength) + |> yLine(length = sinkLength) + |> xLine(length = -sinkWidth) + |> yLine(length = -sinkLength) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() |> patternLinear2d(axis = [-1, 0], instances = sinkCount, distance = sinkSpacing) |> extrude(length = sinkDepth) sinkPlaneInside = startSketchOn(tableTopBody, 'END') -sinkBodyInside = startProfileAt([sinkOffsetLeft+metalThickness, sinkOffsetFront+metalThickness], sinkPlaneInside) - |> yLine(length=sinkLength-metalThickness*2) - |> xLine(length=sinkWidth-metalThickness*2) - |> yLine(length=-sinkLength+metalThickness*2) +sinkBodyInside = startProfileAt([ + sinkOffsetLeft + metalThickness, + sinkOffsetFront + metalThickness + ], sinkPlaneInside) + |> yLine(length = sinkLength - (metalThickness * 2)) + |> xLine(length = sinkWidth - (metalThickness * 2)) + |> yLine(length = -sinkLength + metalThickness * 2) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() |> patternLinear2d(axis = [1, 0], instances = sinkCount, distance = sinkSpacing) |> extrude(length = -sinkDepth) - + // door panels doorGap = 2 -doorWidth = blockSubdivisionWidth - profileThickness - doorGap*2 -doorStart = profileThickness+doorGap +doorWidth = blockSubdivisionWidth - profileThickness - (doorGap * 2) +doorStart = profileThickness + doorGap doorHeightAboveTheFloor = pillarHeightAboveTheFloor + doorGap doorHeight = blockHeight - doorHeightAboveTheFloor - profileThickness - doorGap doorCount = blockCount * blockSubdivisionCount doorPlane = startSketchOn(offsetPlane(XY, offset = doorHeightAboveTheFloor)) doorBody = startProfileAt([doorStart, 0], doorPlane) - |> yLine(length=profileThickness) - |> xLine(length=doorWidth) - |> yLine(length=-profileThickness) + |> yLine(length = profileThickness) + |> xLine(length = doorWidth) + |> yLine(length = -profileThickness) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() |> patternLinear2d(axis = [1, 0], instances = doorCount, distance = blockSubdivisionWidth) |> extrude(length = doorHeight) // side panels -panelWidth = blockDepth - profileThickness - doorGap*2 +panelWidth = blockDepth - profileThickness - (doorGap * 2) panelCount = doorCount + 1 panelSpacing = tableWidth - profileThickness panelBody = startProfileAt([0, doorStart], doorPlane) - |> yLine(length=panelWidth) - |> xLine(length=profileThickness) - |> yLine(length=-panelWidth) + |> yLine(length = panelWidth) + |> xLine(length = profileThickness) + |> yLine(length = -panelWidth) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() |> patternLinear2d(axis = [1, 0], instances = 2, distance = panelSpacing) |> extrude(length = doorHeight) - + // handle handleDepth = 40 handleWidth = 120 @@ -179,22 +183,25 @@ handleLengthSegmentB = handleWidth - (handleFillet * 2) handlePlane = startSketchOn(offsetPlane(XY, offset = handleHeightAboveTheFloor)) handleProfilePath = startProfileAt([0 + handleOffset, 0], handlePlane) - |> yLine(length=-handleLengthSegmentA) + |> yLine(length = -handleLengthSegmentA) |> tangentialArcTo([ handleFillet + handleOffset, -handleDepth ], %) - |> xLine(length=handleLengthSegmentB) + |> xLine(length = handleLengthSegmentB) |> tangentialArcTo([ handleOffset + handleWidth, -handleLengthSegmentA ], %) - |> yLine(length=handleLengthSegmentA) + |> yLine(length = handleLengthSegmentA) handleSectionPlane = startSketchOn(XZ) handleProfileSection = circle( handleSectionPlane, - center = [handleOffset, handleHeightAboveTheFloor], - radius = 2) - + center = [ + handleOffset, + handleHeightAboveTheFloor + ], + radius = 2, +) handleBody = sweep(handleProfileSection, path = handleProfilePath) |> patternLinear3d(axis = [1, 0, 0], instances = doorCount, distance = blockSubdivisionWidth) diff --git a/public/kcl-samples/i-beam/main.kcl b/public/kcl-samples/i-beam/main.kcl index 4b21ff85b..3fd810cce 100644 --- a/public/kcl-samples/i-beam/main.kcl +++ b/public/kcl-samples/i-beam/main.kcl @@ -5,7 +5,7 @@ @settings(defaultLengthUnit = in) // Define Beam Dimensions -beamLength = 6*ft() +beamLength = 6 * ft() beamHeight = 4 flangeWidth = 2.663 flangeThickness = 0.293 diff --git a/public/kcl-samples/makeup-mirror/main.kcl b/public/kcl-samples/makeup-mirror/main.kcl index deacc57c5..fea832c7c 100644 --- a/public/kcl-samples/makeup-mirror/main.kcl +++ b/public/kcl-samples/makeup-mirror/main.kcl @@ -52,19 +52,22 @@ armPartB = armFn(XZ, armLength, hingeHeight * 2.5 + hingeGap * 2) // mirror fn mirrorFn(plane, offsetX, offsetY, altitude, radius, tiefe, gestellR, gestellD) { - armPlane = startSketchOn(offsetPlane(plane, offset = offsetY - (tiefe / 2))) + armPlane = startSketchOn( offsetPlane(plane, offset = offsetY - (tiefe / 2))) armBody = circle(armPlane, center = [offsetX, altitude], radius = radius) |> extrude(length = tiefe) - archBody = startProfileAt([offsetX-gestellR, altitude], armPlane) + archBody = startProfileAt([offsetX - gestellR, altitude], armPlane) |> xLine(length = gestellD) |> arcTo({ - interior = [offsetX, altitude-gestellR], - end = [offsetX+gestellR, altitude] + interior = [offsetX, altitude - gestellR], + end = [offsetX + gestellR, altitude] }, %) |> xLine(length = gestellD) |> arcTo({ - interior = [offsetX, altitude-gestellR-gestellD], + interior = [ + offsetX, + altitude - gestellR - gestellD + ], end = [profileStartX(%), profileStartY(%)] }, %) |> close() @@ -72,4 +75,4 @@ fn mirrorFn(plane, offsetX, offsetY, altitude, radius, tiefe, gestellR, gestellD return armBody } -mirror = mirrorFn(XZ, armLength, armLength, hingeHeight * 4 + hingeGap * 3 + mirrorRadius+archToMirrorGap+archThickness, mirrorRadius, mirrorThickness, archRadius, archThickness) +mirror = mirrorFn(XZ, armLength, armLength, hingeHeight * 4 + hingeGap * 3 + mirrorRadius + archToMirrorGap + archThickness, mirrorRadius, mirrorThickness, archRadius, archThickness) diff --git a/public/kcl-samples/pipe-flange-assembly/91251a404-bolt.kcl b/public/kcl-samples/pipe-flange-assembly/91251a404-bolt.kcl index 2b264a563..94159764f 100644 --- a/public/kcl-samples/pipe-flange-assembly/91251a404-bolt.kcl +++ b/public/kcl-samples/pipe-flange-assembly/91251a404-bolt.kcl @@ -4,7 +4,6 @@ // set units @settings(defaultLengthUnit = in) - // import constants import boltDiameter, boltLength, boltHeadLength, boltHeadDiameter, boltHexDrive, boltHexFlatLength, boltThreadLength from "globals.kcl" diff --git a/public/kcl-samples/pipe-flange-assembly/98017a257-washer.kcl b/public/kcl-samples/pipe-flange-assembly/98017a257-washer.kcl index ca2980293..0f0a7c066 100644 --- a/public/kcl-samples/pipe-flange-assembly/98017a257-washer.kcl +++ b/public/kcl-samples/pipe-flange-assembly/98017a257-washer.kcl @@ -1,5 +1,5 @@ // 98017A257 Washer -// washer for the screws in the pipe flange assembly. +// washer for the screws in the pipe flange assembly. // set units @settings(defaultLengthUnit = in) diff --git a/public/kcl-samples/pipe-flange-assembly/main.kcl b/public/kcl-samples/pipe-flange-assembly/main.kcl index 15d083ff6..9855056a8 100644 --- a/public/kcl-samples/pipe-flange-assembly/main.kcl +++ b/public/kcl-samples/pipe-flange-assembly/main.kcl @@ -19,27 +19,15 @@ import pipe from "1120t74-pipe.kcl" flange() flange() |> rotate(axis = [0, 1, 0], angle = 180) - |> translate(translate = [ - 0, - 0, - flangeBackHeight * 2 + gasketThickness - ]) + |> translate(x = 0, y = 0, z = flangeBackHeight * 2 + gasketThickness) // place gasket between the flanges gasket() - |> translate(translate = [ - 0, - 0, - -flangeBackHeight - gasketThickness - ]) + |> translate(x = 0, y = 0, z = -flangeBackHeight - gasketThickness) // place eight washers (four front, four back) washer() - |> translate(translate = [ - mountingHolePlacementDiameter / 2, - 0, - flangeBaseThickness - ]) + |> translate(x = mountingHolePlacementDiameter / 2, y = 0, z = flangeBaseThickness) |> patternCircular3d( %, instances = 4, @@ -57,11 +45,7 @@ washer() // place four bolts bolt() - |> translate(translate = [ - mountingHolePlacementDiameter / 2, - 0, - flangeBaseThickness + washerThickness - ]) + |> translate(x = mountingHolePlacementDiameter / 2, y = 0, z = flangeBaseThickness + washerThickness) |> rotate(roll = 90, pitch = 0, yaw = 0) |> patternCircular3d( %, @@ -74,11 +58,7 @@ bolt() // place four hex nuts hexNut() - |> translate(translate = [ - mountingHolePlacementDiameter / 2, - 0, - -(flangeBackHeight * 2 + gasketThickness + flangeBaseThickness + washerThickness + hexNutThickness) - ]) + |> translate(x = mountingHolePlacementDiameter / 2, y = 0, z = -(flangeBackHeight * 2 + gasketThickness + flangeBaseThickness + washerThickness + hexNutThickness)) |> patternCircular3d( %, instances = 4, @@ -98,11 +78,9 @@ pipe() ) |> translate( %, - translate = [ - 0, - 0, - flangeBaseThickness + flangeFrontHeight - 0.5 - ], + x = 0, + y = 0, + z = flangeBaseThickness + flangeFrontHeight - 0.5, global = true, ) @@ -115,10 +93,8 @@ pipe() ) |> translate( %, - translate = [ - 0, - 0, - -(flangeBackHeight * 2 + gasketThickness + flangeBaseThickness + flangeFrontHeight - 0.5) - ], + x = 0, + y = 0, + z = -(flangeBackHeight * 2 + gasketThickness + flangeBaseThickness + flangeFrontHeight - 0.5), global = true, ) diff --git a/public/kcl-samples/router-template-cross-bar/main.kcl b/public/kcl-samples/router-template-cross-bar/main.kcl index ee84d1ed6..34fcfe4e4 100644 --- a/public/kcl-samples/router-template-cross-bar/main.kcl +++ b/public/kcl-samples/router-template-cross-bar/main.kcl @@ -14,7 +14,7 @@ radius = 10 depth = 30 distanceToInsideEdge = slateWidthHalf + templateThickness + templateGap sketch001 = startSketchOn(XZ) - |> startProfileAt([ZERO, depth + templateGap], %) + |> startProfileAt([0, depth + templateGap], %) |> xLine(length = slateWidthHalf - radius, tag = $seg01) |> arc({ angleEnd = 0, @@ -28,7 +28,7 @@ sketch001 = startSketchOn(XZ) |> yLine(length = templateThickness * 2, tag = $seg08) |> xLine(endAbsolute = segEndX(seg02) + 0, tag = $seg05) |> yLine(endAbsolute = segEndY(seg01) + templateThickness, tag = $seg10) - |> xLine(endAbsolute = ZERO, tag = $seg04) + |> xLine(endAbsolute = 0, tag = $seg04) |> xLine(length = -segLen(seg04)) |> yLine(length = -segLen(seg10)) |> xLine(length = -segLen(seg05)) diff --git a/public/kcl-samples/router-template-slate/main.kcl b/public/kcl-samples/router-template-slate/main.kcl index adbde8403..2d1c876e4 100644 --- a/public/kcl-samples/router-template-slate/main.kcl +++ b/public/kcl-samples/router-template-slate/main.kcl @@ -28,7 +28,7 @@ sketch001 = startSketchOn(XZ) |> yLine(endAbsolute = -templateGap * 2 - (templateDiameter / 2), tag = $seg05) |> xLine(endAbsolute = slateWidthHalf + templateThickness, tag = $seg04) |> yLine(length = -length002, tag = $seg03) - |> xLine(endAbsolute = ZERO, tag = $seg02) + |> xLine(endAbsolute = 0, tag = $seg02) // |> line(end = [7.78, 11.16]) |> xLine(length = -segLen(seg02)) |> yLine(length = segLen(seg03)) diff --git a/public/kcl-samples/walkie-talkie/main.kcl b/public/kcl-samples/walkie-talkie/main.kcl index 203880722..8d68708cd 100644 --- a/public/kcl-samples/walkie-talkie/main.kcl +++ b/public/kcl-samples/walkie-talkie/main.kcl @@ -20,37 +20,25 @@ body() // import the antenna antenna() - |> translate(translate = [-width / 2 + .45, -0.10, height / 2]) + |> translate(x = -width / 2 + .45, y = -0.10, z = height / 2) // import the case case() - |> translate(translate = [0, -1, 0]) + |> translate(x = 0, y = -1, z = 0) // import the talk button talkButton() - |> translate(translate = [width / 2, -thickness / 2, .5]) + |> translate(x = width / 2, y = -thickness / 2, z = .5) // import the frequency knob knob() - |> translate(translate = [ - width / 2 - 0.70, - -thickness / 2, - height / 2 - ]) + |> translate(x = width / 2 - 0.70, y = -thickness / 2, z = height / 2) // import the buttons button() - |> translate(translate = [ - -(screenWidth / 2 + tolerance), - -1, - screenYPosition - ]) + |> translate(x = -(screenWidth / 2 + tolerance), y = -1, z = screenYPosition) button() - |> translate(translate = [ - -(screenWidth / 2 + tolerance), - -1, - screenYPosition - buttonHeight - (tolerance * 2) - ]) + |> translate(x = -(screenWidth / 2 + tolerance), y = -1, z = screenYPosition - buttonHeight - (tolerance * 2)) button() |> rotate( %, @@ -59,11 +47,9 @@ button() yaw = 0, ) |> translate( - translate = [ - screenWidth / 2 + tolerance, - -1, - screenYPosition - buttonHeight - ], + x = screenWidth / 2 + tolerance, + y = -1, + z = screenYPosition - buttonHeight, global = true, ) button() @@ -74,10 +60,8 @@ button() yaw = 0, ) |> translate( - translate = [ - screenWidth / 2 + tolerance, - -1, - screenYPosition - (buttonHeight * 2) - (tolerance * 2) - ], + x = screenWidth / 2 + tolerance, + y = -1, + z = screenYPosition - (buttonHeight * 2) - (tolerance * 2), global = true, ) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index ba2521209..d3c912e7b 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -1780,7 +1780,7 @@ dependencies = [ [[package]] name = "kcl-bumper" -version = "0.1.55" +version = "0.1.56" dependencies = [ "anyhow", "clap", @@ -1791,7 +1791,7 @@ dependencies = [ [[package]] name = "kcl-derive-docs" -version = "0.1.55" +version = "0.1.56" dependencies = [ "Inflector", "anyhow", @@ -1810,7 +1810,7 @@ dependencies = [ [[package]] name = "kcl-directory-test-macro" -version = "0.1.55" +version = "0.1.56" dependencies = [ "proc-macro2", "quote", @@ -1819,7 +1819,7 @@ dependencies = [ [[package]] name = "kcl-language-server" -version = "0.2.55" +version = "0.2.56" dependencies = [ "anyhow", "clap", @@ -1840,7 +1840,7 @@ dependencies = [ [[package]] name = "kcl-language-server-release" -version = "0.1.55" +version = "0.1.56" dependencies = [ "anyhow", "clap", @@ -1860,7 +1860,7 @@ dependencies = [ [[package]] name = "kcl-lib" -version = "0.2.55" +version = "0.2.56" dependencies = [ "anyhow", "approx 0.5.1", @@ -1928,7 +1928,7 @@ dependencies = [ [[package]] name = "kcl-python-bindings" -version = "0.3.55" +version = "0.3.56" dependencies = [ "anyhow", "kcl-lib", @@ -1943,7 +1943,7 @@ dependencies = [ [[package]] name = "kcl-test-server" -version = "0.1.55" +version = "0.1.56" dependencies = [ "anyhow", "hyper 0.14.32", @@ -1956,7 +1956,7 @@ dependencies = [ [[package]] name = "kcl-to-core" -version = "0.1.55" +version = "0.1.56" dependencies = [ "anyhow", "async-trait", @@ -1970,7 +1970,7 @@ dependencies = [ [[package]] name = "kcl-wasm-lib" -version = "0.1.55" +version = "0.1.56" dependencies = [ "bson", "console_error_panic_hook", @@ -1996,9 +1996,9 @@ dependencies = [ [[package]] name = "kittycad" -version = "0.3.33" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f6f65645cc07a8f43c34584e4979bf4da16c047cce50c4715fa9381227574d5" +checksum = "0a345fd2a4cb16205f32bd1aa41715045830c59d78c59927fca6580e2a651ac9" dependencies = [ "anyhow", "async-trait", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 3de4d4ebb..a2909ba41 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -35,7 +35,7 @@ clap = { version = "4.5.31", features = ["derive"] } dashmap = { version = "6.1.0" } http = "1" indexmap = "2.7.0" -kittycad = { version = "0.3.33", default-features = false, features = ["js", "requests"] } +kittycad = { version = "0.3.36", default-features = false, features = ["js", "requests"] } kittycad-modeling-cmds = { version = "0.2.107", features = ["ts-rs", "websocket"] } lazy_static = "1.5.0" miette = "7.5.0" diff --git a/rust/kcl-bumper/Cargo.toml b/rust/kcl-bumper/Cargo.toml index 9476ce192..9aeae2585 100644 --- a/rust/kcl-bumper/Cargo.toml +++ b/rust/kcl-bumper/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kcl-bumper" -version = "0.1.55" +version = "0.1.56" edition = "2021" repository = "https://github.com/KittyCAD/modeling-api" rust-version = "1.76" diff --git a/rust/kcl-derive-docs/Cargo.toml b/rust/kcl-derive-docs/Cargo.toml index 66e139449..eddd97ecf 100644 --- a/rust/kcl-derive-docs/Cargo.toml +++ b/rust/kcl-derive-docs/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kcl-derive-docs" description = "A tool for generating documentation from Rust derive macros" -version = "0.1.55" +version = "0.1.56" edition = "2021" license = "MIT" repository = "https://github.com/KittyCAD/modeling-app" diff --git a/rust/kcl-derive-docs/src/lib.rs b/rust/kcl-derive-docs/src/lib.rs index 58ed9e83b..2aa2e0c0e 100644 --- a/rust/kcl-derive-docs/src/lib.rs +++ b/rust/kcl-derive-docs/src/lib.rs @@ -816,7 +816,7 @@ fn generate_code_block_test(fn_name: &str, code_block: &str, index: usize) -> pr async fn #test_name() -> miette::Result<()> { let code = #code_block; // Note, `crate` must be kcl_lib - let result = match crate::test_server::execute_and_snapshot(code, crate::settings::types::UnitLength::Mm, None).await { + let result = match crate::test_server::execute_and_snapshot(code, None).await { Err(crate::errors::ExecError::Kcl(e)) => { return Err(miette::Report::new(crate::errors::Report { error: e.error, diff --git a/rust/kcl-derive-docs/tests/args_with_lifetime.gen b/rust/kcl-derive-docs/tests/args_with_lifetime.gen index 60c38a161..a79915c3c 100644 --- a/rust/kcl-derive-docs/tests/args_with_lifetime.gen +++ b/rust/kcl-derive-docs/tests/args_with_lifetime.gen @@ -31,13 +31,7 @@ mod test_examples_someFn { #[tokio::test(flavor = "multi_thread", worker_threads = 5)] async fn kcl_test_example_someFn0() -> miette::Result<()> { let code = "someFn()"; - let result = match crate::test_server::execute_and_snapshot( - code, - crate::settings::types::UnitLength::Mm, - None, - ) - .await - { + let result = match crate::test_server::execute_and_snapshot(code, None).await { Err(crate::errors::ExecError::Kcl(e)) => { return Err(miette::Report::new(crate::errors::Report { error: e.error, diff --git a/rust/kcl-derive-docs/tests/args_with_refs.gen b/rust/kcl-derive-docs/tests/args_with_refs.gen index 679b8194c..5b6c36566 100644 --- a/rust/kcl-derive-docs/tests/args_with_refs.gen +++ b/rust/kcl-derive-docs/tests/args_with_refs.gen @@ -31,13 +31,7 @@ mod test_examples_someFn { #[tokio::test(flavor = "multi_thread", worker_threads = 5)] async fn kcl_test_example_someFn0() -> miette::Result<()> { let code = "someFn()"; - let result = match crate::test_server::execute_and_snapshot( - code, - crate::settings::types::UnitLength::Mm, - None, - ) - .await - { + let result = match crate::test_server::execute_and_snapshot(code, None).await { Err(crate::errors::ExecError::Kcl(e)) => { return Err(miette::Report::new(crate::errors::Report { error: e.error, diff --git a/rust/kcl-derive-docs/tests/array.gen b/rust/kcl-derive-docs/tests/array.gen index 56d7871d4..9af507c30 100644 --- a/rust/kcl-derive-docs/tests/array.gen +++ b/rust/kcl-derive-docs/tests/array.gen @@ -32,13 +32,7 @@ mod test_examples_show { #[tokio::test(flavor = "multi_thread", worker_threads = 5)] async fn kcl_test_example_show0() -> miette::Result<()> { let code = "This is another code block.\nyes sirrr.\nshow"; - let result = match crate::test_server::execute_and_snapshot( - code, - crate::settings::types::UnitLength::Mm, - None, - ) - .await - { + let result = match crate::test_server::execute_and_snapshot(code, None).await { Err(crate::errors::ExecError::Kcl(e)) => { return Err(miette::Report::new(crate::errors::Report { error: e.error, diff --git a/rust/kcl-derive-docs/tests/box.gen b/rust/kcl-derive-docs/tests/box.gen index be96f7080..a613af7bc 100644 --- a/rust/kcl-derive-docs/tests/box.gen +++ b/rust/kcl-derive-docs/tests/box.gen @@ -32,13 +32,7 @@ mod test_examples_show { #[tokio::test(flavor = "multi_thread", worker_threads = 5)] async fn kcl_test_example_show0() -> miette::Result<()> { let code = "This is code.\nIt does other shit.\nshow"; - let result = match crate::test_server::execute_and_snapshot( - code, - crate::settings::types::UnitLength::Mm, - None, - ) - .await - { + let result = match crate::test_server::execute_and_snapshot(code, None).await { Err(crate::errors::ExecError::Kcl(e)) => { return Err(miette::Report::new(crate::errors::Report { error: e.error, diff --git a/rust/kcl-derive-docs/tests/doc_comment_with_code.gen b/rust/kcl-derive-docs/tests/doc_comment_with_code.gen index b1ba0cfe9..b4410a3e5 100644 --- a/rust/kcl-derive-docs/tests/doc_comment_with_code.gen +++ b/rust/kcl-derive-docs/tests/doc_comment_with_code.gen @@ -33,13 +33,7 @@ mod test_examples_my_func { #[tokio::test(flavor = "multi_thread", worker_threads = 5)] async fn kcl_test_example_my_func0() -> miette::Result<()> { let code = "This is another code block.\nyes sirrr.\nmyFunc"; - let result = match crate::test_server::execute_and_snapshot( - code, - crate::settings::types::UnitLength::Mm, - None, - ) - .await - { + let result = match crate::test_server::execute_and_snapshot(code, None).await { Err(crate::errors::ExecError::Kcl(e)) => { return Err(miette::Report::new(crate::errors::Report { error: e.error, diff --git a/rust/kcl-derive-docs/tests/lineTo.gen b/rust/kcl-derive-docs/tests/lineTo.gen index ff2f2bd4e..17acfb8a0 100644 --- a/rust/kcl-derive-docs/tests/lineTo.gen +++ b/rust/kcl-derive-docs/tests/lineTo.gen @@ -33,13 +33,7 @@ mod test_examples_line_to { #[tokio::test(flavor = "multi_thread", worker_threads = 5)] async fn kcl_test_example_line_to0() -> miette::Result<()> { let code = "This is another code block.\nyes sirrr.\nlineTo"; - let result = match crate::test_server::execute_and_snapshot( - code, - crate::settings::types::UnitLength::Mm, - None, - ) - .await - { + let result = match crate::test_server::execute_and_snapshot(code, None).await { Err(crate::errors::ExecError::Kcl(e)) => { return Err(miette::Report::new(crate::errors::Report { error: e.error, diff --git a/rust/kcl-derive-docs/tests/min.gen b/rust/kcl-derive-docs/tests/min.gen index 6009394a2..435322812 100644 --- a/rust/kcl-derive-docs/tests/min.gen +++ b/rust/kcl-derive-docs/tests/min.gen @@ -32,13 +32,7 @@ mod test_examples_min { #[tokio::test(flavor = "multi_thread", worker_threads = 5)] async fn kcl_test_example_min0() -> miette::Result<()> { let code = "This is another code block.\nyes sirrr.\nmin"; - let result = match crate::test_server::execute_and_snapshot( - code, - crate::settings::types::UnitLength::Mm, - None, - ) - .await - { + let result = match crate::test_server::execute_and_snapshot(code, None).await { Err(crate::errors::ExecError::Kcl(e)) => { return Err(miette::Report::new(crate::errors::Report { error: e.error, diff --git a/rust/kcl-derive-docs/tests/option.gen b/rust/kcl-derive-docs/tests/option.gen index e44a8c461..3441316c8 100644 --- a/rust/kcl-derive-docs/tests/option.gen +++ b/rust/kcl-derive-docs/tests/option.gen @@ -32,13 +32,7 @@ mod test_examples_show { #[tokio::test(flavor = "multi_thread", worker_threads = 5)] async fn kcl_test_example_show0() -> miette::Result<()> { let code = "This is code.\nIt does other shit.\nshow"; - let result = match crate::test_server::execute_and_snapshot( - code, - crate::settings::types::UnitLength::Mm, - None, - ) - .await - { + let result = match crate::test_server::execute_and_snapshot(code, None).await { Err(crate::errors::ExecError::Kcl(e)) => { return Err(miette::Report::new(crate::errors::Report { error: e.error, diff --git a/rust/kcl-derive-docs/tests/option_input_format.gen b/rust/kcl-derive-docs/tests/option_input_format.gen index b0c801e47..b6fb3b4bf 100644 --- a/rust/kcl-derive-docs/tests/option_input_format.gen +++ b/rust/kcl-derive-docs/tests/option_input_format.gen @@ -32,13 +32,7 @@ mod test_examples_import { #[tokio::test(flavor = "multi_thread", worker_threads = 5)] async fn kcl_test_example_import0() -> miette::Result<()> { let code = "This is code.\nIt does other shit.\nimport"; - let result = match crate::test_server::execute_and_snapshot( - code, - crate::settings::types::UnitLength::Mm, - None, - ) - .await - { + let result = match crate::test_server::execute_and_snapshot(code, None).await { Err(crate::errors::ExecError::Kcl(e)) => { return Err(miette::Report::new(crate::errors::Report { error: e.error, diff --git a/rust/kcl-derive-docs/tests/return_vec_box_sketch.gen b/rust/kcl-derive-docs/tests/return_vec_box_sketch.gen index 8a2d46da0..b7bc31f51 100644 --- a/rust/kcl-derive-docs/tests/return_vec_box_sketch.gen +++ b/rust/kcl-derive-docs/tests/return_vec_box_sketch.gen @@ -32,13 +32,7 @@ mod test_examples_import { #[tokio::test(flavor = "multi_thread", worker_threads = 5)] async fn kcl_test_example_import0() -> miette::Result<()> { let code = "This is code.\nIt does other shit.\nimport"; - let result = match crate::test_server::execute_and_snapshot( - code, - crate::settings::types::UnitLength::Mm, - None, - ) - .await - { + let result = match crate::test_server::execute_and_snapshot(code, None).await { Err(crate::errors::ExecError::Kcl(e)) => { return Err(miette::Report::new(crate::errors::Report { error: e.error, diff --git a/rust/kcl-derive-docs/tests/return_vec_sketch.gen b/rust/kcl-derive-docs/tests/return_vec_sketch.gen index 1501d992f..08c97efbd 100644 --- a/rust/kcl-derive-docs/tests/return_vec_sketch.gen +++ b/rust/kcl-derive-docs/tests/return_vec_sketch.gen @@ -32,13 +32,7 @@ mod test_examples_import { #[tokio::test(flavor = "multi_thread", worker_threads = 5)] async fn kcl_test_example_import0() -> miette::Result<()> { let code = "This is code.\nIt does other shit.\nimport"; - let result = match crate::test_server::execute_and_snapshot( - code, - crate::settings::types::UnitLength::Mm, - None, - ) - .await - { + let result = match crate::test_server::execute_and_snapshot(code, None).await { Err(crate::errors::ExecError::Kcl(e)) => { return Err(miette::Report::new(crate::errors::Report { error: e.error, diff --git a/rust/kcl-derive-docs/tests/show.gen b/rust/kcl-derive-docs/tests/show.gen index 00ae5ecdf..26aa3613b 100644 --- a/rust/kcl-derive-docs/tests/show.gen +++ b/rust/kcl-derive-docs/tests/show.gen @@ -32,13 +32,7 @@ mod test_examples_show { #[tokio::test(flavor = "multi_thread", worker_threads = 5)] async fn kcl_test_example_show0() -> miette::Result<()> { let code = "This is code.\nIt does other shit.\nshow"; - let result = match crate::test_server::execute_and_snapshot( - code, - crate::settings::types::UnitLength::Mm, - None, - ) - .await - { + let result = match crate::test_server::execute_and_snapshot(code, None).await { Err(crate::errors::ExecError::Kcl(e)) => { return Err(miette::Report::new(crate::errors::Report { error: e.error, diff --git a/rust/kcl-derive-docs/tests/test_args_with_exec_state.gen b/rust/kcl-derive-docs/tests/test_args_with_exec_state.gen index 6fa5ac694..ce8088a64 100644 --- a/rust/kcl-derive-docs/tests/test_args_with_exec_state.gen +++ b/rust/kcl-derive-docs/tests/test_args_with_exec_state.gen @@ -31,13 +31,7 @@ mod test_examples_some_function { #[tokio::test(flavor = "multi_thread", worker_threads = 5)] async fn kcl_test_example_some_function0() -> miette::Result<()> { let code = "someFunction()"; - let result = match crate::test_server::execute_and_snapshot( - code, - crate::settings::types::UnitLength::Mm, - None, - ) - .await - { + let result = match crate::test_server::execute_and_snapshot(code, None).await { Err(crate::errors::ExecError::Kcl(e)) => { return Err(miette::Report::new(crate::errors::Report { error: e.error, diff --git a/rust/kcl-directory-test-macro/Cargo.toml b/rust/kcl-directory-test-macro/Cargo.toml index 64a2aba41..df302b97f 100644 --- a/rust/kcl-directory-test-macro/Cargo.toml +++ b/rust/kcl-directory-test-macro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kcl-directory-test-macro" description = "A tool for generating tests from a directory of kcl files" -version = "0.1.55" +version = "0.1.56" edition = "2021" license = "MIT" repository = "https://github.com/KittyCAD/modeling-app" diff --git a/rust/kcl-language-server-release/Cargo.toml b/rust/kcl-language-server-release/Cargo.toml index e48fe3baa..e21f4d468 100644 --- a/rust/kcl-language-server-release/Cargo.toml +++ b/rust/kcl-language-server-release/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kcl-language-server-release" -version = "0.1.55" +version = "0.1.56" edition = "2021" authors = ["KittyCAD Inc "] publish = false diff --git a/rust/kcl-language-server/Cargo.toml b/rust/kcl-language-server/Cargo.toml index cd779f078..2a8320b7d 100644 --- a/rust/kcl-language-server/Cargo.toml +++ b/rust/kcl-language-server/Cargo.toml @@ -2,7 +2,7 @@ name = "kcl-language-server" description = "A language server for KCL." authors = ["KittyCAD Inc "] -version = "0.2.55" +version = "0.2.56" edition = "2021" license = "MIT" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/rust/kcl-language-server/yarn.lock b/rust/kcl-language-server/yarn.lock index 70459fea4..2d232da91 100644 --- a/rust/kcl-language-server/yarn.lock +++ b/rust/kcl-language-server/yarn.lock @@ -2194,9 +2194,9 @@ supports-color@^8.1.1: has-flag "^4.0.0" tar-fs@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" - integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + version "2.1.2" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.2.tgz#425f154f3404cb16cb8ff6e671d45ab2ed9596c5" + integrity sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA== dependencies: chownr "^1.1.1" mkdirp-classic "^0.5.2" diff --git a/rust/kcl-lib/Cargo.toml b/rust/kcl-lib/Cargo.toml index 795c90cd8..f771c73fc 100644 --- a/rust/kcl-lib/Cargo.toml +++ b/rust/kcl-lib/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kcl-lib" description = "KittyCAD Language implementation and tools" -version = "0.2.55" +version = "0.2.56" edition = "2021" license = "MIT" repository = "https://github.com/KittyCAD/modeling-app" @@ -104,7 +104,7 @@ tower-lsp = { workspace = true, features = ["proposed", "default"] } [features] default = ["engine"] -cli = ["dep:clap"] +cli = ["dep:clap", "kittycad/clap"] dhat-heap = ["dep:dhat"] # For the lsp server, when run with stdout for rpc we want to disable println. # This is used for editor extensions that use the lsp server. @@ -153,8 +153,3 @@ harness = false name = "executor" path = "e2e/executor/main.rs" required-features = ["engine"] - -[[test]] -name = "modify" -path = "e2e/modify/main.rs" -required-features = ["engine"] diff --git a/rust/kcl-lib/benches/benchmark_kcl_samples.rs b/rust/kcl-lib/benches/benchmark_kcl_samples.rs index 7f32df1ee..80a69a1f4 100644 --- a/rust/kcl-lib/benches/benchmark_kcl_samples.rs +++ b/rust/kcl-lib/benches/benchmark_kcl_samples.rs @@ -76,7 +76,7 @@ fn run_benchmarks(c: &mut Criterion) { group.bench_function(format!("execute_{}", dir_name), |b| { b.iter(|| { if let Err(err) = rt.block_on(async { - let ctx = kcl_lib::ExecutorContext::new_with_default_client(Default::default()).await?; + let ctx = kcl_lib::ExecutorContext::new_with_default_client().await?; let mut exec_state = kcl_lib::ExecState::new(&ctx); ctx.run(black_box(&program), &mut exec_state).await?; ctx.close().await; diff --git a/rust/kcl-lib/e2e/executor/cache.rs b/rust/kcl-lib/e2e/executor/cache.rs index 991dd58ce..07e81cc28 100644 --- a/rust/kcl-lib/e2e/executor/cache.rs +++ b/rust/kcl-lib/e2e/executor/cache.rs @@ -1,6 +1,8 @@ //! Cache testing framework. use kcl_lib::{bust_cache, ExecError, ExecOutcome}; +use kcmc::{each_cmd as mcmd, ModelingCmd}; +use kittycad_modeling_cmds as kcmc; #[derive(Debug)] struct Variation<'a> { @@ -49,45 +51,6 @@ async fn cache_test( img_results } -#[tokio::test(flavor = "multi_thread")] -async fn kcl_test_cache_change_units_changes_output() { - let code = r#"part001 = startSketchOn('XY') - |> startProfileAt([5.5229, 5.25217], %) - |> line(end = [10.50433, -1.19122]) - |> line(end = [8.01362, -5.48731]) - |> line(end = [-1.02877, -6.76825]) - |> line(end = [-11.53311, 2.81559]) - |> close() - |> extrude(length = 4) -"#; - - let result = cache_test( - "change_units_changes_output", - vec![ - Variation { - code, - settings: &kcl_lib::ExecutorSettings { - units: kcl_lib::UnitLength::In, - ..Default::default() - }, - }, - Variation { - code, - settings: &kcl_lib::ExecutorSettings { - units: kcl_lib::UnitLength::Mm, - ..Default::default() - }, - }, - ], - ) - .await; - - let first = result.first().unwrap(); - let second = result.last().unwrap(); - - assert!(first.1 != second.1); -} - #[tokio::test(flavor = "multi_thread")] async fn kcl_test_cache_change_grid_visualizes_grid_off_to_on() { let code = r#"part001 = startSketchOn('XY') @@ -253,3 +216,69 @@ extrude(sketch001, length = 4) second.artifact_graph.len() ); } + +#[tokio::test(flavor = "multi_thread")] +async fn kcl_test_cache_empty_file_pop_cache_empty_file_planes_work() { + // Get the current working directory. + let code = ""; + + let ctx = kcl_lib::ExecutorContext::new_with_default_client().await.unwrap(); + let program = kcl_lib::Program::parse_no_errs(code).unwrap(); + let outcome = ctx.run_with_caching(program).await.unwrap(); + + // Ensure nothing is left in the batch + assert!(ctx.engine.batch().read().await.is_empty()); + assert!(ctx.engine.batch_end().read().await.is_empty()); + + // Ensure the planes work, and we can show or hide them. + // Hide/show the grid. + let default_planes = ctx.engine.get_default_planes().read().await.clone().unwrap(); + + // Assure the outcome is the same. + assert_eq!(outcome.default_planes, Some(default_planes.clone())); + + ctx.engine + .send_modeling_cmd( + uuid::Uuid::new_v4(), + Default::default(), + &ModelingCmd::from(mcmd::ObjectVisible { + hidden: false, + object_id: default_planes.xy, + }), + ) + .await + .unwrap(); + + // Now simulate an engine pause/network disconnect. + // Raw dog clear the scene entirely. + ctx.engine + .send_modeling_cmd( + uuid::Uuid::new_v4(), + Default::default(), + &ModelingCmd::from(mcmd::SceneClearAll {}), + ) + .await + .unwrap(); + + // Bust the cache and reset the scene. + let outcome = ctx.bust_cache_and_reset_scene().await.unwrap(); + // Get the default planes. + let default_planes = ctx.engine.get_default_planes().read().await.clone().unwrap(); + + assert_eq!(outcome.default_planes, Some(default_planes.clone())); + + // Ensure we can show a plane. + ctx.engine + .send_modeling_cmd( + uuid::Uuid::new_v4(), + Default::default(), + &ModelingCmd::from(mcmd::ObjectVisible { + hidden: false, + object_id: default_planes.xz, + }), + ) + .await + .unwrap(); + + ctx.close().await; +} diff --git a/rust/kcl-lib/e2e/executor/inputs/cylinder-inches.kcl b/rust/kcl-lib/e2e/executor/inputs/cylinder-inches.kcl new file mode 100644 index 000000000..a23ac0b81 --- /dev/null +++ b/rust/kcl-lib/e2e/executor/inputs/cylinder-inches.kcl @@ -0,0 +1,4 @@ +@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) + |> circle(center = [0, 0], radius = 20) +extrude001 = extrude(sketch001, length = 10) diff --git a/rust/kcl-lib/e2e/executor/inputs/e2e-can-sketch-on-chamfer-no-pipeExpr.kcl b/rust/kcl-lib/e2e/executor/inputs/e2e-can-sketch-on-chamfer-no-pipeExpr.kcl index 1ee7bf174..66bbbdfb3 100644 --- a/rust/kcl-lib/e2e/executor/inputs/e2e-can-sketch-on-chamfer-no-pipeExpr.kcl +++ b/rust/kcl-lib/e2e/executor/inputs/e2e-can-sketch-on-chamfer-no-pipeExpr.kcl @@ -1,4 +1,5 @@ -const sketch001 = startSketchOn(XZ) +@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) |> startProfileAt([75.8, 317.2], %) |> angledLine([0, 268.43], %, $rectangleSegmentA001) |> angledLine([ @@ -11,8 +12,8 @@ const sketch001 = startSketchOn(XZ) ], %, $yo) |> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02) |> close() -const extrude001 = extrude(sketch001, length = 100) -const chamf = chamfer( +extrude001 = extrude(sketch001, length = 100) +chamf = chamfer( extrude001, length = 30, tags = [ diff --git a/rust/kcl-lib/e2e/executor/inputs/e2e-can-sketch-on-chamfer.kcl b/rust/kcl-lib/e2e/executor/inputs/e2e-can-sketch-on-chamfer.kcl index 30b0e8367..d36ebcf9e 100644 --- a/rust/kcl-lib/e2e/executor/inputs/e2e-can-sketch-on-chamfer.kcl +++ b/rust/kcl-lib/e2e/executor/inputs/e2e-can-sketch-on-chamfer.kcl @@ -1,4 +1,5 @@ -const sketch001 = startSketchOn(XZ) +@settings(defaultLengthUnit = in) +sketch001 = startSketchOn(XZ) |> startProfileAt([75.8, 317.2], %) // [$startCapTag, $EndCapTag] |> angledLine([0, 268.43], %, $rectangleSegmentA001) |> angledLine([ @@ -11,7 +12,7 @@ const sketch001 = startSketchOn(XZ) ], %, $yo) |> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02) |> close() -const extrude001 = extrude(sketch001, length = 100) +extrude001 = extrude(sketch001, length = 100) |> chamfer( length = 30, tags = [ diff --git a/rust/kcl-lib/e2e/executor/main.rs b/rust/kcl-lib/e2e/executor/main.rs index 32f1759b6..327cb9ab3 100644 --- a/rust/kcl-lib/e2e/executor/main.rs +++ b/rust/kcl-lib/e2e/executor/main.rs @@ -2,7 +2,7 @@ mod cache; use kcl_lib::{ test_server::{execute_and_export_step, execute_and_snapshot, execute_and_snapshot_no_auth}, - ExecError, UnitLength, + ExecError, }; /// The minimum permissible difference between asserted twenty-twenty images. @@ -26,7 +26,7 @@ pub(crate) fn assert_out(test_name: &str, result: &image::DynamicImage) -> Strin async fn kcl_test_fillet_duplicate_tags() { let code = kcl_input!("fillet_duplicate_tags"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; let err = result.expect_err("Code should have failed due to the duplicate edges being filletted"); let err = err.as_kcl_error().unwrap(); @@ -48,7 +48,7 @@ async fn kcl_test_execute_engine_error_return() { |> extrude(length = 4) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -61,7 +61,7 @@ async fn kcl_test_execute_i_shape() { // This is some code from lee that starts a pipe expression with a variable. let code = kcl_input!("i_shape"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("i_shape", &result); } @@ -70,7 +70,7 @@ async fn kcl_test_execute_i_shape() { async fn kcl_test_execute_pipes_on_pipes() { let code = kcl_input!("pipes_on_pipes"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("pipes_on_pipes", &result); } @@ -78,7 +78,7 @@ async fn kcl_test_execute_pipes_on_pipes() { async fn kcl_test_execute_cylinder() { let code = kcl_input!("cylinder"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("cylinder", &result); } @@ -86,7 +86,7 @@ async fn kcl_test_execute_cylinder() { async fn kcl_test_execute_kittycad_svg() { let code = kcl_input!("kittycad_svg"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("kittycad_svg", &result); } @@ -94,7 +94,7 @@ async fn kcl_test_execute_kittycad_svg() { async fn kcl_test_execute_lsystem() { let code = kcl_input!("lsystem"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("lsystem", &result); } @@ -102,7 +102,7 @@ async fn kcl_test_execute_lsystem() { async fn kcl_test_member_expression_sketch() { let code = kcl_input!("member_expression_sketch"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("member_expression_sketch", &result); } @@ -110,7 +110,7 @@ async fn kcl_test_member_expression_sketch() { async fn kcl_test_helix_defaults() { let code = kcl_input!("helix_defaults"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("helix_defaults", &result); } @@ -118,7 +118,7 @@ async fn kcl_test_helix_defaults() { async fn kcl_test_helix_defaults_negative_extrude() { let code = kcl_input!("helix_defaults_negative_extrude"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("helix_defaults_negative_extrude", &result); } @@ -126,7 +126,7 @@ async fn kcl_test_helix_defaults_negative_extrude() { async fn kcl_test_helix_with_length() { let code = kcl_input!("helix_with_length"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("helix_with_length", &result); } @@ -134,7 +134,7 @@ async fn kcl_test_helix_with_length() { async fn kcl_test_dimensions_match() { let code = kcl_input!("dimensions_match"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("dimensions_match", &result); } @@ -142,7 +142,7 @@ async fn kcl_test_dimensions_match() { async fn kcl_test_close_arc() { let code = kcl_input!("close_arc"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("close_arc", &result); } @@ -150,7 +150,7 @@ async fn kcl_test_close_arc() { async fn kcl_test_negative_args() { let code = kcl_input!("negative_args"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("negative_args", &result); } @@ -164,7 +164,7 @@ async fn kcl_test_basic_tangential_arc_with_point() { |> extrude(length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("tangential_arc_with_point", &result); } @@ -178,7 +178,7 @@ async fn kcl_test_basic_tangential_arc_to() { |> extrude(length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("tangential_arc_to", &result); } @@ -205,7 +205,7 @@ box(30, 43, 18, '-xy') let thing = box(-12, -15, 10, 'yz') box(-20, -5, 10, 'xy')"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("different_planes_same_drawing", &result); } @@ -263,7 +263,7 @@ part004 = startSketchOn(YZ) |> close() "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("lots_of_planes", &result); } @@ -280,7 +280,7 @@ async fn kcl_test_holes() { |> extrude(length = 2) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("holes", &result); } @@ -299,7 +299,7 @@ async fn optional_params() { thing = other_circle([2, 2], 20) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("optional_params", &result); } @@ -335,7 +335,7 @@ part = roundedRectangle([0, 0], 20, 20, 4) |> extrude(length = 2) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("rounded_with_holes", &result); } @@ -343,7 +343,7 @@ part = roundedRectangle([0, 0], 20, 20, 4) async fn kcl_test_top_level_expression() { let code = r#"startSketchOn(XY) |> circle(center = [0,0], radius= 22) |> extrude(length = 14)"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("top_level_expression", &result); } @@ -357,7 +357,7 @@ part = startSketchOn(XY) |> extrude(length = 1) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_linear_basic_with_math", &result); } @@ -369,7 +369,7 @@ async fn kcl_test_patterns_linear_basic() { |> extrude(length = 1) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_linear_basic", &result); } @@ -385,7 +385,7 @@ async fn kcl_test_patterns_linear_basic_3d() { |> patternLinear3d(axis = [1, 0, 1], instances = 4, distance = 6) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_linear_basic_3d", &result); } @@ -397,7 +397,7 @@ async fn kcl_test_patterns_linear_basic_negative_distance() { |> extrude(length = 1) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_linear_basic_negative_distance", &result); } @@ -409,7 +409,7 @@ async fn kcl_test_patterns_linear_basic_negative_axis() { |> extrude(length = 1) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_linear_basic_negative_axis", &result); } @@ -430,7 +430,7 @@ rectangle = startSketchOn(XY) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_linear_basic_holes", &result); } @@ -442,7 +442,7 @@ async fn kcl_test_patterns_circular_basic_2d() { |> extrude(length = 1) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_circular_basic_2d", &result); } @@ -458,7 +458,7 @@ async fn kcl_test_patterns_circular_basic_3d() { |> patternCircular3d(axis = [0,0, 1], center = [-20, -20, -20], instances = 41, arcDegrees = 360, rotateDuplicates = false) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_circular_basic_3d", &result); } @@ -474,7 +474,7 @@ async fn kcl_test_patterns_circular_3d_tilted_axis() { |> patternCircular3d(axis = [1,1,0], center = [10, 0, 10], instances = 11, arcDegrees = 360, rotateDuplicates = true) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("patterns_circular_3d_tilted_axis", &result); } @@ -483,7 +483,7 @@ async fn kcl_test_import_file_doesnt_exist() { let code = r#"import 'thing.obj' model = cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -496,7 +496,7 @@ async fn kcl_test_import_obj_with_mtl() { let code = r#"import 'e2e/executor/inputs/cube.obj' model = cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("import_obj_with_mtl", &result); } @@ -506,7 +506,7 @@ async fn kcl_test_import_obj_with_mtl_units() { import 'e2e/executor/inputs/cube.obj' model = cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("import_obj_with_mtl_units", &result); } @@ -515,7 +515,7 @@ async fn kcl_test_import_stl() { let code = r#"import 'e2e/executor/inputs/2-5-long-m8-chc-screw.stl' as screw model = screw"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("import_stl", &result); } @@ -524,7 +524,7 @@ async fn kcl_test_import_gltf_with_bin() { let code = r#"import 'e2e/executor/inputs/cube.gltf' model = cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("import_gltf_with_bin", &result); } @@ -533,7 +533,7 @@ async fn kcl_test_import_gltf_embedded() { let code = r#"import 'e2e/executor/inputs/cube-embedded.gltf' as cube model = cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("import_gltf_embedded", &result); } @@ -542,7 +542,7 @@ async fn kcl_test_import_glb() { let code = r#"import 'e2e/executor/inputs/cube.glb' model = cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("import_glb", &result); } @@ -551,7 +551,7 @@ async fn kcl_test_import_glb_no_assign() { let code = r#"import 'e2e/executor/inputs/cube.glb' cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("import_glb_no_assign", &result); } @@ -561,7 +561,7 @@ async fn kcl_test_import_ext_doesnt_match() { import 'e2e/executor/inputs/cube.gltf' model = cube"#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -586,14 +586,15 @@ async fn kcl_test_cube_mm() { myCube = cube([0,0], 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("cube_mm", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_cube_cm() { - let code = r#"fn cube = (pos, scale) => { - sg = startSketchOn(XY) + let code = r#"@settings(defaultLengthUnit = cm) +fn cube = (pos, scale) => { + sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale]) |> line(end = [scale, 0]) @@ -607,14 +608,15 @@ async fn kcl_test_cube_cm() { myCube = cube([0,0], 10) "#; - let result = execute_and_snapshot(code, UnitLength::Cm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("cube_cm", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_cube_m() { - let code = r#"fn cube = (pos, scale) => { - sg = startSketchOn(XY) + let code = r#"@settings(defaultLengthUnit = m) +fn cube = (pos, scale) => { + sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale]) |> line(end = [scale, 0]) @@ -628,14 +630,15 @@ async fn kcl_test_cube_m() { myCube = cube([0,0], 10) "#; - let result = execute_and_snapshot(code, UnitLength::M, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("cube_m", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_cube_in() { - let code = r#"fn cube = (pos, scale) => { - sg = startSketchOn(XY) + let code = r#"@settings(defaultLengthUnit = in) +fn cube = (pos, scale) => { + sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale]) |> line(end = [scale, 0]) @@ -649,14 +652,15 @@ async fn kcl_test_cube_in() { myCube = cube([0,0], 10) "#; - let result = execute_and_snapshot(code, UnitLength::In, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("cube_in", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_cube_ft() { - let code = r#"fn cube = (pos, scale) => { - sg = startSketchOn(XY) + let code = r#"@settings(defaultLengthUnit = ft) +fn cube = (pos, scale) => { + sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale]) |> line(end = [scale, 0]) @@ -670,14 +674,15 @@ async fn kcl_test_cube_ft() { myCube = cube([0,0], 10) "#; - let result = execute_and_snapshot(code, UnitLength::Ft, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("cube_ft", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_cube_yd() { - let code = r#"fn cube = (pos, scale) => { - sg = startSketchOn(XY) + let code = r#"@settings(defaultLengthUnit = yd) +fn cube = (pos, scale) => { + sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line(end = [0, scale]) |> line(end = [scale, 0]) @@ -691,7 +696,7 @@ async fn kcl_test_cube_yd() { myCube = cube([0,0], 10) "#; - let result = execute_and_snapshot(code, UnitLength::Yd, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("cube_yd", &result); } @@ -719,7 +724,7 @@ part002 = startSketchOn(part001, part001.sketch.tags.here) |> extrude(length = 1) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; let err = result.err().unwrap(); let ExecError::Kcl(err) = err else { @@ -763,7 +768,7 @@ part003 = startSketchOn(part002, "end") |> extrude(length = 5) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("sketch_on_face_of_face", &result); } @@ -780,7 +785,7 @@ async fn kcl_test_stdlib_kcl_error_right_code_path() { |> extrude(length = 2) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; let err = result.err().unwrap(); let ExecError::Kcl(err) = err else { panic!("Expected KCL error, found {err}"); @@ -811,7 +816,7 @@ part002 = startSketchOn(part001, "end") |> extrude(length = 5) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("sketch_on_face_circle", &result); } @@ -853,7 +858,7 @@ part = rectShape([0, 0], 20, 20) ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; let err = result.err().unwrap(); let ExecError::Kcl(err) = err else { panic!("Expected KCL error, found {err}"); @@ -880,7 +885,7 @@ async fn kcl_test_simple_revolve() { "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("simple_revolve", &result); } @@ -900,7 +905,7 @@ async fn kcl_test_simple_revolve_uppercase() { "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("simple_revolve_uppercase", &result); } @@ -920,7 +925,7 @@ async fn kcl_test_simple_revolve_negative() { "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("simple_revolve_negative", &result); } @@ -940,7 +945,7 @@ async fn kcl_test_revolve_bad_angle_low() { "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert!(result @@ -966,7 +971,7 @@ async fn kcl_test_revolve_bad_angle_high() { "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert!(result @@ -992,7 +997,7 @@ async fn kcl_test_simple_revolve_custom_angle() { "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("simple_revolve_custom_angle", &result); } @@ -1012,7 +1017,7 @@ async fn kcl_test_simple_revolve_custom_axis() { "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("simple_revolve_custom_axis", &result); } @@ -1036,7 +1041,7 @@ sketch001 = startSketchOn(box, "end") "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("revolve_on_edge", &result); } @@ -1060,7 +1065,7 @@ sketch001 = startSketchOn(box, revolveAxis) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; result.unwrap_err(); //this fails right now, but slightly differently, lets just say its enough for it to fail - mike @@ -1088,7 +1093,7 @@ sketch001 = startSketchOn(box, "END") ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("revolve_on_face_circle_edge", &result); } @@ -1110,7 +1115,7 @@ sketch001 = startSketchOn(box, "END") ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("revolve_on_face_circle", &result); } @@ -1136,7 +1141,7 @@ sketch001 = startSketchOn(box, "end") ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("revolve_on_face", &result); } @@ -1150,7 +1155,7 @@ async fn kcl_test_basic_revolve_circle() { ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("basic_revolve_circle", &result); } @@ -1177,7 +1182,7 @@ part002 = startSketchOn(part001, 'end') |> extrude(length = 5) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("simple_revolve_sketch_on_edge", &result); } @@ -1240,7 +1245,7 @@ plumbus1 = circle1 ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("plumbus_fillets", &result); } @@ -1248,7 +1253,7 @@ plumbus1 = circle1 async fn kcl_test_empty_file_is_ok() { let code = r#""#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; result.unwrap(); } @@ -1278,7 +1283,7 @@ async fn kcl_test_member_expression_in_params() { capScrew([0, 0.5, 0], 50, 37.5, 50, 25) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("member_expression_in_params", &result); } @@ -1323,7 +1328,7 @@ bracket = startSketchOn(XY) ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; result.unwrap(); } @@ -1343,7 +1348,7 @@ secondSketch = startSketchOn(part001, '') |> extrude(length = 20) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1374,7 +1379,7 @@ extrusion = startSketchOn(XY) |> extrude(length = height) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1407,7 +1412,7 @@ sketch001 = [profile001, profile002] extrude(sketch001, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("array_of_sketches", &result); } @@ -1444,7 +1449,7 @@ pattn1 = patternLinear3d( ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("pattern3d_array_of_extrudes", &result); } @@ -1492,7 +1497,7 @@ baseExtrusion = extrude(sketch001, length = width) ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("fillets_referencing_other_fillets", &result); } @@ -1540,7 +1545,7 @@ baseExtrusion = extrude(sketch001, length = width) ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("chamfers_referencing_other_chamfers", &result); } @@ -1560,7 +1565,7 @@ async fn kcl_test_shell_with_tag() { ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("shell_with_tag", &result); } @@ -1591,7 +1596,7 @@ pattn1 = patternLinear3d( ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("linear_pattern3d_filleted_sketch", &result); } @@ -1618,7 +1623,7 @@ pattn2 = patternCircular3d(part001, axis = [0,0, 1], center = [-20, -20, -20], i "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("circular_pattern3d_filleted_sketch", &result); } @@ -1644,7 +1649,7 @@ part001 = cube([0,0], 20) pattn2 = patternCircular3d(part001, axis = [0,0, 1], center = [-20, -20, -20], instances = 5, arcDegrees = 360, rotateDuplicates = false) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("circular_pattern3d_chamfered_sketch", &result); } @@ -1671,7 +1676,7 @@ part001 = cube([0,0], 20) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; let err = result.err().unwrap(); let ExecError::Kcl(err) = err else { panic!("Expected KCL error, found {err}"); @@ -1701,7 +1706,7 @@ async fn kcl_test_duplicate_tags_should_error() { let p = triangle(200) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1712,49 +1717,49 @@ let p = triangle(200) #[tokio::test(flavor = "multi_thread")] async fn kcl_test_global_tags() { let code = kcl_input!("global-tags"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("global_tags", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_extrude_inside_fn_with_tags() { let code = kcl_input!("extrude-inside-fn-with-tags"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("extrude-inside-fn-with-tags", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_pattern_vase() { let code = kcl_input!("pattern_vase"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("pattern_vase", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_scoped_tags() { let code = kcl_input!("scoped-tags"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("scoped_tags", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_order_sketch_extrude_in_order() { let code = kcl_input!("order-sketch-extrude-in-order"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("order-sketch-extrude-in-order", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_order_sketch_extrude_out_of_order() { let code = kcl_input!("order-sketch-extrude-out-of-order"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("order-sketch-extrude-out-of-order", &result); } #[tokio::test(flavor = "multi_thread")] async fn kcl_test_extrude_custom_plane() { let code = kcl_input!("extrude-custom-plane"); - let result = execute_and_snapshot(code, UnitLength::Mm, None).await.unwrap(); + let result = execute_and_snapshot(code, None).await.unwrap(); assert_out("extrude-custom-plane", &result); } @@ -1776,7 +1781,7 @@ async fn kcl_test_arc_error_same_start_end() { ) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1796,7 +1801,7 @@ async fn kcl_test_angled_line_to_x_90() { example = extrude(exampleSketch, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1816,7 +1821,7 @@ async fn kcl_test_angled_line_to_x_270() { example = extrude(exampleSketch, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1836,7 +1841,7 @@ async fn kcl_test_angled_line_to_y_0() { example = extrude(exampleSketch, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1856,7 +1861,7 @@ async fn kcl_test_angled_line_to_y_180() { example = extrude(exampleSketch, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1876,7 +1881,7 @@ async fn kcl_test_angled_line_of_x_length_90() { extrusion = extrude(sketch001, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1896,7 +1901,7 @@ async fn kcl_test_angled_line_of_x_length_270() { extrusion = extrude(sketch001, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1918,7 +1923,7 @@ async fn kcl_test_angled_line_of_y_length_0() { example = extrude(exampleSketch, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1940,7 +1945,7 @@ async fn kcl_test_angled_line_of_y_length_180() { example = extrude(exampleSketch, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1962,7 +1967,7 @@ async fn kcl_test_angled_line_of_y_length_negative_180() { example = extrude(exampleSketch, length = 10) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -1979,7 +1984,7 @@ async fn kcl_test_error_inside_fn_also_has_source_range_of_call_site() { someFunction('INVALID') "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -2000,7 +2005,7 @@ async fn kcl_test_error_inside_fn_also_has_source_range_of_call_site_recursive() someFunction('INVALID') "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), @@ -2024,7 +2029,7 @@ async fn kcl_test_error_no_auth_websocket() { ) "#; - let result = execute_and_snapshot_no_auth(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot_no_auth(code, None).await; assert!(result.is_err()); assert!(result .err() @@ -2050,9 +2055,7 @@ sketch000 = startSketchOn(XY) |> line(end = [0, innerDiameter / 2]) "#; - let ctx = kcl_lib::ExecutorContext::new_with_default_client(Default::default()) - .await - .unwrap(); + let ctx = kcl_lib::ExecutorContext::new_with_default_client().await.unwrap(); let mut exec_state = kcl_lib::ExecState::new(&ctx); let program = kcl_lib::Program::parse_no_errs(code).unwrap(); ctx.run(&program, &mut exec_state).await.unwrap(); @@ -2075,9 +2078,7 @@ async fn kcl_test_ensure_nothing_left_in_batch_multi_file() { // Change the current working directory to the test directory. std::env::set_current_dir(path.parent().unwrap()).unwrap(); - let ctx = kcl_lib::ExecutorContext::new_with_default_client(Default::default()) - .await - .unwrap(); + let ctx = kcl_lib::ExecutorContext::new_with_default_client().await.unwrap(); let mut exec_state = kcl_lib::ExecState::new(&ctx); let program = kcl_lib::Program::parse_no_errs(&code).unwrap(); ctx.run(&program, &mut exec_state).await.unwrap(); @@ -2095,7 +2096,7 @@ async fn kcl_test_better_type_names() { |> circle(center = [-95.51, -74.7], radius = 262.23) |> appearance(metalness = 0.9) "#; - let result = execute_and_snapshot(code, UnitLength::Mm, None).await; + let result = execute_and_snapshot(code, None).await; let err = match result.err() { Some(x) => match x { @@ -2114,7 +2115,7 @@ async fn kcl_test_exporting_step_file() { // This tests export like how we do it in cli and kcl.py. let code = kcl_input!("helix_defaults_negative_extrude"); - let (_, _, files) = execute_and_export_step(code, UnitLength::Mm, None).await.unwrap(); + let (_, _, files) = execute_and_export_step(code, None).await.unwrap(); for file in files { expectorate::assert_contents( format!("e2e/executor/outputs/helix_defaults_negative_extrude_{}", file.name), diff --git a/rust/kcl-lib/e2e/modify/main.rs b/rust/kcl-lib/e2e/modify/main.rs deleted file mode 100644 index c443437f4..000000000 --- a/rust/kcl-lib/e2e/modify/main.rs +++ /dev/null @@ -1,232 +0,0 @@ -use anyhow::Result; -use kcl_lib::{ - exec::{KclValue, PlaneType}, - modify_ast_for_sketch, ExecState, ExecutorContext, ModuleId, Program, SourceRange, -}; -use kittycad_modeling_cmds::{each_cmd as mcmd, length_unit::LengthUnit, shared::Point3d, ModelingCmd}; -use pretty_assertions::assert_eq; - -/// Setup the engine and parse code for an ast. -async fn setup(code: &str, name: &str) -> Result<(ExecutorContext, Program, ModuleId, uuid::Uuid)> { - let program = Program::parse_no_errs(code)?; - let ctx = kcl_lib::ExecutorContext::new_with_default_client(Default::default()).await?; - let mut exec_state = ExecState::new(&ctx); - let result = ctx.run(&program, &mut exec_state).await?; - let outcome = exec_state.to_wasm_outcome(result.0).await; - - // We need to get the sketch ID. - let KclValue::Sketch { value: sketch } = outcome.variables.get(name).unwrap() else { - anyhow::bail!("part001 not found in: {:?}", outcome.variables); - }; - let sketch_id = sketch.id; - - let plane_id = uuid::Uuid::new_v4(); - ctx.engine - .send_modeling_cmd( - plane_id, - SourceRange::default(), - &ModelingCmd::from(mcmd::MakePlane { - clobber: false, - origin: Point3d::default(), - size: LengthUnit(60.0), - x_axis: Point3d { x: 1.0, y: 0.0, z: 0.0 }, - y_axis: Point3d { x: 0.0, y: 1.0, z: 0.0 }, - hide: Some(true), - }), - ) - .await?; - - // Enter sketch mode. - // We can't get control points without being in sketch mode. - // You can however get path info without sketch mode. - ctx.engine - .send_modeling_cmd( - uuid::Uuid::new_v4(), - SourceRange::default(), - &ModelingCmd::from(mcmd::EnableSketchMode { - animated: false, - ortho: true, - entity_id: plane_id, - planar_normal: Some(Point3d { x: 0.0, y: 0.0, z: 1.0 }), - adjust_camera: false, - }), - ) - .await?; - - Ok((ctx, program, ModuleId::default(), sketch_id)) -} - -#[tokio::test(flavor = "multi_thread")] -async fn kcl_test_modify_sketch_part001() { - let name = "part001"; - let code = format!( - r#"{} = startSketchOn(XY) - |> startProfileAt([8.41, 5.78], %) - |> line(end = [7.37, -11]) - |> line(end = [-8.69, -3.75]) - |> line(end = [-5, 4.25]) -"#, - name - ); - - let (ctx, program, module_id, sketch_id) = setup(&code, name).await.unwrap(); - let mut new_program = program.clone(); - let new_code = modify_ast_for_sketch(&ctx.engine, &mut new_program, module_id, name, PlaneType::XY, sketch_id) - .await - .unwrap(); - - // Make sure the code is the same. - assert_eq!(code, new_code); - // Make sure the program is the same. - assert_eq!(new_program, program); -} - -#[tokio::test(flavor = "multi_thread")] -async fn kcl_test_modify_sketch_part002() { - let name = "part002"; - let code = format!( - r#"{} = startSketchOn(XY) - |> startProfileAt([8.41, 5.78], %) - |> line(end = [7.42, -8.62]) - |> line(end = [-6.38, -3.51]) - |> line(end = [-3.77, 3.56]) -"#, - name - ); - - let (ctx, program, module_id, sketch_id) = setup(&code, name).await.unwrap(); - let mut new_program = program.clone(); - let new_code = modify_ast_for_sketch(&ctx.engine, &mut new_program, module_id, name, PlaneType::XY, sketch_id) - .await - .unwrap(); - - // Make sure the code is the same. - assert_eq!(code, new_code); - // Make sure the program is the same. - assert_eq!(new_program, program); -} - -#[tokio::test(flavor = "multi_thread")] -#[ignore] // until KittyCAD/engine#1434 is fixed. -async fn kcl_test_modify_close_sketch() { - let name = "part002"; - let code = format!( - r#"{} = startSketchOn(XY) - |> startProfileAt([7.91, 3.89], %) - |> line(end = [7.42, -8.62]) - |> line(end = [-6.38, -3.51]) - |> line(end = [-3.77, 3.56]) - |> close() -"#, - name - ); - - let (ctx, program, module_id, sketch_id) = setup(&code, name).await.unwrap(); - let mut new_program = program.clone(); - let new_code = modify_ast_for_sketch(&ctx.engine, &mut new_program, module_id, name, PlaneType::XY, sketch_id) - .await - .unwrap(); - - // Make sure the code is the same. - assert_eq!(code, new_code); - // Make sure the program is the same. - assert_eq!(new_program, program); -} - -#[tokio::test(flavor = "multi_thread")] -async fn kcl_test_modify_line_to_close_sketch() { - let name = "part002"; - let code = format!( - r#"const {} = startSketchOn(XY) - |> startProfileAt([7.91, 3.89], %) - |> line(end = [7.42, -8.62]) - |> line(end = [-6.38, -3.51]) - |> line(end = [-3.77, 3.56]) - |> line(endAbsolute = [7.91, 3.89]) -"#, - name - ); - - let (ctx, program, module_id, sketch_id) = setup(&code, name).await.unwrap(); - let mut new_program = program.clone(); - let new_code = modify_ast_for_sketch(&ctx.engine, &mut new_program, module_id, name, PlaneType::XY, sketch_id) - .await - .unwrap(); - - // Make sure the code is the same. - assert_eq!( - new_code, - format!( - r#"{} = startSketchOn(XY) - |> startProfileAt([7.91, 3.89], %) - |> line(end = [7.42, -8.62]) - |> line(end = [-6.38, -3.51]) - |> line(end = [-3.77, 3.56]) - |> close() -"#, - name - ) - ); -} - -#[tokio::test(flavor = "multi_thread")] -async fn kcl_test_modify_with_constraint() { - let name = "part002"; - let code = format!( - r#"const thing = 12 -const {} = startSketchOn(XY) - |> startProfileAt([7.91, 3.89], %) - |> line(end = [7.42, -8.62]) - |> line(end = [-6.38, -3.51]) - |> line(end = [-3.77, 3.56]) - |> line(endAbsolute = [thing, 3.89]) -"#, - name - ); - - let (ctx, program, module_id, sketch_id) = setup(&code, name).await.unwrap(); - let mut new_program = program.clone(); - let result = modify_ast_for_sketch(&ctx.engine, &mut new_program, module_id, name, PlaneType::XY, sketch_id).await; - - assert!(result.is_err()); - assert_eq!( - result.unwrap_err().message(), - "Sketch part002 is constrained `partial` and cannot be modified", - ); -} - -#[tokio::test(flavor = "multi_thread")] -async fn kcl_test_modify_line_should_close_sketch() { - let name = "part003"; - let code = format!( - r#"const {} = startSketchOn(XY) - |> startProfileAt([13.69, 3.8], %) - |> line(end = [4.23, -11.79]) - |> line(end = [-10.7, -1.16]) - |> line(end = [-3.72, 8.69]) - |> line(end = [10.19, 4.26]) -"#, - name - ); - - let (ctx, program, module_id, sketch_id) = setup(&code, name).await.unwrap(); - let mut new_program = program.clone(); - let new_code = modify_ast_for_sketch(&ctx.engine, &mut new_program, module_id, name, PlaneType::XY, sketch_id) - .await - .unwrap(); - - // Make sure the code is the same. - assert_eq!( - new_code, - format!( - r#"{} = startSketchOn(XY) - |> startProfileAt([13.69, 3.8], %) - |> line(end = [4.23, -11.79]) - |> line(end = [-10.7, -1.16]) - |> line(end = [-3.72, 8.69]) - |> close() -"#, - name - ) - ); -} diff --git a/rust/kcl-lib/src/coredump/mod.rs b/rust/kcl-lib/src/coredump/mod.rs index 3057e3e40..df217a651 100644 --- a/rust/kcl-lib/src/coredump/mod.rs +++ b/rust/kcl-lib/src/coredump/mod.rs @@ -53,7 +53,7 @@ pub trait CoreDump: Clone { .meta() .create_debug_uploads(vec![kittycad::types::multipart::Attachment { name: "".to_string(), - filename: Some(format!(r#"modeling-app/coredump-{coredump_id}-screenshot.png"#)), + filepath: Some(format!(r#"modeling-app/coredump-{coredump_id}-screenshot.png"#).into()), content_type: Some("image/png".to_string()), data, }]) @@ -101,7 +101,7 @@ pub trait CoreDump: Clone { .meta() .create_debug_uploads(vec![kittycad::types::multipart::Attachment { name: "".to_string(), - filename: Some(format!(r#"modeling-app/coredump-{}.json"#, coredump_id)), + filepath: Some(format!(r#"modeling-app/coredump-{}.json"#, coredump_id).into()), content_type: Some("application/json".to_string()), data, }]) diff --git a/rust/kcl-lib/src/docs/gen_std_tests.rs b/rust/kcl-lib/src/docs/gen_std_tests.rs index ce930b392..3702bd70a 100644 --- a/rust/kcl-lib/src/docs/gen_std_tests.rs +++ b/rust/kcl-lib/src/docs/gen_std_tests.rs @@ -339,9 +339,9 @@ fn generate_index(combined: &IndexMap>, kcl_lib: &[Doc } functions.entry(d.mod_name()).or_default().push(match d { - DocData::Fn(f) => (f.name.clone(), d.file_name()), - DocData::Const(c) => (c.name.clone(), d.file_name()), - DocData::Ty(t) => (t.name.clone(), d.file_name()), + DocData::Fn(f) => (f.preferred_name.clone(), d.file_name()), + DocData::Const(c) => (c.preferred_name.clone(), d.file_name()), + DocData::Ty(t) => (t.preferred_name.clone(), d.file_name()), }); if let DocData::Const(c) = d { @@ -1172,7 +1172,7 @@ fn find_examples(text: &str, filename: &str) -> Vec<(String, String)> { async fn run_example(text: &str) -> Result<()> { let program = crate::Program::parse_no_errs(text)?; - let ctx = ExecutorContext::new_with_default_client(crate::UnitLength::Mm).await?; + let ctx = ExecutorContext::new_with_default_client().await?; let mut exec_state = crate::execution::ExecState::new(&ctx); ctx.run(&program, &mut exec_state).await?; Ok(()) diff --git a/rust/kcl-lib/src/docs/kcl_doc.rs b/rust/kcl-lib/src/docs/kcl_doc.rs index 0c72cdd7d..6fb2f1517 100644 --- a/rust/kcl-lib/src/docs/kcl_doc.rs +++ b/rust/kcl-lib/src/docs/kcl_doc.rs @@ -9,7 +9,7 @@ use tower_lsp::lsp_types::{ use crate::{ execution::annotations, parsing::{ - ast::types::{Annotation, Node, PrimitiveType, Type, VariableKind}, + ast::types::{Annotation, ImportSelector, Node, PrimitiveType, Type, VariableKind}, token::NumericSuffix, }, ModuleId, @@ -17,7 +17,7 @@ use crate::{ pub fn walk_prelude() -> Vec { let mut visitor = CollectionVisitor::default(); - visitor.visit_module("prelude").unwrap(); + visitor.visit_module("prelude", "").unwrap(); visitor.result } @@ -29,7 +29,7 @@ struct CollectionVisitor { } impl CollectionVisitor { - fn visit_module(&mut self, name: &str) -> Result<(), String> { + fn visit_module(&mut self, name: &str, preferred_prefix: &str) -> Result<(), String> { let old_name = std::mem::replace(&mut self.name, name.to_owned()); let source = crate::modules::read_std(name).unwrap(); let parsed = crate::parsing::parse_str(source, ModuleId::from_usize(self.id)) @@ -40,14 +40,16 @@ impl CollectionVisitor { for n in &parsed.body { match n { crate::parsing::ast::types::BodyItem::ImportStatement(import) if !import.visibility.is_default() => { - // Only supports glob imports for now. - assert!(matches!( - import.selector, - crate::parsing::ast::types::ImportSelector::Glob(..) - )); match &import.path { crate::parsing::ast::types::ImportPath::Std { path } => { - self.visit_module(&path[1])?; + match import.selector { + ImportSelector::Glob(..) => self.visit_module(&path[1], "")?, + ImportSelector::None { .. } => { + self.visit_module(&path[1], &format!("{}::", import.module_name().unwrap()))? + } + // Only supports glob or whole-module imports for now. + _ => unimplemented!(), + } } p => return Err(format!("Unexpected import: `{p}`")), } @@ -59,8 +61,8 @@ impl CollectionVisitor { format!("std::{}::", self.name) }; let mut dd = match var.kind { - VariableKind::Fn => DocData::Fn(FnData::from_ast(var, qual_name)), - VariableKind::Const => DocData::Const(ConstData::from_ast(var, qual_name)), + VariableKind::Fn => DocData::Fn(FnData::from_ast(var, qual_name, preferred_prefix)), + VariableKind::Const => DocData::Const(ConstData::from_ast(var, qual_name, preferred_prefix)), }; dd.with_meta(&var.outer_attrs); @@ -77,7 +79,7 @@ impl CollectionVisitor { } else { format!("std::{}::", self.name) }; - let mut dd = DocData::Ty(TyData::from_ast(ty, qual_name)); + let mut dd = DocData::Ty(TyData::from_ast(ty, qual_name, preferred_prefix)); dd.with_meta(&ty.outer_attrs); for a in &ty.outer_attrs { @@ -200,6 +202,8 @@ impl DocData { #[derive(Debug, Clone)] pub struct ConstData { pub name: String, + /// How the const is indexed, etc. + pub preferred_name: String, /// The fully qualified name. pub qual_name: String, pub value: Option, @@ -216,7 +220,11 @@ pub struct ConstData { } impl ConstData { - fn from_ast(var: &crate::parsing::ast::types::VariableDeclaration, mut qual_name: String) -> Self { + fn from_ast( + var: &crate::parsing::ast::types::VariableDeclaration, + mut qual_name: String, + preferred_prefix: &str, + ) -> Self { assert_eq!(var.kind, crate::parsing::ast::types::VariableKind::Const); let (value, ty) = match &var.declaration.init { @@ -240,6 +248,7 @@ impl ConstData { let name = var.declaration.id.name.clone(); qual_name.push_str(&name); ConstData { + preferred_name: format!("{preferred_prefix}{name}"), name, qual_name, value, @@ -272,7 +281,7 @@ impl ConstData { detail.push_str(ty); } CompletionItem { - label: self.name.clone(), + label: self.preferred_name.clone(), label_details: Some(CompletionItemLabelDetails { detail: self.value.clone(), description: None, @@ -306,6 +315,8 @@ impl ConstData { pub struct FnData { /// The name of the function. pub name: String, + /// How the function is indexed, etc. + pub preferred_name: String, /// The fully qualified name. pub qual_name: String, /// The args of the function. @@ -326,7 +337,11 @@ pub struct FnData { } impl FnData { - fn from_ast(var: &crate::parsing::ast::types::VariableDeclaration, mut qual_name: String) -> Self { + fn from_ast( + var: &crate::parsing::ast::types::VariableDeclaration, + mut qual_name: String, + preferred_prefix: &str, + ) -> Self { assert_eq!(var.kind, crate::parsing::ast::types::VariableKind::Fn); let crate::parsing::ast::types::Expr::FunctionExpression(expr) = &var.declaration.init else { unreachable!(); @@ -345,6 +360,7 @@ impl FnData { } FnData { + preferred_name: format!("{preferred_prefix}{name}"), name, qual_name, args: expr.params.iter().map(ArgData::from_ast).collect(), @@ -443,7 +459,7 @@ impl FnData { } // We end with ${} so you can jump to the end of the snippet. // After the last argument. - format!("{}({})${{}}", self.name, args.join(", ")) + format!("{}({})${{}}", self.preferred_name, args.join(", ")) } fn to_signature_help(&self) -> SignatureHelp { @@ -452,7 +468,7 @@ impl FnData { SignatureHelp { signatures: vec![SignatureInformation { - label: self.name.clone(), + label: self.preferred_name.clone(), documentation: self.short_docs().map(|s| { Documentation::MarkupContent(MarkupContent { kind: MarkupKind::Markdown, @@ -580,6 +596,8 @@ impl ArgKind { pub struct TyData { /// The name of the function. pub name: String, + /// How the type is indexed, etc. + pub preferred_name: String, /// The fully qualified name. pub qual_name: String, pub properties: Properties, @@ -597,7 +615,11 @@ pub struct TyData { } impl TyData { - fn from_ast(ty: &crate::parsing::ast::types::TypeDeclaration, mut qual_name: String) -> Self { + fn from_ast( + ty: &crate::parsing::ast::types::TypeDeclaration, + mut qual_name: String, + preferred_prefix: &str, + ) -> Self { let name = ty.name.name.clone(); qual_name.push_str(&name); let mut referenced_types = HashSet::new(); @@ -606,6 +628,7 @@ impl TyData { } TyData { + preferred_name: format!("{preferred_prefix}{name}"), name, qual_name, properties: Properties { @@ -641,7 +664,7 @@ impl TyData { fn to_completion_item(&self) -> CompletionItem { CompletionItem { - label: self.name.clone(), + label: self.preferred_name.clone(), label_details: self.alias.as_ref().map(|t| CompletionItemLabelDetails { detail: Some(format!("type {} = {t}", self.name)), description: None, @@ -658,7 +681,7 @@ impl TyData { preselect: None, sort_text: None, filter_text: None, - insert_text: Some(self.name.clone()), + insert_text: Some(self.preferred_name.clone()), insert_text_format: Some(InsertTextFormat::SNIPPET), insert_text_mode: None, text_edit: None, @@ -987,20 +1010,17 @@ mod test { let std = walk_prelude(); for d in std { for (i, eg) in d.examples().enumerate() { - let result = - match crate::test_server::execute_and_snapshot(eg, crate::settings::types::UnitLength::Mm, None) - .await - { - Err(crate::errors::ExecError::Kcl(e)) => { - return Err(miette::Report::new(crate::errors::Report { - error: e.error, - filename: format!("{}{i}", d.name()), - kcl_source: eg.to_string(), - })); - } - Err(other_err) => panic!("{}", other_err), - Ok(img) => img, - }; + let result = match crate::test_server::execute_and_snapshot(eg, None).await { + Err(crate::errors::ExecError::Kcl(e)) => { + return Err(miette::Report::new(crate::errors::Report { + error: e.error, + filename: format!("{}{i}", d.name()), + kcl_source: eg.to_string(), + })); + } + Err(other_err) => panic!("{}", other_err), + Ok(img) => img, + }; twenty_twenty::assert_image( format!("tests/outputs/serial_test_example_{}{i}.png", d.example_name()), &result, diff --git a/rust/kcl-lib/src/docs/mod.rs b/rust/kcl-lib/src/docs/mod.rs index 458176629..4c3558c66 100644 --- a/rust/kcl-lib/src/docs/mod.rs +++ b/rust/kcl-lib/src/docs/mod.rs @@ -1141,7 +1141,7 @@ mod tests { let snippet = scale_fn.to_autocomplete_snippet().unwrap(); assert_eq!( snippet, - r#"scale(${0:%}, scale = [${1:3.14}, ${2:3.14}, ${3:3.14}])${}"# + r#"scale(${0:%}, x = ${1:3.14}, y = ${2:3.14}, z = ${3:3.14})${}"# ); } @@ -1152,7 +1152,7 @@ mod tests { let snippet = translate_fn.to_autocomplete_snippet().unwrap(); assert_eq!( snippet, - r#"translate(${0:%}, translate = [${1:3.14}, ${2:3.14}, ${3:3.14}])${}"# + r#"translate(${0:%}, x = ${1:3.14}, y = ${2:3.14}, z = ${3:3.14})${}"# ); } diff --git a/rust/kcl-lib/src/engine/conn_wasm.rs b/rust/kcl-lib/src/engine/conn_wasm.rs index ee023ce24..2242f8f83 100644 --- a/rust/kcl-lib/src/engine/conn_wasm.rs +++ b/rust/kcl-lib/src/engine/conn_wasm.rs @@ -121,6 +121,13 @@ impl EngineConnection { } })?; + if value.is_null() || value.is_undefined() { + return Err(KclError::Engine(KclErrorDetails { + message: "Received null or undefined response from engine".into(), + source_ranges: vec![source_range], + })); + } + // Convert JsValue to a Uint8Array let data = js_sys::Uint8Array::from(value); diff --git a/rust/kcl-lib/src/engine/mod.rs b/rust/kcl-lib/src/engine/mod.rs index fd20fcd80..6cef90c8e 100644 --- a/rust/kcl-lib/src/engine/mod.rs +++ b/rust/kcl-lib/src/engine/mod.rs @@ -170,12 +170,16 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static { self.clear_queues().await; self.batch_modeling_cmd( - uuid::Uuid::new_v4(), + id_generator.next_uuid(), source_range, &ModelingCmd::SceneClearAll(mcmd::SceneClearAll::default()), ) .await?; + // Reset to the default units. Modules assume the engine starts in the + // default state. + self.set_units(Default::default(), source_range, id_generator).await?; + // Flush the batch queue, so clear is run right away. // Otherwise the hooks below won't work. self.flush_batch(false, source_range).await?; @@ -195,9 +199,10 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static { &self, visible: bool, source_range: SourceRange, + id_generator: &mut IdGenerator, ) -> Result<(), crate::errors::KclError> { self.batch_modeling_cmd( - uuid::Uuid::new_v4(), + id_generator.next_uuid(), source_range, &ModelingCmd::from(mcmd::EdgeLinesVisible { hidden: !visible }), ) @@ -231,10 +236,11 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static { &self, units: crate::UnitLength, source_range: SourceRange, + id_generator: &mut IdGenerator, ) -> Result<(), crate::errors::KclError> { // Before we even start executing the program, set the units. self.batch_modeling_cmd( - uuid::Uuid::new_v4(), + id_generator.next_uuid(), source_range, &ModelingCmd::from(mcmd::SetSceneUnits { unit: units.into() }), ) @@ -248,15 +254,15 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static { &self, settings: &crate::ExecutorSettings, source_range: SourceRange, + id_generator: &mut IdGenerator, ) -> Result<(), crate::errors::KclError> { // Set the edge visibility. - self.set_edge_visibility(settings.highlight_edges, source_range).await?; - - // Change the units. - self.set_units(settings.units, source_range).await?; + self.set_edge_visibility(settings.highlight_edges, source_range, id_generator) + .await?; // Send the command to show the grid. - self.modify_grid(!settings.show_grid, source_range).await?; + self.modify_grid(!settings.show_grid, source_range, id_generator) + .await?; // We do not have commands for changing ssao on the fly. @@ -502,6 +508,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static { y_axis: Point3d, color: Option, source_range: SourceRange, + id_generator: &mut IdGenerator, ) -> Result { // Create new default planes. let default_size = 100.0; @@ -524,7 +531,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static { if let Some(color) = color { // Set the color. self.batch_modeling_cmd( - uuid::Uuid::new_v4(), + id_generator.next_uuid(), source_range, &ModelingCmd::from(mcmd::PlaneSetColor { color, plane_id }), ) @@ -615,7 +622,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static { for (name, plane_id, x_axis, y_axis, color) in plane_settings { planes.insert( name, - self.make_default_plane(plane_id, x_axis, y_axis, color, source_range) + self.make_default_plane(plane_id, x_axis, y_axis, color, source_range, id_generator) .await?, ); } @@ -701,10 +708,15 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static { })) } - async fn modify_grid(&self, hidden: bool, source_range: SourceRange) -> Result<(), KclError> { + async fn modify_grid( + &self, + hidden: bool, + source_range: SourceRange, + id_generator: &mut IdGenerator, + ) -> Result<(), KclError> { // Hide/show the grid. self.batch_modeling_cmd( - uuid::Uuid::new_v4(), + id_generator.next_uuid(), source_range, &ModelingCmd::from(mcmd::ObjectVisible { hidden, @@ -715,7 +727,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static { // Hide/show the grid scale text. self.batch_modeling_cmd( - uuid::Uuid::new_v4(), + id_generator.next_uuid(), source_range, &ModelingCmd::from(mcmd::ObjectVisible { hidden, diff --git a/rust/kcl-lib/src/execution/cache.rs b/rust/kcl-lib/src/execution/cache.rs index dcbecfc1c..b9c69a69f 100644 --- a/rust/kcl-lib/src/execution/cache.rs +++ b/rust/kcl-lib/src/execution/cache.rs @@ -6,7 +6,7 @@ use itertools::{EitherOrBoth, Itertools}; use tokio::sync::RwLock; use crate::{ - execution::{annotations, memory::Stack, EnvironmentRef, ExecState, ExecutorSettings}, + execution::{annotations, memory::Stack, state::ModuleInfoMap, EnvironmentRef, ExecState, ExecutorSettings}, parsing::ast::types::{Annotation, Node, Program}, walk::Node as WalkNode, }; @@ -15,7 +15,7 @@ lazy_static::lazy_static! { /// A static mutable lock for updating the last successful execution state for the cache. static ref OLD_AST: Arc>> = Default::default(); // The last successful run's memory. Not cleared after an unssuccessful run. - static ref PREV_MEMORY: Arc>> = Default::default(); + static ref PREV_MEMORY: Arc>> = Default::default(); } /// Read the old ast memory from the lock. @@ -29,12 +29,12 @@ pub(super) async fn write_old_ast(old_state: OldAstState) { *old_ast = Some(old_state); } -pub(crate) async fn read_old_memory() -> Option { +pub(crate) async fn read_old_memory() -> Option<(Stack, ModuleInfoMap)> { let old_mem = PREV_MEMORY.read().await; old_mem.clone() } -pub(super) async fn write_old_memory(mem: Stack) { +pub(super) async fn write_old_memory(mem: (Stack, ModuleInfoMap)) { let mut old_mem = PREV_MEMORY.write().await; *old_mem = Some(mem); } @@ -97,15 +97,6 @@ pub(super) async fn get_changed_program(old: CacheInformation<'_>, new: CacheInf // If the settings are different we might need to bust the cache. // We specifically do this before checking if they are the exact same. if old.settings != new.settings { - // If the units are different we need to re-execute the whole thing. - if old.settings.units != new.settings.units { - return CacheResult::ReExecute { - clear_scene: true, - reapply_settings: true, - program: new.ast.clone(), - }; - } - // If anything else is different we may not need to re-execute, but rather just // run the settings again. reapply_settings = true; @@ -424,50 +415,6 @@ shell(firstSketch, faces = ['end'], thickness = 0.25)"#; assert_eq!(result, CacheResult::NoAction(false)); } - // Changing the units with the exact same file should bust the cache. - #[tokio::test(flavor = "multi_thread")] - async fn test_get_changed_program_same_code_but_different_units() { - let new = r#"// Remove the end face for the extrusion. -firstSketch = startSketchOn('XY') - |> startProfileAt([-12, 12], %) - |> line(end = [24, 0]) - |> line(end = [0, -24]) - |> line(end = [-24, 0]) - |> close() - |> extrude(length = 6) - -// Remove the end face for the extrusion. -shell(firstSketch, faces = ['end'], thickness = 0.25)"#; - - let ExecTestResults { - program, mut exec_ctxt, .. - } = parse_execute(new).await.unwrap(); - - // Change the settings to cm. - exec_ctxt.settings.units = crate::UnitLength::Cm; - - let result = get_changed_program( - CacheInformation { - ast: &program.ast, - settings: &Default::default(), - }, - CacheInformation { - ast: &program.ast, - settings: &exec_ctxt.settings, - }, - ) - .await; - - assert_eq!( - result, - CacheResult::ReExecute { - clear_scene: true, - reapply_settings: true, - program: program.ast - } - ); - } - // Changing the grid settings with the exact same file should NOT bust the cache. #[tokio::test(flavor = "multi_thread")] async fn test_get_changed_program_same_code_but_different_grid_setting() { @@ -615,4 +562,42 @@ startSketchOn('XY') } ); } + + // Removing the units settings using an annotation, when it was non-default + // units, with the exact same file should bust the cache. + #[tokio::test(flavor = "multi_thread")] + async fn test_get_changed_program_same_code_but_removed_unit_setting_using_annotation() { + let old_code = r#"@settings(defaultLengthUnit = in) +startSketchOn('XY') +"#; + let new_code = r#" +startSketchOn('XY') +"#; + + let ExecTestResults { program, exec_ctxt, .. } = parse_execute(old_code).await.unwrap(); + + let mut new_program = crate::Program::parse_no_errs(new_code).unwrap(); + new_program.compute_digest(); + + let result = get_changed_program( + CacheInformation { + ast: &program.ast, + settings: &exec_ctxt.settings, + }, + CacheInformation { + ast: &new_program.ast, + settings: &exec_ctxt.settings, + }, + ) + .await; + + assert_eq!( + result, + CacheResult::ReExecute { + clear_scene: true, + reapply_settings: true, + program: new_program.ast + } + ); + } } diff --git a/rust/kcl-lib/src/execution/exec_ast.rs b/rust/kcl-lib/src/execution/exec_ast.rs index 1c0d400d4..15bc878e2 100644 --- a/rust/kcl-lib/src/execution/exec_ast.rs +++ b/rust/kcl-lib/src/execution/exec_ast.rs @@ -64,7 +64,11 @@ impl ExecutorContext { let new_units = exec_state.length_unit(); if !self.engine.execution_kind().await.is_isolated() { self.engine - .set_units(new_units.into(), annotation.as_source_range()) + .set_units( + new_units.into(), + annotation.as_source_range(), + exec_state.id_generator(), + ) .await?; } } else { @@ -106,12 +110,7 @@ impl ExecutorContext { let old_units = exec_state.length_unit(); let original_execution = self.engine.replace_execution_kind(exec_kind).await; - let mut local_state = ModuleState::new( - &self.settings, - path.std_path(), - exec_state.stack().memory.clone(), - Some(module_id), - ); + let mut local_state = ModuleState::new(path.std_path(), exec_state.stack().memory.clone(), Some(module_id)); if !preserve_mem { std::mem::swap(&mut exec_state.mod_local, &mut local_state); } @@ -143,7 +142,9 @@ impl ExecutorContext { // command and we'd need to flush the batch again. // This avoids that. if !exec_kind.is_isolated() && new_units != old_units && *path != ModulePath::Main { - self.engine.set_units(old_units.into(), Default::default()).await?; + self.engine + .set_units(old_units.into(), Default::default(), exec_state.id_generator()) + .await?; } self.engine.replace_execution_kind(original_execution).await; diff --git a/rust/kcl-lib/src/execution/id_generator.rs b/rust/kcl-lib/src/execution/id_generator.rs index e1cd37e0a..4fb1d0890 100644 --- a/rust/kcl-lib/src/execution/id_generator.rs +++ b/rust/kcl-lib/src/execution/id_generator.rs @@ -2,7 +2,7 @@ use crate::execution::ModuleId; -const NAMESPACE_KCL: uuid::Uuid = uuid::uuid!("efcd6508-4ce6-4a09-8317-e6a6994a3cd7"); +const NAMESPACE_KCL: uuid::Uuid = uuid::uuid!("8bda3118-75eb-58c7-a866-bef1dcb495e7"); /// A generator for ArtifactIds that can be stable across executions. #[derive(Debug, Clone, Default, PartialEq)] diff --git a/rust/kcl-lib/src/execution/mod.rs b/rust/kcl-lib/src/execution/mod.rs index 6c1de6748..d6b66cf59 100644 --- a/rust/kcl-lib/src/execution/mod.rs +++ b/rust/kcl-lib/src/execution/mod.rs @@ -40,7 +40,6 @@ use crate::{ fs::FileManager, modules::{ModuleId, ModulePath}, parsing::ast::types::{Expr, ImportPath, NodeRef}, - settings::types::UnitLength, source_range::SourceRange, std::StdLib, CompilationError, ExecError, ExecutionKind, KclErrorWithOutputs, @@ -266,8 +265,6 @@ pub struct ExecutorContext { #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] #[ts(export)] pub struct ExecutorSettings { - /// The project-default unit to use in modeling dimensions. - pub units: UnitLength, /// Highlight edges of 3D objects? pub highlight_edges: bool, /// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled. @@ -288,7 +285,6 @@ pub struct ExecutorSettings { impl Default for ExecutorSettings { fn default() -> Self { Self { - units: Default::default(), highlight_edges: true, enable_ssao: false, show_grid: false, @@ -302,7 +298,6 @@ impl Default for ExecutorSettings { impl From for ExecutorSettings { fn from(config: crate::settings::types::Configuration) -> Self { Self { - units: config.settings.modeling.base_unit, highlight_edges: config.settings.modeling.highlight_edges.into(), enable_ssao: config.settings.modeling.enable_ssao.into(), show_grid: config.settings.modeling.show_scale_grid, @@ -316,7 +311,6 @@ impl From for ExecutorSettings { impl From for ExecutorSettings { fn from(config: crate::settings::types::project::ProjectConfiguration) -> Self { Self { - units: config.settings.modeling.base_unit, highlight_edges: config.settings.modeling.highlight_edges.into(), enable_ssao: config.settings.modeling.enable_ssao.into(), show_grid: Default::default(), @@ -330,7 +324,6 @@ impl From for ExecutorSet impl From for ExecutorSettings { fn from(modeling: crate::settings::types::ModelingSettings) -> Self { Self { - units: modeling.base_unit, highlight_edges: modeling.highlight_edges.into(), enable_ssao: modeling.enable_ssao.into(), show_grid: modeling.show_scale_grid, @@ -344,7 +337,6 @@ impl From for ExecutorSettings { impl From for ExecutorSettings { fn from(modeling: crate::settings::types::project::ProjectModelingSettings) -> Self { Self { - units: modeling.base_unit, highlight_edges: modeling.highlight_edges.into(), enable_ssao: modeling.enable_ssao.into(), show_grid: Default::default(), @@ -492,26 +484,17 @@ impl ExecutorContext { /// This allows for passing in `ZOO_API_TOKEN` and `ZOO_HOST` as environment /// variables. #[cfg(not(target_arch = "wasm32"))] - pub async fn new_with_default_client(units: UnitLength) -> Result { + pub async fn new_with_default_client() -> Result { // Create the client. - let ctx = Self::new_with_client( - ExecutorSettings { - units, - ..Default::default() - }, - None, - None, - ) - .await?; + let ctx = Self::new_with_client(Default::default(), None, None).await?; Ok(ctx) } /// For executing unit tests. #[cfg(not(target_arch = "wasm32"))] - pub async fn new_for_unit_test(units: UnitLength, engine_addr: Option) -> Result { + pub async fn new_for_unit_test(engine_addr: Option) -> Result { let ctx = ExecutorContext::new_with_client( ExecutorSettings { - units, highlight_edges: true, enable_ssao: false, show_grid: false, @@ -545,6 +528,18 @@ impl ExecutorContext { .await } + pub async fn bust_cache_and_reset_scene(&self) -> Result { + cache::bust_cache().await; + + // Execute an empty program to clear and reset the scene. + // We specifically want to be returned the objects after the scene is reset. + // Like the default planes so it is easier to just execute an empty program + // after the cache is busted. + let outcome = self.run_with_caching(crate::Program::empty()).await?; + + Ok(outcome) + } + async fn prepare_mem(&self, exec_state: &mut ExecState) -> Result<(), KclErrorWithOutputs> { self.eval_prelude(exec_state, SourceRange::synthetic()) .await @@ -563,7 +558,10 @@ impl ExecutorContext { let mut exec_state = ExecState::new(self); if use_prev_memory { match cache::read_old_memory().await { - Some(mem) => *exec_state.mut_stack() = mem, + Some(mem) => { + *exec_state.mut_stack() = mem.0; + exec_state.global.module_infos = mem.1; + } None => self.prepare_mem(&mut exec_state).await?, } } else { @@ -581,10 +579,11 @@ impl ExecutorContext { // memory, not to the exec_state which is not cached for mock execution. let mut mem = exec_state.stack().clone(); + let module_infos = exec_state.global.module_infos.clone(); let outcome = exec_state.to_mock_wasm_outcome(result.0).await; mem.squash_env(result.0); - cache::write_old_memory(mem).await; + cache::write_old_memory((mem, module_infos)).await; Ok(outcome) } @@ -618,7 +617,7 @@ impl ExecutorContext { if reapply_settings && self .engine - .reapply_settings(&self.settings, Default::default()) + .reapply_settings(&self.settings, Default::default(), old_state.id_generator()) .await .is_err() { @@ -636,7 +635,7 @@ impl ExecutorContext { CacheResult::NoAction(true) => { if self .engine - .reapply_settings(&self.settings, Default::default()) + .reapply_settings(&self.settings, Default::default(), old_state.id_generator()) .await .is_ok() { @@ -737,7 +736,7 @@ impl ExecutorContext { // Re-apply the settings, in case the cache was busted. self.engine - .reapply_settings(&self.settings, Default::default()) + .reapply_settings(&self.settings, Default::default(), exec_state.id_generator()) .await .map_err(KclErrorWithOutputs::no_outputs)?; @@ -774,7 +773,7 @@ impl ExecutorContext { if !self.is_mock() { let mut mem = exec_state.stack().deep_clone(); mem.restore_env(env_ref); - cache::write_old_memory(mem).await; + cache::write_old_memory((mem, exec_state.global.module_infos.clone())).await; } let session_data = self.engine.get_session_data().await; Ok((env_ref, session_data)) @@ -862,11 +861,6 @@ impl ExecutorContext { Ok(()) } - /// Update the units for the executor. - pub(crate) fn update_units(&mut self, units: UnitLength) { - self.settings.units = units; - } - /// Get a snapshot of the current scene. pub async fn prepare_snapshot(&self) -> std::result::Result { // Zoom to fit. @@ -1008,11 +1002,7 @@ mod tests { use pretty_assertions::assert_eq; use super::*; - use crate::{ - errors::{KclErrorDetails, Severity}, - execution::memory::Stack, - ModuleId, - }; + use crate::{errors::KclErrorDetails, execution::memory::Stack, ModuleId}; /// Convenience function to get a JSON value from memory and unwrap. #[track_caller] @@ -1615,34 +1605,6 @@ const inInches = 2.0 * inch()"#; ); } - #[tokio::test(flavor = "multi_thread")] - async fn test_unit_suggest() { - let src = "foo = 42"; - let program = crate::Program::parse_no_errs(src).unwrap(); - let ctx = ExecutorContext { - engine: Arc::new(Box::new( - crate::engine::conn_mock::EngineConnection::new().await.unwrap(), - )), - fs: Arc::new(crate::fs::FileManager::new()), - stdlib: Arc::new(crate::std::StdLib::new()), - settings: ExecutorSettings { - units: UnitLength::Ft, - ..Default::default() - }, - context_type: ContextType::Mock, - }; - let mut exec_state = ExecState::new(&ctx); - ctx.run(&program, &mut exec_state).await.unwrap(); - let errs = exec_state.errors(); - assert_eq!(errs.len(), 1, "{errs:?}"); - let warn = &errs[0]; - assert_eq!(warn.severity, Severity::Warning); - assert_eq!( - warn.apply_suggestion(src).unwrap(), - "@settings(defaultLengthUnit = ft)\nfoo = 42" - ) - } - #[tokio::test(flavor = "multi_thread")] async fn test_zero_param_fn() { let ast = r#"const sigmaAllow = 35000 // psi @@ -1971,9 +1933,7 @@ let w = f() + f() ) "#; - let ctx = crate::test_server::new_context(UnitLength::Mm, true, None) - .await - .unwrap(); + let ctx = crate::test_server::new_context(true, None).await.unwrap(); let old_program = crate::Program::parse_no_errs(code).unwrap(); // Execute the program. @@ -2026,9 +1986,7 @@ let w = f() + f() ) "#; - let mut ctx = crate::test_server::new_context(UnitLength::Mm, true, None) - .await - .unwrap(); + let mut ctx = crate::test_server::new_context(true, None).await.unwrap(); let old_program = crate::Program::parse_no_errs(code).unwrap(); // Execute the program. @@ -2060,11 +2018,13 @@ let w = f() + f() // Ensure the settings are as expected. assert_eq!(settings_state, ctx.settings); + + ctx.close().await; } #[tokio::test(flavor = "multi_thread")] async fn mock_after_not_mock() { - let ctx = ExecutorContext::new_with_default_client(UnitLength::Mm).await.unwrap(); + let ctx = ExecutorContext::new_with_default_client().await.unwrap(); let program = crate::Program::parse_no_errs("x = 2").unwrap(); let result = ctx.run_with_caching(program).await.unwrap(); assert_eq!(result.variables.get("x").unwrap().as_f64().unwrap(), 2.0); @@ -2073,6 +2033,9 @@ let w = f() + f() let program2 = crate::Program::parse_no_errs("z = x + 1").unwrap(); let result = ctx2.run_mock(program2, true).await.unwrap(); assert_eq!(result.variables.get("z").unwrap().as_f64().unwrap(), 3.0); + + ctx.close().await; + ctx2.close().await; } #[tokio::test(flavor = "multi_thread")] diff --git a/rust/kcl-lib/src/execution/state.rs b/rust/kcl-lib/src/execution/state.rs index 803ea150c..f23e65efe 100644 --- a/rust/kcl-lib/src/execution/state.rs +++ b/rust/kcl-lib/src/execution/state.rs @@ -30,6 +30,8 @@ pub struct ExecState { pub(super) exec_context: Option, } +pub type ModuleInfoMap = IndexMap; + #[derive(Debug, Clone)] pub(super) struct GlobalState { /// Map from source file absolute path to module ID. @@ -37,7 +39,7 @@ pub(super) struct GlobalState { /// Map from module ID to source file. pub id_to_source: IndexMap, /// Map from module ID to module info. - pub module_infos: IndexMap, + pub module_infos: ModuleInfoMap, /// Output map of UUIDs to artifacts. pub artifacts: IndexMap, /// Output commands to allow building the artifact graph by the caller. @@ -80,7 +82,7 @@ impl ExecState { pub fn new(exec_context: &super::ExecutorContext) -> Self { ExecState { global: GlobalState::new(&exec_context.settings), - mod_local: ModuleState::new(&exec_context.settings, None, ProgramMemory::new(), Default::default()), + mod_local: ModuleState::new(None, ProgramMemory::new(), Default::default()), exec_context: Some(exec_context.clone()), } } @@ -90,7 +92,7 @@ impl ExecState { *self = ExecState { global, - mod_local: ModuleState::new(&exec_context.settings, None, ProgramMemory::new(), Default::default()), + mod_local: ModuleState::new(None, ProgramMemory::new(), Default::default()), exec_context: Some(exec_context.clone()), }; } @@ -291,12 +293,7 @@ impl GlobalState { } impl ModuleState { - pub(super) fn new( - exec_settings: &ExecutorSettings, - std_path: Option, - memory: Arc, - module_id: Option, - ) -> Self { + pub(super) fn new(std_path: Option, memory: Arc, module_id: Option) -> Self { ModuleState { id_generator: IdGenerator::new(module_id), stack: memory.new_stack(), @@ -305,14 +302,14 @@ impl ModuleState { explicit_length_units: false, std_path, settings: MetaSettings { - default_length_units: exec_settings.units.into(), + default_length_units: Default::default(), default_angle_units: Default::default(), }, } } } -#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] +#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq, ts_rs::TS, JsonSchema)] #[ts(export)] #[serde(rename_all = "camelCase")] pub struct MetaSettings { diff --git a/rust/kcl-lib/src/lib.rs b/rust/kcl-lib/src/lib.rs index 1ffd64486..d03015a8e 100644 --- a/rust/kcl-lib/src/lib.rs +++ b/rust/kcl-lib/src/lib.rs @@ -93,11 +93,11 @@ pub use lsp::{ kcl::{Backend as KclLspBackend, Server as KclLspServerSubCommand}, }; pub use modules::ModuleId; -pub use parsing::ast::{modify::modify_ast_for_sketch, types::FormatOptions}; +pub use parsing::ast::types::FormatOptions; pub use settings::types::{project::ProjectConfiguration, Configuration, UnitLength}; pub use source_range::SourceRange; #[cfg(not(target_arch = "wasm32"))] -pub use unparser::recast_dir; +pub use unparser::{recast_dir, walk_dir}; // Rather than make executor public and make lots of it pub(crate), just re-export into a new module. // Ideally we wouldn't export these things at all, they should only be used for testing. @@ -195,6 +195,10 @@ impl Program { }) } + pub fn is_empty_or_only_settings(&self) -> bool { + self.ast.is_empty_or_only_settings() + } + pub fn lint_all(&self) -> Result, anyhow::Error> { self.ast.lint_all() } @@ -211,6 +215,14 @@ impl Program { pub fn recast_with_options(&self, options: &FormatOptions) -> String { self.ast.recast(options, 0) } + + /// Create an empty program. + pub fn empty() -> Self { + Self { + ast: parsing::ast::types::Node::no_src(parsing::ast::types::Program::default()), + original_file_contents: String::new(), + } + } } #[inline] diff --git a/rust/kcl-lib/src/lsp/kcl/mod.rs b/rust/kcl-lib/src/lsp/kcl/mod.rs index c42c1fb66..465abce1b 100644 --- a/rust/kcl-lib/src/lsp/kcl/mod.rs +++ b/rust/kcl-lib/src/lsp/kcl/mod.rs @@ -786,7 +786,7 @@ impl Backend { vec![kittycad::types::multipart::Attachment { // Clean the URI part. name: "attachment".to_string(), - filename: Some("attachment.zip".to_string()), + filepath: Some("attachment.zip".into()), content_type: Some("application/x-zip".to_string()), data: self.create_zip().await?, }], @@ -812,56 +812,6 @@ impl Backend { Ok(()) } - pub async fn update_units( - &self, - params: custom_notifications::UpdateUnitsParams, - ) -> RpcResult> { - { - let mut ctx = self.executor_ctx.write().await; - // Borrow the executor context mutably. - let Some(ref mut executor_ctx) = *ctx else { - self.client - .log_message(MessageType::ERROR, "no executor context set to update units for") - .await; - return Ok(None); - }; - - self.client - .log_message(MessageType::INFO, format!("update units: {:?}", params)) - .await; - - if executor_ctx.settings.units == params.units - && !self.has_diagnostics(params.text_document.uri.as_ref()).await - { - // Return early the units are the same. - return Ok(None); - } - - // Set the engine units. - executor_ctx.update_units(params.units); - } - // Lock is dropped here since nested. - // This is IMPORTANT. - - let new_params = TextDocumentItem { - uri: params.text_document.uri.clone(), - text: std::mem::take(&mut params.text.to_string()), - version: Default::default(), - language_id: Default::default(), - }; - - // Force re-execution. - self.inner_on_change(new_params, true).await; - - // Check if we have diagnostics. - // If we do we return early, since we failed in some way. - if self.has_diagnostics(params.text_document.uri.as_ref()).await { - return Ok(None); - } - - Ok(Some(custom_notifications::UpdateUnitsResponse {})) - } - pub async fn update_can_execute( &self, params: custom_notifications::UpdateCanExecuteParams, @@ -1635,7 +1585,7 @@ fn position_to_char_index(position: Position, code: &str) -> usize { async fn with_cached_var(name: &str, f: impl Fn(&KclValue) -> T) -> Option { let mem = cache::read_old_memory().await?; - let value = mem.get(name, SourceRange::default()).ok()?; + let value = mem.0.get(name, SourceRange::default()).ok()?; Some(f(value)) } diff --git a/rust/kcl-lib/src/lsp/test_util.rs b/rust/kcl-lib/src/lsp/test_util.rs index e757a3a28..3b8aa5011 100644 --- a/rust/kcl-lib/src/lsp/test_util.rs +++ b/rust/kcl-lib/src/lsp/test_util.rs @@ -42,7 +42,6 @@ pub async fn kcl_lsp_server(execute: bool) -> Result { can_execute: Arc::new(tokio::sync::RwLock::new(can_execute)), is_initialized: Default::default(), }) - .custom_method("kcl/updateUnits", crate::lsp::kcl::Backend::update_units) .custom_method("kcl/updateCanExecute", crate::lsp::kcl::Backend::update_can_execute) .finish(); diff --git a/rust/kcl-lib/src/lsp/tests.rs b/rust/kcl-lib/src/lsp/tests.rs index d44c4402b..bd871da38 100644 --- a/rust/kcl-lib/src/lsp/tests.rs +++ b/rust/kcl-lib/src/lsp/tests.rs @@ -1016,6 +1016,8 @@ startSketchOn(XY) } _ => unreachable!(), } + + server.executor_ctx().await.clone().unwrap().close().await; } #[tokio::test(flavor = "multi_thread")] @@ -2318,78 +2320,8 @@ async fn kcl_test_kcl_lsp_on_change_update_memory() { }], }) .await; -} -#[tokio::test(flavor = "multi_thread", worker_threads = 10)] -async fn kcl_test_kcl_lsp_update_units() { - let server = kcl_lsp_server(true).await.unwrap(); - - let same_text = r#"fn cube = (pos, scale) => { - sg = startSketchOn(XY) - |> startProfileAt(pos, %) - |> line(end = [0, scale]) - |> line(end = [scale, 0]) - |> line(end = [0, -scale]) - - return sg -} -part001 = cube([0,0], 20) - |> close() - |> extrude(length = 20)"# - .to_string(); - - // Send open file. - server - .did_open(tower_lsp::lsp_types::DidOpenTextDocumentParams { - text_document: tower_lsp::lsp_types::TextDocumentItem { - uri: "file:///test.kcl".try_into().unwrap(), - language_id: "kcl".to_string(), - version: 1, - text: same_text.clone(), - }, - }) - .await; - - // Get the tokens. - let tokens = server.token_map.get("file:///test.kcl").unwrap().clone(); - assert_eq!(tokens.as_slice().len(), 123); - - // Get the ast. - let ast = server.ast_map.get("file:///test.kcl").unwrap().clone(); - assert_eq!(ast.ast.body.len(), 2); - - // Send change file. - server - .did_change(tower_lsp::lsp_types::DidChangeTextDocumentParams { - text_document: tower_lsp::lsp_types::VersionedTextDocumentIdentifier { - uri: "file:///test.kcl".try_into().unwrap(), - version: 1, - }, - content_changes: vec![tower_lsp::lsp_types::TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: same_text.clone(), - }], - }) - .await; - - let units = server.executor_ctx.read().await.clone().unwrap().settings.units; - assert_eq!(units, crate::settings::types::UnitLength::Mm); - - // Update the units. - server - .update_units(crate::lsp::kcl::custom_notifications::UpdateUnitsParams { - text_document: crate::lsp::kcl::custom_notifications::TextDocumentIdentifier { - uri: "file:///test.kcl".try_into().unwrap(), - }, - units: crate::settings::types::UnitLength::M, - text: same_text.clone(), - }) - .await - .unwrap(); - - let units = server.executor_ctx().await.clone().unwrap().settings.units; - assert_eq!(units, crate::settings::types::UnitLength::M); + server.executor_ctx().await.clone().unwrap().close().await; } #[tokio::test(flavor = "multi_thread")] @@ -2506,6 +2438,8 @@ async fn kcl_test_kcl_lsp_diagnostics_on_execution_error() { // Get the diagnostics. assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 0); + + server.executor_ctx().await.clone().unwrap().close().await; } #[tokio::test(flavor = "multi_thread")] @@ -2556,6 +2490,8 @@ async fn kcl_test_kcl_lsp_full_to_empty_file_updates_ast_and_memory() { // Get the ast. let ast = server.ast_map.get("file:///test.kcl").unwrap().clone(); assert_eq!(ast.ast, default_hashed); + + server.executor_ctx().await.clone().unwrap().close().await; } #[tokio::test(flavor = "multi_thread")] @@ -2642,6 +2578,8 @@ async fn kcl_test_kcl_lsp_code_unchanged_but_has_diagnostics_reexecute() { // Assure we have no diagnostics. assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 0); + + server.executor_ctx().await.clone().unwrap().close().await; } #[tokio::test(flavor = "multi_thread")] @@ -2717,141 +2655,8 @@ async fn kcl_test_kcl_lsp_code_and_ast_unchanged_but_has_diagnostics_reexecute() // Assure we have no diagnostics. assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 0); -} -#[tokio::test(flavor = "multi_thread")] -async fn kcl_test_kcl_lsp_code_and_ast_units_unchanged_but_has_diagnostics_reexecute_on_unit_change() { - let server = kcl_lsp_server(true).await.unwrap(); - - let code = r#"part001 = startSketchOn(XY) - |> startProfileAt([-10, -10], %) - |> line(end = [20, 0]) - |> line(end = [0, 20]) - |> line(end = [-20, 0]) - |> close() - |> extrude(length = 3.14)"#; - - // Send open file. - server - .did_open(tower_lsp::lsp_types::DidOpenTextDocumentParams { - text_document: tower_lsp::lsp_types::TextDocumentItem { - uri: "file:///test.kcl".try_into().unwrap(), - language_id: "kcl".to_string(), - version: 1, - text: code.to_string(), - }, - }) - .await; - - // Get the ast. - let ast = server.ast_map.get("file:///test.kcl").unwrap().clone(); - assert!(ast.ast != Node::::default()); - - // Assure we have no diagnostics. - assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 0); - - // Add some fake diagnostics. - server.diagnostics_map.insert( - "file:///test.kcl".to_string(), - vec![tower_lsp::lsp_types::Diagnostic { - range: tower_lsp::lsp_types::Range { - start: tower_lsp::lsp_types::Position { line: 0, character: 0 }, - end: tower_lsp::lsp_types::Position { line: 0, character: 0 }, - }, - message: "fake diagnostic".to_string(), - severity: Some(tower_lsp::lsp_types::DiagnosticSeverity::ERROR), - code: None, - source: None, - related_information: None, - tags: None, - data: None, - code_description: None, - }], - ); - // Assure we have one diagnostics. - assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 1); - - let units = server.executor_ctx().await.clone().unwrap().settings.units; - assert_eq!(units, crate::settings::types::UnitLength::Mm); - - // Update the units to the _same_ units. - server - .update_units(crate::lsp::kcl::custom_notifications::UpdateUnitsParams { - text_document: crate::lsp::kcl::custom_notifications::TextDocumentIdentifier { - uri: "file:///test.kcl".try_into().unwrap(), - }, - units: crate::settings::types::UnitLength::Mm, - text: code.to_string(), - }) - .await - .unwrap(); - - let units = server.executor_ctx().await.clone().unwrap().settings.units; - assert_eq!(units, crate::settings::types::UnitLength::Mm); - - // Get the ast. - let ast = server.ast_map.get("file:///test.kcl").unwrap().clone(); - assert!(ast.ast != Node::::default()); - - // Assure we have no diagnostics. - assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 0); -} - -#[tokio::test(flavor = "multi_thread")] -async fn kcl_test_kcl_lsp_code_and_ast_units_unchanged_but_has_memory_reexecute_on_unit_change() { - let server = kcl_lsp_server(true).await.unwrap(); - - let code = r#"part001 = startSketchOn(XY) - |> startProfileAt([-10, -10], %) - |> line(end = [20, 0]) - |> line(end = [0, 20]) - |> line(end = [-20, 0]) - |> close() - |> extrude(length = 3.14)"#; - - // Send open file. - server - .did_open(tower_lsp::lsp_types::DidOpenTextDocumentParams { - text_document: tower_lsp::lsp_types::TextDocumentItem { - uri: "file:///test.kcl".try_into().unwrap(), - language_id: "kcl".to_string(), - version: 1, - text: code.to_string(), - }, - }) - .await; - - // Get the ast. - let ast = server.ast_map.get("file:///test.kcl").unwrap().clone(); - assert!(ast.ast != Node::::default()); - - // Assure we have no diagnostics. - assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 0); - - let units = server.executor_ctx().await.clone().unwrap().settings.units; - assert_eq!(units, crate::settings::types::UnitLength::Mm); - - // Update the units to the _same_ units. - server - .update_units(crate::lsp::kcl::custom_notifications::UpdateUnitsParams { - text_document: crate::lsp::kcl::custom_notifications::TextDocumentIdentifier { - uri: "file:///test.kcl".try_into().unwrap(), - }, - units: crate::settings::types::UnitLength::Mm, - text: code.to_string(), - }) - .await - .unwrap(); - - let units = server.executor_ctx().await.clone().unwrap().settings.units; - assert_eq!(units, crate::settings::types::UnitLength::Mm); - - // Get the ast. - let ast = server.ast_map.get("file:///test.kcl").unwrap().clone(); - assert!(ast.ast != Node::::default()); - - // Assure we have no diagnostics. - assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 0); + server.executor_ctx().await.clone().unwrap().close().await; } #[tokio::test(flavor = "multi_thread")] @@ -2885,23 +2690,6 @@ async fn kcl_test_kcl_lsp_cant_execute_set() { // Assure we have no diagnostics. assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 0); - // Update the units to the _same_ units. - let units = server.executor_ctx().await.clone().unwrap().settings.units; - assert_eq!(units, crate::settings::types::UnitLength::Mm); - server - .update_units(crate::lsp::kcl::custom_notifications::UpdateUnitsParams { - text_document: crate::lsp::kcl::custom_notifications::TextDocumentIdentifier { - uri: "file:///test.kcl".try_into().unwrap(), - }, - units: crate::settings::types::UnitLength::Mm, - text: code.to_string(), - }) - .await - .unwrap(); - - let units = server.executor_ctx().await.clone().unwrap().settings.units; - assert_eq!(units, crate::settings::types::UnitLength::Mm); - // Get the ast. let ast = server.ast_map.get("file:///test.kcl").unwrap().clone(); assert!(ast.ast != Node::::default()); @@ -2918,23 +2706,6 @@ async fn kcl_test_kcl_lsp_cant_execute_set() { .unwrap(); assert_eq!(server.can_execute().await, false); - // Update the units to the _same_ units. - let units = server.executor_ctx().await.clone().unwrap().settings.units; - assert_eq!(units, crate::settings::types::UnitLength::Mm); - server - .update_units(crate::lsp::kcl::custom_notifications::UpdateUnitsParams { - text_document: crate::lsp::kcl::custom_notifications::TextDocumentIdentifier { - uri: "file:///test.kcl".try_into().unwrap(), - }, - units: crate::settings::types::UnitLength::Mm, - text: code.to_string(), - }) - .await - .unwrap(); - - let units = server.executor_ctx().await.clone().unwrap().settings.units; - assert_eq!(units, crate::settings::types::UnitLength::Mm); - let mut default_hashed = Node::::default(); default_hashed.compute_digest(); @@ -2952,29 +2723,14 @@ async fn kcl_test_kcl_lsp_cant_execute_set() { .unwrap(); assert_eq!(server.can_execute().await, true); - // Update the units to the _same_ units. - let units = server.executor_ctx.read().await.clone().unwrap().settings.units; - assert_eq!(units, crate::settings::types::UnitLength::Mm); - server - .update_units(crate::lsp::kcl::custom_notifications::UpdateUnitsParams { - text_document: crate::lsp::kcl::custom_notifications::TextDocumentIdentifier { - uri: "file:///test.kcl".try_into().unwrap(), - }, - units: crate::settings::types::UnitLength::Mm, - text: code.to_string(), - }) - .await - .unwrap(); - - let units = server.executor_ctx.read().await.clone().unwrap().settings.units; - assert_eq!(units, crate::settings::types::UnitLength::Mm); - // Get the ast. let ast = server.ast_map.get("file:///test.kcl").unwrap().clone(); assert!(ast.ast != Node::::default()); // Assure we have no diagnostics. assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 0); + + server.executor_ctx().await.clone().unwrap().close().await; } #[tokio::test(flavor = "multi_thread")] @@ -3243,6 +2999,8 @@ part001 = startSketchOn(XY) // Check the diagnostics. assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 2); + + server.executor_ctx().await.clone().unwrap().close().await; } #[tokio::test(flavor = "multi_thread")] @@ -3310,6 +3068,8 @@ NEW_LINT = 1"# // Check the diagnostics. assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 2); + + server.executor_ctx().await.clone().unwrap().close().await; } #[tokio::test(flavor = "multi_thread")] @@ -3377,6 +3137,8 @@ NEW_LINT = 1"# // Check the diagnostics. assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 1); + + server.executor_ctx().await.clone().unwrap().close().await; } #[tokio::test(flavor = "multi_thread")] @@ -3460,6 +3222,8 @@ NEW_LINT = 1"# // Check the diagnostics. assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 1); + + server.executor_ctx().await.clone().unwrap().close().await; } #[tokio::test(flavor = "multi_thread")] @@ -3551,6 +3315,8 @@ part001 = startSketchOn(XY) // Check the diagnostics. assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 2); + + server.executor_ctx().await.clone().unwrap().close().await; } #[tokio::test(flavor = "multi_thread")] @@ -3649,4 +3415,6 @@ async fn kcl_test_kcl_lsp_multi_file_error() { } else { panic!("Expected diagnostics"); } + + server.executor_ctx().await.clone().unwrap().close().await; } diff --git a/rust/kcl-lib/src/modules.rs b/rust/kcl-lib/src/modules.rs index 9e6c248eb..9107f7714 100644 --- a/rust/kcl-lib/src/modules.rs +++ b/rust/kcl-lib/src/modules.rs @@ -88,6 +88,7 @@ pub(crate) fn read_std(mod_name: &str) -> Option<&'static str> { "prelude" => Some(include_str!("../std/prelude.kcl")), "math" => Some(include_str!("../std/math.kcl")), "sketch" => Some(include_str!("../std/sketch.kcl")), + "turns" => Some(include_str!("../std/turns.kcl")), _ => None, } } diff --git a/rust/kcl-lib/src/parsing/ast/mod.rs b/rust/kcl-lib/src/parsing/ast/mod.rs index 5f58caf9c..ed23328e3 100644 --- a/rust/kcl-lib/src/parsing/ast/mod.rs +++ b/rust/kcl-lib/src/parsing/ast/mod.rs @@ -1,5 +1,4 @@ pub(crate) mod digest; -pub mod modify; pub mod types; use crate::{ diff --git a/rust/kcl-lib/src/parsing/ast/modify.rs b/rust/kcl-lib/src/parsing/ast/modify.rs deleted file mode 100644 index a55da9180..000000000 --- a/rust/kcl-lib/src/parsing/ast/modify.rs +++ /dev/null @@ -1,285 +0,0 @@ -use std::sync::Arc; - -use kcmc::{ - each_cmd as mcmd, ok_response::OkModelingCmdResponse, shared::PathCommand, websocket::OkWebSocketResponseData, - ModelingCmd, -}; -use kittycad_modeling_cmds as kcmc; - -use super::types::{CallExpressionKw, Identifier, LabeledArg, LiteralValue}; -use crate::{ - engine::EngineManager, - errors::{KclError, KclErrorDetails}, - execution::Point2d, - parsing::ast::types::{ - ArrayExpression, CallExpression, ConstraintLevel, FormatOptions, Literal, Node, PipeExpression, - PipeSubstitution, VariableDeclarator, - }, - source_range::SourceRange, - ModuleId, Program, -}; - -type Point3d = kcmc::shared::Point3d; - -#[derive(Debug)] -/// The control point data for a curve or line. -struct ControlPointData { - /// The control points for the curve or line. - points: Vec, - /// The command that created this curve or line. - _command: PathCommand, - /// The id of the curve or line. - _id: uuid::Uuid, -} - -const EPSILON: f64 = 0.015625; // or 2^-6 - -/// Update the AST to reflect the new state of the program after something like -/// a move or a new line. -pub async fn modify_ast_for_sketch( - engine: &Arc>, - program: &mut Program, - module_id: ModuleId, - // The name of the sketch. - sketch_name: &str, - // The type of plane the sketch is on. `XY` or `XZ`, etc - plane: crate::execution::PlaneType, - // The ID of the parent sketch. - sketch_id: uuid::Uuid, -) -> Result { - // First we need to check if this sketch is constrained (even partially). - // If it is, we cannot modify it. - - // Get the information about the sketch. - if let Some(ast_sketch) = program.ast.get_variable(sketch_name) { - let constraint_level = match ast_sketch { - super::types::Definition::Variable(var) => var.get_constraint_level(), - super::types::Definition::Import(import) => import.get_constraint_level(), - super::types::Definition::Type(_) => ConstraintLevel::Ignore { - source_ranges: Vec::new(), - }, - }; - match &constraint_level { - ConstraintLevel::None { source_ranges: _ } => {} - ConstraintLevel::Ignore { source_ranges: _ } => {} - ConstraintLevel::Partial { - source_ranges: _, - levels, - } => { - return Err(KclError::Engine(KclErrorDetails { - message: format!( - "Sketch {} is constrained `{}` and cannot be modified", - sketch_name, constraint_level - ), - source_ranges: levels.get_all_partial_or_full_source_ranges(), - })); - } - ConstraintLevel::Full { source_ranges } => { - return Err(KclError::Engine(KclErrorDetails { - message: format!( - "Sketch {} is constrained `{}` and cannot be modified", - sketch_name, constraint_level - ), - source_ranges: source_ranges.clone(), - })); - } - } - } - - // Let's start by getting the path info. - - // Let's get the path info. - let resp = engine - .send_modeling_cmd( - uuid::Uuid::new_v4(), - SourceRange::default(), - &ModelingCmd::PathGetInfo(mcmd::PathGetInfo { path_id: sketch_id }), - ) - .await?; - - let OkWebSocketResponseData::Modeling { - modeling_response: OkModelingCmdResponse::PathGetInfo(path_info), - } = &resp - else { - return Err(KclError::Engine(KclErrorDetails { - message: format!("Get path info response was not as expected: {:?}", resp), - source_ranges: vec![SourceRange::default()], - })); - }; - - // Now let's get the control points for all the segments. - // TODO: We should probably await all these at once so we aren't going one by one. - // But I guess this is fine for now. - // We absolutely have to preserve the order of the control points. - let mut control_points = Vec::new(); - for segment in &path_info.segments { - if let Some(command_id) = &segment.command_id { - let cmd = ModelingCmd::from(mcmd::CurveGetControlPoints { - curve_id: (*command_id).into(), - }); - let h = engine.send_modeling_cmd(uuid::Uuid::new_v4(), SourceRange::default(), &cmd); - - let OkWebSocketResponseData::Modeling { - modeling_response: OkModelingCmdResponse::CurveGetControlPoints(data), - } = h.await? - else { - return Err(KclError::Engine(KclErrorDetails { - message: format!("Curve get control points response was not as expected: {:?}", resp), - source_ranges: vec![SourceRange::default()], - })); - }; - - control_points.push(ControlPointData { - points: data.control_points.clone(), - _command: segment.command, - _id: (*command_id).into(), - }); - } - } - - if control_points.is_empty() { - return Err(KclError::Engine(KclErrorDetails { - message: format!("No control points found for sketch {}", sketch_name), - source_ranges: vec![SourceRange::default()], - })); - } - - let first_control_points = control_points.first().ok_or_else(|| { - KclError::Engine(KclErrorDetails { - message: format!("No control points found for sketch {}", sketch_name), - source_ranges: vec![SourceRange::default()], - }) - })?; - - let mut additional_lines = Vec::new(); - let mut last_point = first_control_points.points[1]; - for control_point in control_points[1..].iter() { - additional_lines.push([ - (control_point.points[1].x - last_point.x), - (control_point.points[1].y - last_point.y), - ]); - last_point = Point3d { - x: control_point.points[1].x, - y: control_point.points[1].y, - z: control_point.points[1].z, - }; - } - - // Okay now let's recalculate the sketch from the control points. - let start_sketch_at_end = Point3d { - x: (first_control_points.points[1].x - first_control_points.points[0].x), - y: (first_control_points.points[1].y - first_control_points.points[0].y), - z: (first_control_points.points[1].z - first_control_points.points[0].z), - }; - let sketch = create_start_sketch_on( - sketch_name, - [first_control_points.points[0].x, first_control_points.points[0].y], - [start_sketch_at_end.x, start_sketch_at_end.y], - plane, - additional_lines, - )?; - - // Add the sketch back to the program. - program.ast.replace_variable(sketch_name, sketch); - - let recasted = program.ast.recast(&FormatOptions::default(), 0); - - // Re-parse the ast so we get the correct source ranges. - program.ast = crate::parsing::parse_str(&recasted, module_id).parse_errs_as_err()?; - - Ok(recasted) -} - -/// Create a pipe expression that starts a sketch at the given point and draws a line to the given point. -fn create_start_sketch_on( - name: &str, - start: [f64; 2], - end: [f64; 2], - plane: crate::execution::PlaneType, - additional_lines: Vec<[f64; 2]>, -) -> Result, KclError> { - let start_sketch_on = CallExpression::new("startSketchOn", vec![Literal::new(plane.to_string().into()).into()])?; - let start_profile_at = CallExpression::new( - "startProfileAt", - vec![ - ArrayExpression::new(vec![ - Literal::new(LiteralValue::from_f64_no_uom(round_before_recast(start[0]))).into(), - Literal::new(LiteralValue::from_f64_no_uom(round_before_recast(start[1]))).into(), - ]) - .into(), - PipeSubstitution::new().into(), - ], - )?; - - // Keep track of where we are so we can close the sketch if we need to. - let mut current_position = Point2d { - x: start[0], - y: start[1], - }; - current_position.x += end[0]; - current_position.y += end[1]; - - let expr = ArrayExpression::new(vec![ - Literal::new(LiteralValue::from_f64_no_uom(round_before_recast(end[0]))).into(), - Literal::new(LiteralValue::from_f64_no_uom(round_before_recast(end[1]))).into(), - ]) - .into(); - let initial_line = CallExpressionKw::new( - "line", - None, - vec![LabeledArg { - label: Node::no_src(super::types::Identifier { - name: "end".to_owned(), - digest: None, - }), - arg: expr, - }], - )?; - - let mut pipe_body = vec![start_sketch_on.into(), start_profile_at.into(), initial_line.into()]; - - for (index, line) in additional_lines.iter().enumerate() { - current_position.x += line[0]; - current_position.y += line[1]; - - // If we are on the last line, check if we have to close the sketch. - if index == additional_lines.len() - 1 { - let diff_x = (current_position.x - start[0]).abs(); - let diff_y = (current_position.y - start[1]).abs(); - // Compare the end of the last line to the start of the first line. - // This is a bit more lenient if you look at the value of epsilon. - if diff_x <= EPSILON && diff_y <= EPSILON { - // We have to close the sketch. - let close = CallExpressionKw::new("close", None, vec![])?; - pipe_body.push(close.into()); - break; - } - } - - // TODO: we should check if we should close the sketch. - let expr = ArrayExpression::new(vec![ - Literal::new(LiteralValue::from_f64_no_uom(round_before_recast(line[0]))).into(), - Literal::new(LiteralValue::from_f64_no_uom(round_before_recast(line[1]))).into(), - ]) - .into(); - let line = CallExpressionKw::new( - "line", - None, - vec![LabeledArg { - arg: expr, - label: Node::no_src(Identifier { - name: "end".to_owned(), - digest: None, - }), - }], - )?; - pipe_body.push(line.into()); - } - - Ok(VariableDeclarator::new(name, PipeExpression::new(pipe_body).into())) -} - -fn round_before_recast(num: f64) -> f64 { - // We use 2 decimal places. - (num * 100.0).round() / 100.0 -} diff --git a/rust/kcl-lib/src/parsing/ast/types/mod.rs b/rust/kcl-lib/src/parsing/ast/types/mod.rs index 43f736fb8..f7938a293 100644 --- a/rust/kcl-lib/src/parsing/ast/types/mod.rs +++ b/rust/kcl-lib/src/parsing/ast/types/mod.rs @@ -133,6 +133,13 @@ impl Node { }) } + fn reset_source(&mut self) { + self.start = 0; + self.end = 0; + self.module_id = ModuleId::default(); + self.comment_start = 0; + } + pub fn as_source_range(&self) -> SourceRange { SourceRange::new(self.start, self.end, self.module_id) } @@ -345,7 +352,10 @@ impl Node { let mut found = false; for node in &mut new_program.inner_attrs { if node.name() == Some(annotations::SETTINGS) { - *node = Node::no_src(Annotation::new_from_meta_settings(&settings)); + node.inner = Annotation::new_from_meta_settings(&settings); + // Previous source range no longer makes sense, but we want to + // preserve other things like comments. + node.reset_source(); found = true; break; } @@ -359,6 +369,26 @@ impl Node { Ok(new_program) } + + /// Returns true if the given KCL is empty or only contains settings that + /// would be auto-generated. + pub fn is_empty_or_only_settings(&self) -> bool { + if !self.body.is_empty() { + return false; + } + + if self.non_code_meta.start_nodes.iter().any(|node| node.is_comment()) { + return false; + } + + for item in &self.inner_attrs { + if item.name() != Some(annotations::SETTINGS) { + return false; + } + } + + true + } } impl Program { @@ -1609,19 +1639,21 @@ impl ImportStatement { return Some(alias.name.clone()); } - let mut parts = match &self.path { - ImportPath::Kcl { filename: s } | ImportPath::Foreign { path: s } => s.split('.'), - _ => return None, - }; - let path = parts.next()?; - let _ext = parts.next()?; - let rest = parts.next(); + match &self.path { + ImportPath::Kcl { filename: s } | ImportPath::Foreign { path: s } => { + let mut parts = s.split('.'); + let path = parts.next()?; + let _ext = parts.next()?; + let rest = parts.next(); - if rest.is_some() { - return None; + if rest.is_some() { + return None; + } + + path.rsplit(&['/', '\\']).next().map(str::to_owned) + } + ImportPath::Std { path } => path.last().cloned(), } - - path.rsplit(&['/', '\\']).next().map(str::to_owned) } } @@ -3552,6 +3584,37 @@ mod tests { use super::*; + #[track_caller] + fn parse(code: &str) -> Node { + crate::parsing::top_level_parse(code).unwrap() + } + + #[test] + fn test_empty_or_only_settings() { + // Empty is empty. + assert!(parse("").is_empty_or_only_settings()); + + // Whitespace is empty. + assert!(parse(" ").is_empty_or_only_settings()); + + // Settings are empty. + assert!(parse(r#"@settings(defaultLengthUnit = mm)"#).is_empty_or_only_settings()); + + // Only comments is not empty. + assert!(!parse("// comment").is_empty_or_only_settings()); + + // Any statement is not empty. + assert!(!parse("5").is_empty_or_only_settings()); + + // Any statement is not empty, even with settings. + let code = r#"@settings(defaultLengthUnit = mm) +5"#; + assert!(!parse(code).is_empty_or_only_settings()); + + // Non-settings attributes are not empty. + assert!(!parse("@foo").is_empty_or_only_settings()); + } + // We have this as a test so we can ensure it never panics with an unwrap in the server. #[test] fn test_variable_kind_to_completion() { @@ -4140,6 +4203,50 @@ startSketchOn(XY) r#"@settings(defaultLengthUnit = mm) startSketchOn(XY) +"# + ); + } + + #[tokio::test(flavor = "multi_thread")] + async fn test_change_meta_settings_preserves_comments() { + let code = r#"// Title + +// Set Units +@settings(defaultLengthUnit = in) + +// Between + +// Above Code +5 +"#; + let program = crate::parsing::top_level_parse(code).unwrap(); + + let new_program = program + .change_meta_settings(crate::execution::MetaSettings { + default_length_units: crate::execution::types::UnitLen::Cm, + ..Default::default() + }) + .unwrap(); + + let result = new_program.meta_settings().unwrap(); + assert!(result.is_some()); + let meta_settings = result.unwrap(); + + assert_eq!(meta_settings.default_length_units, crate::execution::types::UnitLen::Cm); + + let formatted = new_program.recast(&Default::default(), 0); + + assert_eq!( + formatted, + r#"// Title + +// Set Units +@settings(defaultLengthUnit = cm) + +// Between + +// Above Code +5 "# ); } diff --git a/rust/kcl-lib/src/parsing/mod.rs b/rust/kcl-lib/src/parsing/mod.rs index d0a81f5cf..b9c734232 100644 --- a/rust/kcl-lib/src/parsing/mod.rs +++ b/rust/kcl-lib/src/parsing/mod.rs @@ -152,7 +152,12 @@ const STR_DEPRECATIONS: [(&str, &str); 6] = [ ("-YZ", "-YZ"), ]; const FN_DEPRECATIONS: [(&str, &str); 3] = [("pi", "PI"), ("e", "E"), ("tau", "TAU")]; -const CONST_DEPRECATIONS: [(&str, &str); 0] = []; +const CONST_DEPRECATIONS: [(&str, &str); 4] = [ + ("ZERO", "turns::ZERO"), + ("QUARTER_TURN", "turns::QUARTER_TURN"), + ("HALF_TURN", "turns::HALF_TURN"), + ("THREE_QUARTER_TURN", "turns::THREE_QUARTER_TURN"), +]; #[derive(Clone, Copy)] pub enum DeprecationKind { diff --git a/rust/kcl-lib/src/parsing/parser.rs b/rust/kcl-lib/src/parsing/parser.rs index b638aa422..bce94ea66 100644 --- a/rust/kcl-lib/src/parsing/parser.rs +++ b/rust/kcl-lib/src/parsing/parser.rs @@ -1823,14 +1823,6 @@ fn import_stmt(i: &mut TokenSlice) -> PResult> { ) .into(), )); - } else if matches!(path, ImportPath::Std { .. }) && matches!(selector, ImportSelector::None { .. }) { - return Err(ErrMode::Cut( - CompilationError::fatal( - SourceRange::new(start, end, module_id), - "the standard library cannot be imported as a part", - ) - .into(), - )); } Ok(Node::boxed( @@ -2341,21 +2333,6 @@ fn nameable_identifier(i: &mut TokenSlice) -> PResult> { )); } - if let Some(suggestion) = super::deprecation(&result.name, DeprecationKind::Const) { - ParseContext::warn( - CompilationError::err( - result.as_source_range(), - format!("Using `{}` is deprecated, prefer using `{}`.", result.name, suggestion), - ) - .with_suggestion( - format!("Replace `{}` with `{}`", result.name, suggestion), - suggestion, - None, - Tag::Deprecated, - ), - ); - } - Ok(result) } @@ -2374,8 +2351,7 @@ fn name(i: &mut TokenSlice) -> PResult> { let name = idents.pop().unwrap(); let end = name.end; let module_id = name.module_id; - - Ok(Node::new( + let result = Node::new( Name { name, path: idents, @@ -2385,7 +2361,24 @@ fn name(i: &mut TokenSlice) -> PResult> { start, end, module_id, - )) + ); + + if let Some(suggestion) = super::deprecation(&result.to_string(), DeprecationKind::Const) { + ParseContext::warn( + CompilationError::err( + result.as_source_range(), + format!("Using `{result}` is deprecated, prefer using `{suggestion}`."), + ) + .with_suggestion( + format!("Replace `{result}` with `{suggestion}`"), + suggestion, + None, + Tag::Deprecated, + ), + ); + } + + Ok(result) } impl TryFrom for Node { diff --git a/rust/kcl-lib/src/simulation_tests.rs b/rust/kcl-lib/src/simulation_tests.rs index b5af5869b..30358e57f 100644 --- a/rust/kcl-lib/src/simulation_tests.rs +++ b/rust/kcl-lib/src/simulation_tests.rs @@ -114,6 +114,8 @@ async fn unparse_test(test: &Test) { let kcl_files = kcl_files.into_iter().filter(|f| f != &entry_point); let futures = kcl_files .into_iter() + .filter(|file| file.extension().is_some_and(|ext| ext == "kcl")) // We only care about kcl + // files here. .map(|file| { let snap_path = Path::new("..").join(&test.output_dir); tokio::spawn(async move { @@ -153,13 +155,9 @@ async fn execute_test(test: &Test, render_to_png: bool, export_step: bool) { let ast = crate::Program::parse_no_errs(&input).unwrap(); // Run the program. - let exec_res = crate::test_server::execute_and_snapshot_ast( - ast, - crate::settings::types::UnitLength::Mm, - Some(test.input_dir.join(&test.entry_point)), - export_step, - ) - .await; + let exec_res = + crate::test_server::execute_and_snapshot_ast(ast, Some(test.input_dir.join(&test.entry_point)), export_step) + .await; match exec_res { Ok((exec_state, env_ref, png, step)) => { let fail_path = test.output_dir.join("execution_error.snap"); diff --git a/rust/kcl-lib/src/simulation_tests/kcl_samples.rs b/rust/kcl-lib/src/simulation_tests/kcl_samples.rs index 27ae5d2db..2f3b590ca 100644 --- a/rust/kcl-lib/src/simulation_tests/kcl_samples.rs +++ b/rust/kcl-lib/src/simulation_tests/kcl_samples.rs @@ -1,6 +1,7 @@ //! Run all the KCL samples in the `kcl_samples` directory. use std::{ fs, + panic::{catch_unwind, AssertUnwindSafe}, path::{Path, PathBuf}, }; @@ -35,9 +36,35 @@ fn parse(dir_name: &str, dir_path: &Path) { #[kcl_directory_test_macro::test_all_dirs("../public/kcl-samples")] async fn unparse(dir_name: &str, dir_path: &Path) { - // TODO: turn this on when we fix the comments recasting. - // let t = test(dir_name, dir_path.join("main.kcl").to_str().unwrap().to_owned()); - // super::unparse_test(&t).await; + let t = test(dir_name, dir_path.join("main.kcl").to_str().unwrap().to_owned()); + unparse_test(&t).await; +} + +/// This is different from the rest of the simulation tests because we want to write +/// back out to the original file. +async fn unparse_test(test: &Test) { + let kcl_files = crate::unparser::walk_dir(&test.input_dir).await.unwrap(); + let futures = kcl_files + .into_iter() + .filter(|file| file.extension().is_some_and(|ext| ext == "kcl")) // We only care about kcl + // files here. + .map(|file| { + tokio::spawn(async move { + let contents = tokio::fs::read_to_string(&file).await.unwrap(); + let program = crate::Program::parse_no_errs(&contents).unwrap(); + let recast = program.recast_with_options(&Default::default()); + + catch_unwind(AssertUnwindSafe(|| { + expectorate::assert_contents(&file, &recast.to_string()); + })) + }) + }) + .collect::>(); + + // Join all futures and await their completion. + for future in futures { + future.await.unwrap().unwrap(); + } } #[kcl_directory_test_macro::test_all_dirs("../public/kcl-samples")] diff --git a/rust/kcl-lib/src/std/appearance.rs b/rust/kcl-lib/src/std/appearance.rs index c19620bf9..d92552a2f 100644 --- a/rust/kcl-lib/src/std/appearance.rs +++ b/rust/kcl-lib/src/std/appearance.rs @@ -66,7 +66,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result, roughness: Option, + exec_state: &mut ExecState, args: Args, ) -> Result, KclError> { for solid in &solids { @@ -306,7 +307,7 @@ async fn inner_appearance( }; args.batch_modeling_cmd( - uuid::Uuid::new_v4(), + exec_state.next_uuid(), ModelingCmd::from(mcmd::ObjectSetMaterialParamsPbr { object_id: solid.id, color, diff --git a/rust/kcl-lib/src/std/fillet.rs b/rust/kcl-lib/src/std/fillet.rs index 0aa08dfcc..7e67eb09d 100644 --- a/rust/kcl-lib/src/std/fillet.rs +++ b/rust/kcl-lib/src/std/fillet.rs @@ -8,6 +8,7 @@ use kittycad_modeling_cmds as kcmc; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use super::DEFAULT_TOLERANCE; use crate::{ errors::{KclError, KclErrorDetails}, execution::{ @@ -15,7 +16,6 @@ use crate::{ EdgeCut, ExecState, ExtrudeSurface, FilletSurface, GeoMeta, KclValue, Solid, TagIdentifier, }, parsing::ast::types::TagNode, - settings::types::UnitLength, std::Args, SourceRange, }; @@ -165,7 +165,7 @@ async fn inner_fillet( edge_id, object_id: solid.id, radius: LengthUnit(radius), - tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))), + tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)), cut_type: CutType::Fillet, // We make this a none so that we can remove it in the future. face_id: None, @@ -195,17 +195,6 @@ async fn inner_fillet( Ok(solid) } -pub(crate) fn default_tolerance(units: &UnitLength) -> f64 { - match units { - UnitLength::Mm => 0.0000001, - UnitLength::Cm => 0.0000001, - UnitLength::In => 0.0000001, - UnitLength::Ft => 0.0001, - UnitLength::Yd => 0.001, - UnitLength::M => 0.001, - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/rust/kcl-lib/src/std/loft.rs b/rust/kcl-lib/src/std/loft.rs index dbe6b47c5..bb8e48db9 100644 --- a/rust/kcl-lib/src/std/loft.rs +++ b/rust/kcl-lib/src/std/loft.rs @@ -7,11 +7,12 @@ use kcl_derive_docs::stdlib; use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd}; use kittycad_modeling_cmds as kcmc; +use super::DEFAULT_TOLERANCE; use crate::{ errors::{KclError, KclErrorDetails}, execution::{types::RuntimeType, ExecState, KclValue, Sketch, Solid}, parsing::ast::types::TagNode, - std::{extrude::do_post_extrude, fillet::default_tolerance, Args}, + std::{extrude::do_post_extrude, Args}, }; const DEFAULT_V_DEGREE: u32 = 2; @@ -159,7 +160,7 @@ async fn inner_loft( section_ids: sketches.iter().map(|group| group.id).collect(), base_curve_index, bez_approximate_rational, - tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))), + tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)), v_degree, }), ) diff --git a/rust/kcl-lib/src/std/mod.rs b/rust/kcl-lib/src/std/mod.rs index 8d9027f75..16078e511 100644 --- a/rust/kcl-lib/src/std/mod.rs +++ b/rust/kcl-lib/src/std/mod.rs @@ -278,6 +278,9 @@ pub enum FunctionKind { UserDefined, } +/// The default tolerance for modeling commands in [`kittycad_modeling_cmds::length_unit::LengthUnit`]. +const DEFAULT_TOLERANCE: f64 = 0.0000001; + /// Compute the length of the given leg. pub async fn leg_length(_exec_state: &mut ExecState, args: Args) -> Result { let (hypotenuse, leg, ty) = args.get_hypotenuse_leg()?; diff --git a/rust/kcl-lib/src/std/revolve.rs b/rust/kcl-lib/src/std/revolve.rs index 5a8b839d0..354210c85 100644 --- a/rust/kcl-lib/src/std/revolve.rs +++ b/rust/kcl-lib/src/std/revolve.rs @@ -5,11 +5,12 @@ use kcl_derive_docs::stdlib; use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd}; use kittycad_modeling_cmds::{self as kcmc}; +use super::DEFAULT_TOLERANCE; use crate::{ errors::{KclError, KclErrorDetails}, execution::{types::RuntimeType, ExecState, KclValue, Sketch, Solid}, parsing::ast::types::TagNode, - std::{axis_or_reference::Axis2dOrEdgeReference, extrude::do_post_extrude, fillet::default_tolerance, Args}, + std::{axis_or_reference::Axis2dOrEdgeReference, extrude::do_post_extrude, Args}, }; /// Revolve a sketch or set of sketches around an axis. @@ -273,7 +274,7 @@ async fn inner_revolve( target: sketch.id.into(), axis, origin, - tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))), + tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)), axis_is_2d: true, }), ) @@ -287,7 +288,7 @@ async fn inner_revolve( angle, target: sketch.id.into(), edge_id, - tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))), + tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)), }), ) .await?; diff --git a/rust/kcl-lib/src/std/sweep.rs b/rust/kcl-lib/src/std/sweep.rs index 3a00ceced..c0f2981da 100644 --- a/rust/kcl-lib/src/std/sweep.rs +++ b/rust/kcl-lib/src/std/sweep.rs @@ -7,11 +7,12 @@ use kittycad_modeling_cmds::{self as kcmc}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use super::DEFAULT_TOLERANCE; use crate::{ errors::KclError, execution::{types::RuntimeType, ExecState, Helix, KclValue, Sketch, Solid}, parsing::ast::types::TagNode, - std::{extrude::do_post_extrude, fillet::default_tolerance, Args}, + std::{extrude::do_post_extrude, Args}, }; /// A path to sweep along. @@ -191,7 +192,7 @@ async fn inner_sweep( target: sketch.id.into(), trajectory, sectional: sectional.unwrap_or(false), - tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))), + tolerance: LengthUnit(tolerance.unwrap_or(DEFAULT_TOLERANCE)), }), ) .await?; diff --git a/rust/kcl-lib/src/std/transform.rs b/rust/kcl-lib/src/std/transform.rs index 3d9f69774..f4bccbe5f 100644 --- a/rust/kcl-lib/src/std/transform.rs +++ b/rust/kcl-lib/src/std/transform.rs @@ -28,15 +28,22 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result Result hole(pipeHole, %) /// |> sweep(path = sweepPath) /// |> scale( -/// scale = [1.0, 1.0, 2.5], +/// x = 1.0, +/// y = 1.0, +/// z = 2.5, /// ) /// ``` /// @@ -89,7 +98,9 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result scale( -/// scale = [1.0, 1.0, 2.5], +/// x = 1.0, +/// y = 1.0, +/// z = 2.5, /// ) /// ``` /// @@ -124,7 +135,7 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result Result, exec_state: &mut ExecState, args: Args, @@ -159,11 +174,7 @@ async fn inner_scale( object_id, transforms: vec![shared::ComponentTransform { scale: Some(shared::TransformBy::> { - property: Point3d { - x: scale[0], - y: scale[1], - z: scale[2], - }, + property: Point3d { x, y, z }, set: false, is_local: !global.unwrap_or(false), }), @@ -190,15 +201,23 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result Result hole(pipeHole, %) /// |> sweep(path = sweepPath) /// |> translate( -/// translate = [1.0, 1.0, 2.5], +/// x = 1.0, +/// y = 1.0, +/// z = 2.5, /// ) /// ``` /// @@ -243,7 +264,9 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result translate( -/// translate = [1.0, 1.0, 2.5], +/// x = 1.0, +/// y = 1.0, +/// z = 2.5, /// ) /// ``` /// @@ -278,7 +301,7 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result Result translate( -/// translate = [5, 5, 0], +/// x = 5, +/// y = 5, +/// z = 0, /// ) /// |> extrude( /// length = 10, @@ -324,7 +349,7 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result translate(translate = [0, 0, 20]) +/// |> translate(x = 0, y = 0, z = 20) /// |> rotate(axis = [0, 0, 1.0], angle = 45) /// /// loft([profile001, profile002]) @@ -336,13 +361,17 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result, exec_state: &mut ExecState, args: Args, @@ -363,9 +392,9 @@ async fn inner_translate( transforms: vec![shared::ComponentTransform { translate: Some(shared::TransformBy::> { property: shared::Point3d { - x: LengthUnit(translate[0]), - y: LengthUnit(translate[1]), - z: LengthUnit(translate[2]), + x: LengthUnit(x), + y: LengthUnit(y), + z: LengthUnit(z), }, set: false, is_local: !global.unwrap_or(false), @@ -506,6 +535,11 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result Result translate(translate = [0, 0, 20]) +/// |> translate(x = 0, y = 0, z = 20) /// |> rotate(axis = [0, 0, 1.0], angle = 45) /// /// loft([profile001, profile002]) diff --git a/rust/kcl-lib/src/test_server.rs b/rust/kcl-lib/src/test_server.rs index e673743fc..c745a4324 100644 --- a/rust/kcl-lib/src/test_server.rs +++ b/rust/kcl-lib/src/test_server.rs @@ -6,7 +6,6 @@ use crate::{ engine::new_zoo_client, errors::ExecErrorWithState, execution::{EnvironmentRef, ExecState, ExecutorContext, ExecutorSettings}, - settings::types::UnitLength, ConnectionError, ExecError, KclError, KclErrorWithOutputs, Program, }; @@ -19,12 +18,8 @@ pub struct RequestBody { /// Executes a kcl program and takes a snapshot of the result. /// This returns the bytes of the snapshot. -pub async fn execute_and_snapshot( - code: &str, - units: UnitLength, - current_file: Option, -) -> Result { - let ctx = new_context(units, true, current_file).await?; +pub async fn execute_and_snapshot(code: &str, current_file: Option) -> Result { + let ctx = new_context(true, current_file).await?; let program = Program::parse_no_errs(code).map_err(KclErrorWithOutputs::no_outputs)?; let res = do_execute_and_snapshot(&ctx, program) .await @@ -38,17 +33,26 @@ pub async fn execute_and_snapshot( /// This returns the bytes of the snapshot. pub async fn execute_and_snapshot_ast( ast: Program, - units: UnitLength, current_file: Option, with_export_step: bool, ) -> Result<(ExecState, EnvironmentRef, image::DynamicImage, Option>), ExecErrorWithState> { - let ctx = new_context(units, true, current_file).await?; - let (exec_state, env, img) = do_execute_and_snapshot(&ctx, ast).await?; + let ctx = new_context(true, current_file).await?; + let (exec_state, env, img) = match do_execute_and_snapshot(&ctx, ast).await { + Ok((exec_state, env_ref, img)) => (exec_state, env_ref, img), + Err(err) => { + // If there was an error executing the program, return it. + // Close the context to avoid any resource leaks. + ctx.close().await; + return Err(err); + } + }; let mut step = None; if with_export_step { let files = match ctx.export_step(true).await { Ok(f) => f, Err(err) => { + // Close the context to avoid any resource leaks. + ctx.close().await; return Err(ExecErrorWithState::new( ExecError::BadExport(format!("Export failed: {:?}", err)), exec_state.clone(), @@ -64,10 +68,9 @@ pub async fn execute_and_snapshot_ast( pub async fn execute_and_snapshot_no_auth( code: &str, - units: UnitLength, current_file: Option, ) -> Result<(image::DynamicImage, EnvironmentRef), ExecError> { - let ctx = new_context(units, false, current_file).await?; + let ctx = new_context(false, current_file).await?; let program = Program::parse_no_errs(code).map_err(KclErrorWithOutputs::no_outputs)?; let res = do_execute_and_snapshot(&ctx, program) .await @@ -111,11 +114,7 @@ async fn do_execute_and_snapshot( Ok((exec_state, result.0, img)) } -pub async fn new_context( - units: UnitLength, - with_auth: bool, - current_file: Option, -) -> Result { +pub async fn new_context(with_auth: bool, current_file: Option) -> Result { let mut client = new_zoo_client(if with_auth { None } else { Some("bad_token".to_string()) }, None) .map_err(ConnectionError::CouldNotMakeClient)?; if !with_auth { @@ -126,7 +125,6 @@ pub async fn new_context( } let mut settings = ExecutorSettings { - units, highlight_edges: true, enable_ssao: false, show_grid: false, @@ -145,7 +143,6 @@ pub async fn new_context( pub async fn execute_and_export_step( code: &str, - units: UnitLength, current_file: Option, ) -> Result< ( @@ -155,7 +152,7 @@ pub async fn execute_and_export_step( ), ExecErrorWithState, > { - let ctx = new_context(units, true, current_file).await?; + let ctx = new_context(true, current_file).await?; let mut exec_state = ExecState::new(&ctx); let program = Program::parse_no_errs(code) .map_err(|err| ExecErrorWithState::new(KclErrorWithOutputs::no_outputs(err).into(), exec_state.clone()))?; diff --git a/rust/kcl-lib/src/unparser.rs b/rust/kcl-lib/src/unparser.rs index d5771d108..8d178cab1 100644 --- a/rust/kcl-lib/src/unparser.rs +++ b/rust/kcl-lib/src/unparser.rs @@ -1,5 +1,8 @@ use std::fmt::Write; +#[cfg(feature = "cli")] +use clap::ValueEnum; + use crate::parsing::{ ast::types::{ Annotation, ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryOperator, BinaryPart, BodyItem, @@ -864,10 +867,33 @@ impl Parameter { } } -/// Collect all the kcl files in a directory, recursively. +lazy_static::lazy_static! { + + pub static ref IMPORT_FILE_EXTENSIONS: Vec = { + let mut import_file_extensions = vec!["stp".to_string(), "glb".to_string(), "fbxb".to_string()]; + #[cfg(feature = "cli")] + let named_extensions = kittycad::types::FileImportFormat::value_variants() + .iter() + .map(|x| format!("{}", x)) + .collect::>(); + #[cfg(not(feature = "cli"))] + let named_extensions = vec![]; // We don't really need this outside of the CLI. + // Add all the default import formats. + import_file_extensions.extend_from_slice(&named_extensions); + import_file_extensions + }; + + pub static ref RELEVANT_EXTENSIONS: Vec = { + let mut relevant_extensions = IMPORT_FILE_EXTENSIONS.clone(); + relevant_extensions.push("kcl".to_string()); + relevant_extensions + }; +} + +/// Collect all the kcl (and other relevant) files in a directory, recursively. #[cfg(not(target_arch = "wasm32"))] #[async_recursion::async_recursion] -pub(crate) async fn walk_dir(dir: &std::path::PathBuf) -> Result, anyhow::Error> { +pub async fn walk_dir(dir: &std::path::PathBuf) -> Result, anyhow::Error> { // Make sure we actually have a directory. if !dir.is_dir() { anyhow::bail!("`{}` is not a directory", dir.display()); @@ -881,7 +907,10 @@ pub(crate) async fn walk_dir(dir: &std::path::PathBuf) -> Result[76, 113, 4]"] - 3["Segment
[119, 136, 4]"] - 4["Segment
[142, 160, 4]"] - 5["Segment
[166, 184, 4]"] - 6["Segment
[190, 246, 4]"] - 7["Segment
[252, 259, 4]"] + 2["Path
[76, 113, 5]"] + 3["Segment
[119, 136, 5]"] + 4["Segment
[142, 160, 5]"] + 5["Segment
[166, 184, 5]"] + 6["Segment
[190, 246, 5]"] + 7["Segment
[252, 259, 5]"] 8[Solid2d] end subgraph path25 [Path] - 25["Path
[76, 111, 5]"] - 26["Segment
[117, 134, 5]"] - 27["Segment
[140, 158, 5]"] - 28["Segment
[164, 182, 5]"] - 29["Segment
[188, 244, 5]"] - 30["Segment
[250, 257, 5]"] + 25["Path
[76, 111, 6]"] + 26["Segment
[117, 134, 6]"] + 27["Segment
[140, 158, 6]"] + 28["Segment
[164, 182, 6]"] + 29["Segment
[188, 244, 6]"] + 30["Segment
[250, 257, 6]"] 31[Solid2d] end - 1["Plane
[47, 66, 4]"] - 9["Sweep Extrusion
[265, 287, 4]"] + 1["Plane
[47, 66, 5]"] + 9["Sweep Extrusion
[265, 287, 5]"] 10[Wall] 11[Wall] 12[Wall] @@ -34,8 +34,8 @@ flowchart LR 21["SweepEdge Adjacent"] 22["SweepEdge Opposite"] 23["SweepEdge Adjacent"] - 24["Plane
[47, 66, 5]"] - 32["Sweep Extrusion
[263, 285, 5]"] + 24["Plane
[47, 66, 6]"] + 32["Sweep Extrusion
[263, 285, 6]"] 33[Wall] 34[Wall] 35[Wall] diff --git a/rust/kcl-lib/tests/assembly_mixed_units_cubes/program_memory.snap b/rust/kcl-lib/tests/assembly_mixed_units_cubes/program_memory.snap index e5b7aa3ff..1a6491220 100644 --- a/rust/kcl-lib/tests/assembly_mixed_units_cubes/program_memory.snap +++ b/rust/kcl-lib/tests/assembly_mixed_units_cubes/program_memory.snap @@ -5,10 +5,10 @@ description: Variables in memory after executing assembly_mixed_units_cubes.kcl { "cubeIn": { "type": "Module", - "value": 4 + "value": 5 }, "cubeMm": { "type": "Module", - "value": 5 + "value": 6 } } diff --git a/rust/kcl-lib/tests/assembly_non_default_units/artifact_commands.snap b/rust/kcl-lib/tests/assembly_non_default_units/artifact_commands.snap index 8d0a44ccb..35d0f62ab 100644 --- a/rust/kcl-lib/tests/assembly_non_default_units/artifact_commands.snap +++ b/rust/kcl-lib/tests/assembly_non_default_units/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands assembly_non_default_units.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/assembly_non_default_units/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/assembly_non_default_units/artifact_graph_flowchart.snap.md index df59ea4bb..3c76048bf 100644 --- a/rust/kcl-lib/tests/assembly_non_default_units/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/assembly_non_default_units/artifact_graph_flowchart.snap.md @@ -1,17 +1,17 @@ ```mermaid flowchart LR subgraph path2 [Path] - 2["Path
[197, 232, 4]"] - 3["Segment
[197, 232, 4]"] + 2["Path
[197, 232, 5]"] + 3["Segment
[197, 232, 5]"] 4[Solid2d] end subgraph path6 [Path] - 6["Path
[113, 148, 5]"] - 7["Segment
[113, 148, 5]"] + 6["Path
[113, 148, 6]"] + 7["Segment
[113, 148, 6]"] 8[Solid2d] end - 1["Plane
[172, 191, 4]"] - 5["Plane
[88, 107, 5]"] + 1["Plane
[172, 191, 5]"] + 5["Plane
[88, 107, 6]"] 1 --- 2 2 --- 3 2 --- 4 diff --git a/rust/kcl-lib/tests/assembly_non_default_units/program_memory.snap b/rust/kcl-lib/tests/assembly_non_default_units/program_memory.snap index 0d6c82eda..9d0c227bf 100644 --- a/rust/kcl-lib/tests/assembly_non_default_units/program_memory.snap +++ b/rust/kcl-lib/tests/assembly_non_default_units/program_memory.snap @@ -5,10 +5,10 @@ description: Variables in memory after executing assembly_non_default_units.kcl { "other1": { "type": "Module", - "value": 4 + "value": 5 }, "other2": { "type": "Module", - "value": 5 + "value": 6 } } diff --git a/rust/kcl-lib/tests/bad_units_in_annotation/artifact_commands.snap b/rust/kcl-lib/tests/bad_units_in_annotation/artifact_commands.snap index 85f71544a..7ff70d0a1 100644 --- a/rust/kcl-lib/tests/bad_units_in_annotation/artifact_commands.snap +++ b/rust/kcl-lib/tests/bad_units_in_annotation/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands bad_units_in_annotation.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/basic_fillet_cube_close_opposite/artifact_commands.snap b/rust/kcl-lib/tests/basic_fillet_cube_close_opposite/artifact_commands.snap index a59a1e02e..db68c4afd 100644 --- a/rust/kcl-lib/tests/basic_fillet_cube_close_opposite/artifact_commands.snap +++ b/rust/kcl-lib/tests/basic_fillet_cube_close_opposite/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands basic_fillet_cube_close_opposite.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/basic_fillet_cube_end/artifact_commands.snap b/rust/kcl-lib/tests/basic_fillet_cube_end/artifact_commands.snap index 9077b89fe..26400b300 100644 --- a/rust/kcl-lib/tests/basic_fillet_cube_end/artifact_commands.snap +++ b/rust/kcl-lib/tests/basic_fillet_cube_end/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands basic_fillet_cube_end.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/basic_fillet_cube_next_adjacent/artifact_commands.snap b/rust/kcl-lib/tests/basic_fillet_cube_next_adjacent/artifact_commands.snap index fe0d4a7bf..651745e1d 100644 --- a/rust/kcl-lib/tests/basic_fillet_cube_next_adjacent/artifact_commands.snap +++ b/rust/kcl-lib/tests/basic_fillet_cube_next_adjacent/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands basic_fillet_cube_next_adjacent.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/basic_fillet_cube_previous_adjacent/artifact_commands.snap b/rust/kcl-lib/tests/basic_fillet_cube_previous_adjacent/artifact_commands.snap index cf4588ae6..5909434e8 100644 --- a/rust/kcl-lib/tests/basic_fillet_cube_previous_adjacent/artifact_commands.snap +++ b/rust/kcl-lib/tests/basic_fillet_cube_previous_adjacent/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands basic_fillet_cube_previous_adjacent.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/basic_fillet_cube_start/artifact_commands.snap b/rust/kcl-lib/tests/basic_fillet_cube_start/artifact_commands.snap index 9389d855b..3ce091a41 100644 --- a/rust/kcl-lib/tests/basic_fillet_cube_start/artifact_commands.snap +++ b/rust/kcl-lib/tests/basic_fillet_cube_start/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands basic_fillet_cube_start.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/big_number_angle_to_match_length_x/artifact_commands.snap b/rust/kcl-lib/tests/big_number_angle_to_match_length_x/artifact_commands.snap index 7070a10ba..7f9c6109a 100644 --- a/rust/kcl-lib/tests/big_number_angle_to_match_length_x/artifact_commands.snap +++ b/rust/kcl-lib/tests/big_number_angle_to_match_length_x/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands big_number_angle_to_match_length_x.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/big_number_angle_to_match_length_y/artifact_commands.snap b/rust/kcl-lib/tests/big_number_angle_to_match_length_y/artifact_commands.snap index 99e9a0dd5..eda9181f3 100644 --- a/rust/kcl-lib/tests/big_number_angle_to_match_length_y/artifact_commands.snap +++ b/rust/kcl-lib/tests/big_number_angle_to_match_length_y/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands big_number_angle_to_match_length_y.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/boolean_logical_and/artifact_commands.snap b/rust/kcl-lib/tests/boolean_logical_and/artifact_commands.snap index 902522491..9cd09307a 100644 --- a/rust/kcl-lib/tests/boolean_logical_and/artifact_commands.snap +++ b/rust/kcl-lib/tests/boolean_logical_and/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands boolean_logical_and.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/boolean_logical_multiple/artifact_commands.snap b/rust/kcl-lib/tests/boolean_logical_multiple/artifact_commands.snap index 78c0c63ed..a53ce5526 100644 --- a/rust/kcl-lib/tests/boolean_logical_multiple/artifact_commands.snap +++ b/rust/kcl-lib/tests/boolean_logical_multiple/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands boolean_logical_multiple.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/boolean_logical_or/artifact_commands.snap b/rust/kcl-lib/tests/boolean_logical_or/artifact_commands.snap index 4cd801e11..374262ba5 100644 --- a/rust/kcl-lib/tests/boolean_logical_or/artifact_commands.snap +++ b/rust/kcl-lib/tests/boolean_logical_or/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands boolean_logical_or.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/circle_three_point/artifact_commands.snap b/rust/kcl-lib/tests/circle_three_point/artifact_commands.snap index f57bf4e09..ae1e90596 100644 --- a/rust/kcl-lib/tests/circle_three_point/artifact_commands.snap +++ b/rust/kcl-lib/tests/circle_three_point/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands circle_three_point.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/circular_pattern3d_a_pattern/artifact_commands.snap b/rust/kcl-lib/tests/circular_pattern3d_a_pattern/artifact_commands.snap index 00e1f220f..bca7d582c 100644 --- a/rust/kcl-lib/tests/circular_pattern3d_a_pattern/artifact_commands.snap +++ b/rust/kcl-lib/tests/circular_pattern3d_a_pattern/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands circular_pattern3d_a_pattern.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/comparisons/artifact_commands.snap b/rust/kcl-lib/tests/comparisons/artifact_commands.snap index 3aa02f17a..4d84ea423 100644 --- a/rust/kcl-lib/tests/comparisons/artifact_commands.snap +++ b/rust/kcl-lib/tests/comparisons/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands comparisons.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/comparisons_multiple/artifact_commands.snap b/rust/kcl-lib/tests/comparisons_multiple/artifact_commands.snap index f3eabeea4..c7f2d8842 100644 --- a/rust/kcl-lib/tests/comparisons_multiple/artifact_commands.snap +++ b/rust/kcl-lib/tests/comparisons_multiple/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands comparisons_multiple.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/computed_var/artifact_commands.snap b/rust/kcl-lib/tests/computed_var/artifact_commands.snap index 040f1571b..5b4200403 100644 --- a/rust/kcl-lib/tests/computed_var/artifact_commands.snap +++ b/rust/kcl-lib/tests/computed_var/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands computed_var.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/crazy_multi_profile/artifact_commands.snap b/rust/kcl-lib/tests/crazy_multi_profile/artifact_commands.snap index 17dbe7722..403cfd8a8 100644 --- a/rust/kcl-lib/tests/crazy_multi_profile/artifact_commands.snap +++ b/rust/kcl-lib/tests/crazy_multi_profile/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands crazy_multi_profile.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/cube/artifact_commands.snap b/rust/kcl-lib/tests/cube/artifact_commands.snap index e9086ae16..f25d36f1c 100644 --- a/rust/kcl-lib/tests/cube/artifact_commands.snap +++ b/rust/kcl-lib/tests/cube/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands cube.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/cube_with_error/artifact_commands.snap b/rust/kcl-lib/tests/cube_with_error/artifact_commands.snap index 711c3f7c6..93b9411b9 100644 --- a/rust/kcl-lib/tests/cube_with_error/artifact_commands.snap +++ b/rust/kcl-lib/tests/cube_with_error/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands cube_with_error.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/double_map_fn/artifact_commands.snap b/rust/kcl-lib/tests/double_map_fn/artifact_commands.snap index 9fd3e7dba..1dbd81b6d 100644 --- a/rust/kcl-lib/tests/double_map_fn/artifact_commands.snap +++ b/rust/kcl-lib/tests/double_map_fn/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands double_map_fn.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/fillet-and-shell/artifact_commands.snap b/rust/kcl-lib/tests/fillet-and-shell/artifact_commands.snap index 392ae4bd9..e8a8c7f18 100644 --- a/rust/kcl-lib/tests/fillet-and-shell/artifact_commands.snap +++ b/rust/kcl-lib/tests/fillet-and-shell/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands fillet-and-shell.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/flush_batch_on_end/artifact_commands.snap b/rust/kcl-lib/tests/flush_batch_on_end/artifact_commands.snap index bd44e849e..5983766de 100644 --- a/rust/kcl-lib/tests/flush_batch_on_end/artifact_commands.snap +++ b/rust/kcl-lib/tests/flush_batch_on_end/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands flush_batch_on_end.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/function_sketch/artifact_commands.snap b/rust/kcl-lib/tests/function_sketch/artifact_commands.snap index af09bcdf9..3a741b800 100644 --- a/rust/kcl-lib/tests/function_sketch/artifact_commands.snap +++ b/rust/kcl-lib/tests/function_sketch/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands function_sketch.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/function_sketch_with_position/artifact_commands.snap b/rust/kcl-lib/tests/function_sketch_with_position/artifact_commands.snap index f1bbba0a5..c05b55d86 100644 --- a/rust/kcl-lib/tests/function_sketch_with_position/artifact_commands.snap +++ b/rust/kcl-lib/tests/function_sketch_with_position/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands function_sketch_with_position.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/helix_ccw/artifact_commands.snap b/rust/kcl-lib/tests/helix_ccw/artifact_commands.snap index d64456fa1..6b40a6102 100644 --- a/rust/kcl-lib/tests/helix_ccw/artifact_commands.snap +++ b/rust/kcl-lib/tests/helix_ccw/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands helix_ccw.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/helix_simple/artifact_commands.snap b/rust/kcl-lib/tests/helix_simple/artifact_commands.snap index 34c27f06d..2db09c2e7 100644 --- a/rust/kcl-lib/tests/helix_simple/artifact_commands.snap +++ b/rust/kcl-lib/tests/helix_simple/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands helix_simple.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/i_shape/artifact_commands.snap b/rust/kcl-lib/tests/i_shape/artifact_commands.snap index c733c4e44..3f7335fe8 100644 --- a/rust/kcl-lib/tests/i_shape/artifact_commands.snap +++ b/rust/kcl-lib/tests/i_shape/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands i_shape.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/if_else/artifact_commands.snap b/rust/kcl-lib/tests/if_else/artifact_commands.snap index 762e10c0b..a33ac287d 100644 --- a/rust/kcl-lib/tests/if_else/artifact_commands.snap +++ b/rust/kcl-lib/tests/if_else/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands if_else.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/import_constant/artifact_commands.snap b/rust/kcl-lib/tests/import_constant/artifact_commands.snap index 028aaffc2..78eeb4c8c 100644 --- a/rust/kcl-lib/tests/import_constant/artifact_commands.snap +++ b/rust/kcl-lib/tests/import_constant/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands import_constant.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/import_cycle1/artifact_commands.snap b/rust/kcl-lib/tests/import_cycle1/artifact_commands.snap index 6dd19278b..0075075f7 100644 --- a/rust/kcl-lib/tests/import_cycle1/artifact_commands.snap +++ b/rust/kcl-lib/tests/import_cycle1/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands import_cycle1.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/import_export/artifact_commands.snap b/rust/kcl-lib/tests/import_export/artifact_commands.snap index 36d9f17ec..7ac69634b 100644 --- a/rust/kcl-lib/tests/import_export/artifact_commands.snap +++ b/rust/kcl-lib/tests/import_export/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands import_export.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/import_file_not_exist_error/artifact_commands.snap b/rust/kcl-lib/tests/import_file_not_exist_error/artifact_commands.snap index 54fb9c7d6..8b760a128 100644 --- a/rust/kcl-lib/tests/import_file_not_exist_error/artifact_commands.snap +++ b/rust/kcl-lib/tests/import_file_not_exist_error/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands import_file_not_exist_error.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/import_file_parse_error/artifact_commands.snap b/rust/kcl-lib/tests/import_file_parse_error/artifact_commands.snap index a69103651..ff504f24c 100644 --- a/rust/kcl-lib/tests/import_file_parse_error/artifact_commands.snap +++ b/rust/kcl-lib/tests/import_file_parse_error/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands import_file_parse_error.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/import_foreign/artifact_commands.snap b/rust/kcl-lib/tests/import_foreign/artifact_commands.snap index 484765b69..a7971688c 100644 --- a/rust/kcl-lib/tests/import_foreign/artifact_commands.snap +++ b/rust/kcl-lib/tests/import_foreign/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands import_foreign.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/import_foreign/program_memory.snap b/rust/kcl-lib/tests/import_foreign/program_memory.snap index 585e23400..88d57cd00 100644 --- a/rust/kcl-lib/tests/import_foreign/program_memory.snap +++ b/rust/kcl-lib/tests/import_foreign/program_memory.snap @@ -5,7 +5,7 @@ description: Variables in memory after executing import_foreign.kcl { "cube": { "type": "Module", - "value": 4 + "value": 5 }, "model": { "type": "ImportedGeometry", diff --git a/rust/kcl-lib/tests/import_function_not_sketch/artifact_commands.snap b/rust/kcl-lib/tests/import_function_not_sketch/artifact_commands.snap index 4d2508cd3..f9fa43681 100644 --- a/rust/kcl-lib/tests/import_function_not_sketch/artifact_commands.snap +++ b/rust/kcl-lib/tests/import_function_not_sketch/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands import_function_not_sketch.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/import_glob/artifact_commands.snap b/rust/kcl-lib/tests/import_glob/artifact_commands.snap index 8d6423f70..eb22fbbc5 100644 --- a/rust/kcl-lib/tests/import_glob/artifact_commands.snap +++ b/rust/kcl-lib/tests/import_glob/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands import_glob.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/import_side_effect/artifact_commands.snap b/rust/kcl-lib/tests/import_side_effect/artifact_commands.snap index d92060f6b..a1e39f9d8 100644 --- a/rust/kcl-lib/tests/import_side_effect/artifact_commands.snap +++ b/rust/kcl-lib/tests/import_side_effect/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands import_side_effect.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/import_transform/artifact_commands.snap b/rust/kcl-lib/tests/import_transform/artifact_commands.snap index 7eadb5e7a..3c4b223ca 100644 --- a/rust/kcl-lib/tests/import_transform/artifact_commands.snap +++ b/rust/kcl-lib/tests/import_transform/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands import_transform.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/import_transform/ast.snap b/rust/kcl-lib/tests/import_transform/ast.snap index 044532537..5c2fb7932 100644 --- a/rust/kcl-lib/tests/import_transform/ast.snap +++ b/rust/kcl-lib/tests/import_transform/ast.snap @@ -151,54 +151,65 @@ description: Result of parsing import_transform.kcl "label": { "commentStart": 159, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 171, - "elements": [ - { - "commentStart": 172, - "end": 0, - "raw": "3.14", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 3.14, - "suffix": "None" - } - }, - { - "commentStart": 178, - "end": 0, - "raw": "3.14", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 3.14, - "suffix": "None" - } - }, - { - "commentStart": 184, - "end": 0, - "raw": "3.14", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 3.14, - "suffix": "None" - } - } - ], + "commentStart": 163, "end": 0, + "raw": "3.14", "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "Literal", + "type": "Literal", + "value": { + "value": 3.14, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 169, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 173, + "end": 0, + "raw": "3.14", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 3.14, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 179, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 183, + "end": 0, + "raw": "3.14", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 3.14, + "suffix": "None" + } } } ], @@ -235,65 +246,76 @@ description: Result of parsing import_transform.kcl { "type": "LabeledArg", "label": { - "commentStart": 205, + "commentStart": 203, "end": 0, - "name": "scale", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 213, - "elements": [ - { - "commentStart": 214, - "end": 0, - "raw": "3.14", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 3.14, - "suffix": "None" - } - }, - { - "commentStart": 220, - "end": 0, - "raw": "3.14", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 3.14, - "suffix": "None" - } - }, - { - "commentStart": 226, - "end": 0, - "raw": "3.14", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 3.14, - "suffix": "None" - } - } - ], + "commentStart": 207, "end": 0, + "raw": "3.14", "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "Literal", + "type": "Literal", + "value": { + "value": 3.14, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 213, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 217, + "end": 0, + "raw": "3.14", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 3.14, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 223, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 227, + "end": 0, + "raw": "3.14", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 3.14, + "suffix": "None" + } } } ], "callee": { "abs_path": false, - "commentStart": 196, + "commentStart": 194, "end": 0, "name": { - "commentStart": 196, + "commentStart": 194, "end": 0, "name": "scale", "start": 0, @@ -303,13 +325,13 @@ description: Result of parsing import_transform.kcl "start": 0, "type": "Name" }, - "commentStart": 196, + "commentStart": 194, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { - "commentStart": 202, + "commentStart": 200, "end": 0, "start": 0, "type": "PipeSubstitution", diff --git a/rust/kcl-lib/tests/import_transform/input.kcl b/rust/kcl-lib/tests/import_transform/input.kcl index a09972a87..953c90838 100644 --- a/rust/kcl-lib/tests/import_transform/input.kcl +++ b/rust/kcl-lib/tests/import_transform/input.kcl @@ -7,5 +7,5 @@ screw pitch = 3.14, yaw = 3.14, ) - |> translate(%, translate = [3.14, 3.14, 3.14]) - |> scale(%, scale = [3.14, 3.14, 3.14]) + |> translate(%, x = 3.14, y = 3.14, z = 3.14) + |> scale(%, x = 3.14, y = 3.14, z = 3.14) diff --git a/rust/kcl-lib/tests/import_transform/program_memory.snap b/rust/kcl-lib/tests/import_transform/program_memory.snap index 8599d50df..ef1a01f7f 100644 --- a/rust/kcl-lib/tests/import_transform/program_memory.snap +++ b/rust/kcl-lib/tests/import_transform/program_memory.snap @@ -5,6 +5,6 @@ description: Variables in memory after executing import_transform.kcl { "screw": { "type": "Module", - "value": 4 + "value": 5 } } diff --git a/rust/kcl-lib/tests/import_transform/unparsed.snap b/rust/kcl-lib/tests/import_transform/unparsed.snap index ea0f378fe..d30f0fbef 100644 --- a/rust/kcl-lib/tests/import_transform/unparsed.snap +++ b/rust/kcl-lib/tests/import_transform/unparsed.snap @@ -11,5 +11,15 @@ screw pitch = 3.14, yaw = 3.14, ) - |> translate(%, translate = [3.14, 3.14, 3.14]) - |> scale(%, scale = [3.14, 3.14, 3.14]) + |> translate( + %, + x = 3.14, + y = 3.14, + z = 3.14, + ) + |> scale( + %, + x = 3.14, + y = 3.14, + z = 3.14, + ) diff --git a/rust/kcl-lib/tests/import_whole/artifact_commands.snap b/rust/kcl-lib/tests/import_whole/artifact_commands.snap index b0c86bfbd..d5018b761 100644 --- a/rust/kcl-lib/tests/import_whole/artifact_commands.snap +++ b/rust/kcl-lib/tests/import_whole/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands import_whole.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/import_whole/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/import_whole/artifact_graph_flowchart.snap.md index 02ba66870..ce1d43882 100644 --- a/rust/kcl-lib/tests/import_whole/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/import_whole/artifact_graph_flowchart.snap.md @@ -1,12 +1,12 @@ ```mermaid flowchart LR subgraph path2 [Path] - 2["Path
[83, 119, 4]"] - 3["Segment
[83, 119, 4]"] + 2["Path
[83, 119, 5]"] + 3["Segment
[83, 119, 5]"] 4[Solid2d] end - 1["Plane
[60, 77, 4]"] - 5["Sweep Extrusion
[125, 145, 4]"] + 1["Plane
[60, 77, 5]"] + 5["Sweep Extrusion
[125, 145, 5]"] 6[Wall] 7["Cap Start"] 8["Cap End"] diff --git a/rust/kcl-lib/tests/import_whole/program_memory.snap b/rust/kcl-lib/tests/import_whole/program_memory.snap index afceb706f..be03eed1d 100644 --- a/rust/kcl-lib/tests/import_whole/program_memory.snap +++ b/rust/kcl-lib/tests/import_whole/program_memory.snap @@ -111,6 +111,6 @@ description: Variables in memory after executing import_whole.kcl }, "foo": { "type": "Module", - "value": 4 + "value": 5 } } diff --git a/rust/kcl-lib/tests/index_of_array/artifact_commands.snap b/rust/kcl-lib/tests/index_of_array/artifact_commands.snap index 7bab36f3a..28adaa521 100644 --- a/rust/kcl-lib/tests/index_of_array/artifact_commands.snap +++ b/rust/kcl-lib/tests/index_of_array/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands index_of_array.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/intersect_cubes/artifact_commands.snap b/rust/kcl-lib/tests/intersect_cubes/artifact_commands.snap index 06ac34587..665c37255 100644 --- a/rust/kcl-lib/tests/intersect_cubes/artifact_commands.snap +++ b/rust/kcl-lib/tests/intersect_cubes/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands intersect_cubes.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/invalid_index_fractional/artifact_commands.snap b/rust/kcl-lib/tests/invalid_index_fractional/artifact_commands.snap index 8499f44b2..d1a70f78c 100644 --- a/rust/kcl-lib/tests/invalid_index_fractional/artifact_commands.snap +++ b/rust/kcl-lib/tests/invalid_index_fractional/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands invalid_index_fractional.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/invalid_index_negative/artifact_commands.snap b/rust/kcl-lib/tests/invalid_index_negative/artifact_commands.snap index 0670fda9a..3badb4d21 100644 --- a/rust/kcl-lib/tests/invalid_index_negative/artifact_commands.snap +++ b/rust/kcl-lib/tests/invalid_index_negative/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands invalid_index_negative.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/invalid_index_str/artifact_commands.snap b/rust/kcl-lib/tests/invalid_index_str/artifact_commands.snap index 0151c1417..2c5ba5365 100644 --- a/rust/kcl-lib/tests/invalid_index_str/artifact_commands.snap +++ b/rust/kcl-lib/tests/invalid_index_str/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands invalid_index_str.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/invalid_member_object/artifact_commands.snap b/rust/kcl-lib/tests/invalid_member_object/artifact_commands.snap index 765c4b0de..7070f1c03 100644 --- a/rust/kcl-lib/tests/invalid_member_object/artifact_commands.snap +++ b/rust/kcl-lib/tests/invalid_member_object/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands invalid_member_object.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/invalid_member_object_prop/artifact_commands.snap b/rust/kcl-lib/tests/invalid_member_object_prop/artifact_commands.snap index 547a828fa..9a82ca531 100644 --- a/rust/kcl-lib/tests/invalid_member_object_prop/artifact_commands.snap +++ b/rust/kcl-lib/tests/invalid_member_object_prop/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands invalid_member_object_prop.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/80-20-rail/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/80-20-rail/artifact_commands.snap index 6b43582ec..abdf82584 100644 --- a/rust/kcl-lib/tests/kcl_samples/80-20-rail/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/80-20-rail/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands 80-20-rail.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/a-parametric-bearing-pillow-block/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/a-parametric-bearing-pillow-block/artifact_commands.snap index cd45bdffe..b5e677798 100644 --- a/rust/kcl-lib/tests/kcl_samples/a-parametric-bearing-pillow-block/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/a-parametric-bearing-pillow-block/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands a-parametric-bearing-pillow-block.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/ball-bearing/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/ball-bearing/artifact_commands.snap index fc1012146..38bd16c17 100644 --- a/rust/kcl-lib/tests/kcl_samples/ball-bearing/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/ball-bearing/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands ball-bearing.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/bench/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/bench/artifact_commands.snap index d81c96b90..a9d90dc3a 100644 --- a/rust/kcl-lib/tests/kcl_samples/bench/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/bench/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands bench.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/bench/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/kcl_samples/bench/artifact_graph_flowchart.snap.md index 5d4b87145..89829e189 100644 --- a/rust/kcl-lib/tests/kcl_samples/bench/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/kcl_samples/bench/artifact_graph_flowchart.snap.md @@ -1,239 +1,239 @@ ```mermaid flowchart LR subgraph path2 [Path] - 2["Path
[361, 394, 4]"] - 3["Segment
[402, 428, 4]"] - 4["Segment
[436, 489, 4]"] - 5["Segment
[497, 550, 4]"] - 6["Segment
[558, 612, 4]"] - 7["Segment
[620, 645, 4]"] - 8["Segment
[653, 673, 4]"] - 9["Segment
[681, 705, 4]"] - 10["Segment
[713, 766, 4]"] - 11["Segment
[774, 799, 4]"] - 12["Segment
[807, 827, 4]"] - 13["Segment
[835, 859, 4]"] - 14["Segment
[867, 919, 4]"] - 15["Segment
[927, 979, 4]"] - 16["Segment
[987, 1012, 4]"] - 17["Segment
[1020, 1044, 4]"] - 18["Segment
[1052, 1105, 4]"] - 19["Segment
[1113, 1138, 4]"] - 20["Segment
[1146, 1173, 4]"] - 21["Segment
[1181, 1233, 4]"] - 22["Segment
[1241, 1276, 4]"] - 23["Segment
[1284, 1291, 4]"] + 2["Path
[361, 394, 5]"] + 3["Segment
[402, 428, 5]"] + 4["Segment
[436, 489, 5]"] + 5["Segment
[497, 550, 5]"] + 6["Segment
[558, 612, 5]"] + 7["Segment
[620, 645, 5]"] + 8["Segment
[653, 673, 5]"] + 9["Segment
[681, 705, 5]"] + 10["Segment
[713, 766, 5]"] + 11["Segment
[774, 799, 5]"] + 12["Segment
[807, 827, 5]"] + 13["Segment
[835, 859, 5]"] + 14["Segment
[867, 919, 5]"] + 15["Segment
[927, 979, 5]"] + 16["Segment
[987, 1012, 5]"] + 17["Segment
[1020, 1044, 5]"] + 18["Segment
[1052, 1105, 5]"] + 19["Segment
[1113, 1138, 5]"] + 20["Segment
[1146, 1173, 5]"] + 21["Segment
[1181, 1233, 5]"] + 22["Segment
[1241, 1276, 5]"] + 23["Segment
[1284, 1291, 5]"] 24[Solid2d] end subgraph path89 [Path] - 89["Path
[361, 394, 4]"] - 90["Segment
[402, 428, 4]"] - 91["Segment
[436, 489, 4]"] - 92["Segment
[497, 550, 4]"] - 93["Segment
[558, 612, 4]"] - 94["Segment
[620, 645, 4]"] - 95["Segment
[653, 673, 4]"] - 96["Segment
[681, 705, 4]"] - 97["Segment
[713, 766, 4]"] - 98["Segment
[774, 799, 4]"] - 99["Segment
[807, 827, 4]"] - 100["Segment
[835, 859, 4]"] - 101["Segment
[867, 919, 4]"] - 102["Segment
[927, 979, 4]"] - 103["Segment
[987, 1012, 4]"] - 104["Segment
[1020, 1044, 4]"] - 105["Segment
[1052, 1105, 4]"] - 106["Segment
[1113, 1138, 4]"] - 107["Segment
[1146, 1173, 4]"] - 108["Segment
[1181, 1233, 4]"] - 109["Segment
[1241, 1276, 4]"] - 110["Segment
[1284, 1291, 4]"] + 89["Path
[361, 394, 5]"] + 90["Segment
[402, 428, 5]"] + 91["Segment
[436, 489, 5]"] + 92["Segment
[497, 550, 5]"] + 93["Segment
[558, 612, 5]"] + 94["Segment
[620, 645, 5]"] + 95["Segment
[653, 673, 5]"] + 96["Segment
[681, 705, 5]"] + 97["Segment
[713, 766, 5]"] + 98["Segment
[774, 799, 5]"] + 99["Segment
[807, 827, 5]"] + 100["Segment
[835, 859, 5]"] + 101["Segment
[867, 919, 5]"] + 102["Segment
[927, 979, 5]"] + 103["Segment
[987, 1012, 5]"] + 104["Segment
[1020, 1044, 5]"] + 105["Segment
[1052, 1105, 5]"] + 106["Segment
[1113, 1138, 5]"] + 107["Segment
[1146, 1173, 5]"] + 108["Segment
[1181, 1233, 5]"] + 109["Segment
[1241, 1276, 5]"] + 110["Segment
[1284, 1291, 5]"] 111[Solid2d] end subgraph path176 [Path] - 176["Path
[361, 394, 4]"] - 177["Segment
[402, 428, 4]"] - 178["Segment
[436, 489, 4]"] - 179["Segment
[497, 550, 4]"] - 180["Segment
[558, 612, 4]"] - 181["Segment
[620, 645, 4]"] - 182["Segment
[653, 673, 4]"] - 183["Segment
[681, 705, 4]"] - 184["Segment
[713, 766, 4]"] - 185["Segment
[774, 799, 4]"] - 186["Segment
[807, 827, 4]"] - 187["Segment
[835, 859, 4]"] - 188["Segment
[867, 919, 4]"] - 189["Segment
[927, 979, 4]"] - 190["Segment
[987, 1012, 4]"] - 191["Segment
[1020, 1044, 4]"] - 192["Segment
[1052, 1105, 4]"] - 193["Segment
[1113, 1138, 4]"] - 194["Segment
[1146, 1173, 4]"] - 195["Segment
[1181, 1233, 4]"] - 196["Segment
[1241, 1276, 4]"] - 197["Segment
[1284, 1291, 4]"] + 176["Path
[361, 394, 5]"] + 177["Segment
[402, 428, 5]"] + 178["Segment
[436, 489, 5]"] + 179["Segment
[497, 550, 5]"] + 180["Segment
[558, 612, 5]"] + 181["Segment
[620, 645, 5]"] + 182["Segment
[653, 673, 5]"] + 183["Segment
[681, 705, 5]"] + 184["Segment
[713, 766, 5]"] + 185["Segment
[774, 799, 5]"] + 186["Segment
[807, 827, 5]"] + 187["Segment
[835, 859, 5]"] + 188["Segment
[867, 919, 5]"] + 189["Segment
[927, 979, 5]"] + 190["Segment
[987, 1012, 5]"] + 191["Segment
[1020, 1044, 5]"] + 192["Segment
[1052, 1105, 5]"] + 193["Segment
[1113, 1138, 5]"] + 194["Segment
[1146, 1173, 5]"] + 195["Segment
[1181, 1233, 5]"] + 196["Segment
[1241, 1276, 5]"] + 197["Segment
[1284, 1291, 5]"] 198[Solid2d] end subgraph path262 [Path] - 262["Path
[361, 394, 4]"] - 263["Segment
[402, 428, 4]"] - 264["Segment
[436, 489, 4]"] - 265["Segment
[497, 550, 4]"] - 266["Segment
[558, 612, 4]"] - 267["Segment
[620, 645, 4]"] - 268["Segment
[653, 673, 4]"] - 269["Segment
[681, 705, 4]"] - 270["Segment
[713, 766, 4]"] - 271["Segment
[774, 799, 4]"] - 272["Segment
[807, 827, 4]"] - 273["Segment
[835, 859, 4]"] - 274["Segment
[867, 919, 4]"] - 275["Segment
[927, 979, 4]"] - 276["Segment
[987, 1012, 4]"] - 277["Segment
[1020, 1044, 4]"] - 278["Segment
[1052, 1105, 4]"] - 279["Segment
[1113, 1138, 4]"] - 280["Segment
[1146, 1173, 4]"] - 281["Segment
[1181, 1233, 4]"] - 282["Segment
[1241, 1276, 4]"] - 283["Segment
[1284, 1291, 4]"] + 262["Path
[361, 394, 5]"] + 263["Segment
[402, 428, 5]"] + 264["Segment
[436, 489, 5]"] + 265["Segment
[497, 550, 5]"] + 266["Segment
[558, 612, 5]"] + 267["Segment
[620, 645, 5]"] + 268["Segment
[653, 673, 5]"] + 269["Segment
[681, 705, 5]"] + 270["Segment
[713, 766, 5]"] + 271["Segment
[774, 799, 5]"] + 272["Segment
[807, 827, 5]"] + 273["Segment
[835, 859, 5]"] + 274["Segment
[867, 919, 5]"] + 275["Segment
[927, 979, 5]"] + 276["Segment
[987, 1012, 5]"] + 277["Segment
[1020, 1044, 5]"] + 278["Segment
[1052, 1105, 5]"] + 279["Segment
[1113, 1138, 5]"] + 280["Segment
[1146, 1173, 5]"] + 281["Segment
[1181, 1233, 5]"] + 282["Segment
[1241, 1276, 5]"] + 283["Segment
[1284, 1291, 5]"] 284[Solid2d] end subgraph path349 [Path] - 349["Path
[361, 394, 4]"] - 350["Segment
[402, 428, 4]"] - 351["Segment
[436, 489, 4]"] - 352["Segment
[497, 550, 4]"] - 353["Segment
[558, 612, 4]"] - 354["Segment
[620, 645, 4]"] - 355["Segment
[653, 673, 4]"] - 356["Segment
[681, 705, 4]"] - 357["Segment
[713, 766, 4]"] - 358["Segment
[774, 799, 4]"] - 359["Segment
[807, 827, 4]"] - 360["Segment
[835, 859, 4]"] - 361["Segment
[867, 919, 4]"] - 362["Segment
[927, 979, 4]"] - 363["Segment
[987, 1012, 4]"] - 364["Segment
[1020, 1044, 4]"] - 365["Segment
[1052, 1105, 4]"] - 366["Segment
[1113, 1138, 4]"] - 367["Segment
[1146, 1173, 4]"] - 368["Segment
[1181, 1233, 4]"] - 369["Segment
[1241, 1276, 4]"] - 370["Segment
[1284, 1291, 4]"] + 349["Path
[361, 394, 5]"] + 350["Segment
[402, 428, 5]"] + 351["Segment
[436, 489, 5]"] + 352["Segment
[497, 550, 5]"] + 353["Segment
[558, 612, 5]"] + 354["Segment
[620, 645, 5]"] + 355["Segment
[653, 673, 5]"] + 356["Segment
[681, 705, 5]"] + 357["Segment
[713, 766, 5]"] + 358["Segment
[774, 799, 5]"] + 359["Segment
[807, 827, 5]"] + 360["Segment
[835, 859, 5]"] + 361["Segment
[867, 919, 5]"] + 362["Segment
[927, 979, 5]"] + 363["Segment
[987, 1012, 5]"] + 364["Segment
[1020, 1044, 5]"] + 365["Segment
[1052, 1105, 5]"] + 366["Segment
[1113, 1138, 5]"] + 367["Segment
[1146, 1173, 5]"] + 368["Segment
[1181, 1233, 5]"] + 369["Segment
[1241, 1276, 5]"] + 370["Segment
[1284, 1291, 5]"] 371[Solid2d] end subgraph path435 [Path] - 435["Path
[361, 394, 4]"] - 436["Segment
[402, 428, 4]"] - 437["Segment
[436, 489, 4]"] - 438["Segment
[497, 550, 4]"] - 439["Segment
[558, 612, 4]"] - 440["Segment
[620, 645, 4]"] - 441["Segment
[653, 673, 4]"] - 442["Segment
[681, 705, 4]"] - 443["Segment
[713, 766, 4]"] - 444["Segment
[774, 799, 4]"] - 445["Segment
[807, 827, 4]"] - 446["Segment
[835, 859, 4]"] - 447["Segment
[867, 919, 4]"] - 448["Segment
[927, 979, 4]"] - 449["Segment
[987, 1012, 4]"] - 450["Segment
[1020, 1044, 4]"] - 451["Segment
[1052, 1105, 4]"] - 452["Segment
[1113, 1138, 4]"] - 453["Segment
[1146, 1173, 4]"] - 454["Segment
[1181, 1233, 4]"] - 455["Segment
[1241, 1276, 4]"] - 456["Segment
[1284, 1291, 4]"] + 435["Path
[361, 394, 5]"] + 436["Segment
[402, 428, 5]"] + 437["Segment
[436, 489, 5]"] + 438["Segment
[497, 550, 5]"] + 439["Segment
[558, 612, 5]"] + 440["Segment
[620, 645, 5]"] + 441["Segment
[653, 673, 5]"] + 442["Segment
[681, 705, 5]"] + 443["Segment
[713, 766, 5]"] + 444["Segment
[774, 799, 5]"] + 445["Segment
[807, 827, 5]"] + 446["Segment
[835, 859, 5]"] + 447["Segment
[867, 919, 5]"] + 448["Segment
[927, 979, 5]"] + 449["Segment
[987, 1012, 5]"] + 450["Segment
[1020, 1044, 5]"] + 451["Segment
[1052, 1105, 5]"] + 452["Segment
[1113, 1138, 5]"] + 453["Segment
[1146, 1173, 5]"] + 454["Segment
[1181, 1233, 5]"] + 455["Segment
[1241, 1276, 5]"] + 456["Segment
[1284, 1291, 5]"] 457[Solid2d] end subgraph path522 [Path] - 522["Path
[1685, 1709, 4]"] + 522["Path
[1685, 1709, 5]"] end subgraph path523 [Path] - 523["Path
[1717, 1847, 4]"] - 524["Segment
[1717, 1847, 4]"] - 525["Segment
[1717, 1847, 4]"] - 526["Segment
[1717, 1847, 4]"] - 527["Segment
[1717, 1847, 4]"] - 528["Segment
[1717, 1847, 4]"] - 529["Segment
[1717, 1847, 4]"] - 530["Segment
[1717, 1847, 4]"] + 523["Path
[1717, 1847, 5]"] + 524["Segment
[1717, 1847, 5]"] + 525["Segment
[1717, 1847, 5]"] + 526["Segment
[1717, 1847, 5]"] + 527["Segment
[1717, 1847, 5]"] + 528["Segment
[1717, 1847, 5]"] + 529["Segment
[1717, 1847, 5]"] + 530["Segment
[1717, 1847, 5]"] 531[Solid2d] end subgraph path553 [Path] - 553["Path
[1685, 1709, 4]"] + 553["Path
[1685, 1709, 5]"] end subgraph path554 [Path] - 554["Path
[1717, 1847, 4]"] - 555["Segment
[1717, 1847, 4]"] - 556["Segment
[1717, 1847, 4]"] - 557["Segment
[1717, 1847, 4]"] - 558["Segment
[1717, 1847, 4]"] - 559["Segment
[1717, 1847, 4]"] - 560["Segment
[1717, 1847, 4]"] - 561["Segment
[1717, 1847, 4]"] + 554["Path
[1717, 1847, 5]"] + 555["Segment
[1717, 1847, 5]"] + 556["Segment
[1717, 1847, 5]"] + 557["Segment
[1717, 1847, 5]"] + 558["Segment
[1717, 1847, 5]"] + 559["Segment
[1717, 1847, 5]"] + 560["Segment
[1717, 1847, 5]"] + 561["Segment
[1717, 1847, 5]"] 562[Solid2d] end subgraph path585 [Path] - 585["Path
[2123, 2150, 4]"] - 586["Segment
[2158, 2180, 4]"] - 587["Segment
[2188, 2210, 4]"] - 588["Segment
[2218, 2240, 4]"] - 589["Segment
[2248, 2271, 4]"] - 590["Segment
[2279, 2302, 4]"] - 591["Segment
[2310, 2345, 4]"] - 592["Segment
[2353, 2360, 4]"] + 585["Path
[2123, 2150, 5]"] + 586["Segment
[2158, 2180, 5]"] + 587["Segment
[2188, 2210, 5]"] + 588["Segment
[2218, 2240, 5]"] + 589["Segment
[2248, 2271, 5]"] + 590["Segment
[2279, 2302, 5]"] + 591["Segment
[2310, 2345, 5]"] + 592["Segment
[2353, 2360, 5]"] 593[Solid2d] end subgraph path618 [Path] - 618["Path
[2632, 2661, 4]"] - 619["Segment
[2669, 2692, 4]"] - 620["Segment
[2700, 2725, 4]"] - 621["Segment
[2733, 2757, 4]"] - 622["Segment
[2765, 2789, 4]"] - 623["Segment
[2797, 2819, 4]"] - 624["Segment
[2827, 2862, 4]"] - 625["Segment
[2870, 2877, 4]"] + 618["Path
[2632, 2661, 5]"] + 619["Segment
[2669, 2692, 5]"] + 620["Segment
[2700, 2725, 5]"] + 621["Segment
[2733, 2757, 5]"] + 622["Segment
[2765, 2789, 5]"] + 623["Segment
[2797, 2819, 5]"] + 624["Segment
[2827, 2862, 5]"] + 625["Segment
[2870, 2877, 5]"] 626[Solid2d] end subgraph path650 [Path] - 650["Path
[3152, 3179, 4]"] - 651["Segment
[3187, 3206, 4]"] - 652["Segment
[3214, 3304, 4]"] + 650["Path
[3152, 3179, 5]"] + 651["Segment
[3187, 3206, 5]"] + 652["Segment
[3214, 3304, 5]"] end subgraph path654 [Path] - 654["Path
[3404, 3437, 4]"] - 655["Segment
[3445, 3464, 4]"] - 656["Segment
[3472, 3494, 4]"] - 657["Segment
[3502, 3525, 4]"] - 658["Segment
[3533, 3553, 4]"] - 659["Segment
[3561, 3585, 4]"] - 660["Segment
[3593, 3616, 4]"] - 661["Segment
[3624, 3631, 4]"] + 654["Path
[3404, 3437, 5]"] + 655["Segment
[3445, 3464, 5]"] + 656["Segment
[3472, 3494, 5]"] + 657["Segment
[3502, 3525, 5]"] + 658["Segment
[3533, 3553, 5]"] + 659["Segment
[3561, 3585, 5]"] + 660["Segment
[3593, 3616, 5]"] + 661["Segment
[3624, 3631, 5]"] 662[Solid2d] end subgraph path688 [Path] - 688["Path
[3152, 3179, 4]"] - 689["Segment
[3187, 3206, 4]"] - 690["Segment
[3214, 3304, 4]"] + 688["Path
[3152, 3179, 5]"] + 689["Segment
[3187, 3206, 5]"] + 690["Segment
[3214, 3304, 5]"] end subgraph path692 [Path] - 692["Path
[3404, 3437, 4]"] - 693["Segment
[3445, 3464, 4]"] - 694["Segment
[3472, 3494, 4]"] - 695["Segment
[3502, 3525, 4]"] - 696["Segment
[3533, 3553, 4]"] - 697["Segment
[3561, 3585, 4]"] - 698["Segment
[3593, 3616, 4]"] - 699["Segment
[3624, 3631, 4]"] + 692["Path
[3404, 3437, 5]"] + 693["Segment
[3445, 3464, 5]"] + 694["Segment
[3472, 3494, 5]"] + 695["Segment
[3502, 3525, 5]"] + 696["Segment
[3533, 3553, 5]"] + 697["Segment
[3561, 3585, 5]"] + 698["Segment
[3593, 3616, 5]"] + 699["Segment
[3624, 3631, 5]"] 700[Solid2d] end - 1["Plane
[333, 353, 4]"] - 25["Sweep Extrusion
[1379, 1417, 4]"] + 1["Plane
[333, 353, 5]"] + 25["Sweep Extrusion
[1379, 1417, 5]"] 26[Wall] 27[Wall] 28[Wall] @@ -296,8 +296,8 @@ flowchart LR 85["SweepEdge Adjacent"] 86["SweepEdge Opposite"] 87["SweepEdge Adjacent"] - 88["Plane
[333, 353, 4]"] - 112["Sweep Extrusion
[1455, 1494, 4]"] + 88["Plane
[333, 353, 5]"] + 112["Sweep Extrusion
[1455, 1494, 5]"] 113[Wall] 114[Wall] 115[Wall] @@ -361,7 +361,7 @@ flowchart LR 173["SweepEdge Opposite"] 174["SweepEdge Adjacent"] 175["Plane
[823, 865, 0]"] - 199["Sweep Extrusion
[1379, 1417, 4]"] + 199["Sweep Extrusion
[1379, 1417, 5]"] 200[Wall] 201[Wall] 202[Wall] @@ -424,7 +424,7 @@ flowchart LR 259["SweepEdge Adjacent"] 260["SweepEdge Opposite"] 261["SweepEdge Adjacent"] - 285["Sweep Extrusion
[1455, 1494, 4]"] + 285["Sweep Extrusion
[1455, 1494, 5]"] 286[Wall] 287[Wall] 288[Wall] @@ -488,7 +488,7 @@ flowchart LR 346["SweepEdge Opposite"] 347["SweepEdge Adjacent"] 348["Plane
[875, 916, 0]"] - 372["Sweep Extrusion
[1379, 1417, 4]"] + 372["Sweep Extrusion
[1379, 1417, 5]"] 373[Wall] 374[Wall] 375[Wall] @@ -551,7 +551,7 @@ flowchart LR 432["SweepEdge Adjacent"] 433["SweepEdge Opposite"] 434["SweepEdge Adjacent"] - 458["Sweep Extrusion
[1455, 1494, 4]"] + 458["Sweep Extrusion
[1455, 1494, 5]"] 459[Wall] 460[Wall] 461[Wall] @@ -615,7 +615,7 @@ flowchart LR 519["SweepEdge Opposite"] 520["SweepEdge Adjacent"] 521["Plane
[975, 1017, 0]"] - 532["Sweep Extrusion
[1949, 1973, 4]"] + 532["Sweep Extrusion
[1949, 1973, 5]"] 533[Wall] 534[Wall] 535[Wall] @@ -636,7 +636,7 @@ flowchart LR 550["SweepEdge Adjacent"] 551["SweepEdge Opposite"] 552["SweepEdge Adjacent"] - 563["Sweep Extrusion
[2015, 2039, 4]"] + 563["Sweep Extrusion
[2015, 2039, 5]"] 564[Wall] 565[Wall] 566[Wall] @@ -658,7 +658,7 @@ flowchart LR 582["SweepEdge Opposite"] 583["SweepEdge Adjacent"] 584["Plane
[1068, 1135, 0]"] - 594["Sweep Extrusion
[2523, 2547, 4]"] + 594["Sweep Extrusion
[2523, 2547, 5]"] 595[Wall] 596[Wall] 597[Wall] @@ -679,10 +679,10 @@ flowchart LR 612["SweepEdge Adjacent"] 613["SweepEdge Opposite"] 614["SweepEdge Adjacent"] - 615["Sweep Extrusion
[2523, 2547, 4]"] - 616["Sweep Extrusion
[2523, 2547, 4]"] + 615["Sweep Extrusion
[2523, 2547, 5]"] + 616["Sweep Extrusion
[2523, 2547, 5]"] 617["Plane
[1205, 1272, 0]"] - 627["Sweep Extrusion
[3047, 3071, 4]"] + 627["Sweep Extrusion
[3047, 3071, 5]"] 628[Wall] 629[Wall] 630[Wall] @@ -703,10 +703,10 @@ flowchart LR 645["SweepEdge Adjacent"] 646["SweepEdge Opposite"] 647["SweepEdge Adjacent"] - 648["Sweep Extrusion
[3047, 3071, 4]"] - 649["Plane
[3712, 3747, 4]"] - 653["Plane
[3778, 3807, 4]"] - 663["Sweep Sweep
[3819, 3846, 4]"] + 648["Sweep Extrusion
[3047, 3071, 5]"] + 649["Plane
[3712, 3747, 5]"] + 653["Plane
[3778, 3807, 5]"] + 663["Sweep Sweep
[3819, 3846, 5]"] 664[Wall] 665[Wall] 666[Wall] @@ -730,9 +730,9 @@ flowchart LR 684["SweepEdge Adjacent"] 685["SweepEdge Opposite"] 686["SweepEdge Adjacent"] - 687["Plane
[3712, 3747, 4]"] - 691["Plane
[3778, 3807, 4]"] - 701["Sweep Sweep
[3819, 3846, 4]"] + 687["Plane
[3712, 3747, 5]"] + 691["Plane
[3778, 3807, 5]"] + 701["Sweep Sweep
[3819, 3846, 5]"] 702[Wall] 703[Wall] 704[Wall] @@ -756,18 +756,18 @@ flowchart LR 722["SweepEdge Adjacent"] 723["SweepEdge Opposite"] 724["SweepEdge Adjacent"] - 725["StartSketchOnPlane
[333, 353, 4]"] - 726["StartSketchOnPlane
[333, 353, 4]"] - 727["StartSketchOnPlane
[333, 353, 4]"] - 728["StartSketchOnPlane
[333, 353, 4]"] - 729["StartSketchOnPlane
[1657, 1677, 4]"] - 730["StartSketchOnPlane
[1657, 1677, 4]"] - 731["StartSketchOnPlane
[2095, 2115, 4]"] - 732["StartSketchOnPlane
[2604, 2624, 4]"] - 733["StartSketchOnPlane
[3124, 3144, 4]"] - 734["StartSketchOnPlane
[3376, 3396, 4]"] - 735["StartSketchOnPlane
[3124, 3144, 4]"] - 736["StartSketchOnPlane
[3376, 3396, 4]"] + 725["StartSketchOnPlane
[333, 353, 5]"] + 726["StartSketchOnPlane
[333, 353, 5]"] + 727["StartSketchOnPlane
[333, 353, 5]"] + 728["StartSketchOnPlane
[333, 353, 5]"] + 729["StartSketchOnPlane
[1657, 1677, 5]"] + 730["StartSketchOnPlane
[1657, 1677, 5]"] + 731["StartSketchOnPlane
[2095, 2115, 5]"] + 732["StartSketchOnPlane
[2604, 2624, 5]"] + 733["StartSketchOnPlane
[3124, 3144, 5]"] + 734["StartSketchOnPlane
[3376, 3396, 5]"] + 735["StartSketchOnPlane
[3124, 3144, 5]"] + 736["StartSketchOnPlane
[3376, 3396, 5]"] 1 --- 2 2 --- 3 2 --- 4 diff --git a/rust/kcl-lib/tests/kcl_samples/bench/ops.snap b/rust/kcl-lib/tests/kcl_samples/bench/ops.snap index 080fe4fc1..3b7561f6c 100644 --- a/rust/kcl-lib/tests/kcl_samples/bench/ops.snap +++ b/rust/kcl-lib/tests/kcl_samples/bench/ops.snap @@ -9,7 +9,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 1331, 1606, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -21,7 +21,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 309, 1312, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -77,7 +77,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 309, 1312, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -248,7 +248,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 1331, 1606, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -260,7 +260,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 309, 1312, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -316,7 +316,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 309, 1312, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -487,7 +487,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 1331, 1606, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -499,7 +499,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 309, 1312, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -555,7 +555,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 309, 1312, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -726,7 +726,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 1889, 2052, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -738,7 +738,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 1626, 1868, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -800,7 +800,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 1626, 1868, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -889,7 +889,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 2474, 2560, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -901,7 +901,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 2071, 2453, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -1007,7 +1007,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 2993, 3084, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -1019,7 +1019,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 2580, 2972, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -1095,7 +1095,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 3671, 3859, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -1131,7 +1131,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 3100, 3325, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -1191,7 +1191,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 3344, 3652, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -1249,7 +1249,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 3671, 3859, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -1285,7 +1285,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 3100, 3325, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -1345,7 +1345,7 @@ description: Operations executed bench.kcl "functionSourceRange": [ 3344, 3652, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, diff --git a/rust/kcl-lib/tests/kcl_samples/bracket/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/bracket/artifact_commands.snap index e170b95b0..fa6610892 100644 --- a/rust/kcl-lib/tests/kcl_samples/bracket/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/bracket/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands bracket.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/artifact_commands.snap index 5df351670..279904952 100644 --- a/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands car-wheel-assembly.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/artifact_graph_flowchart.snap.md index f2ee384f1..66a0ae42b 100644 --- a/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/artifact_graph_flowchart.snap.md @@ -1,264 +1,264 @@ ```mermaid flowchart LR subgraph path2 [Path] - 2["Path
[567, 618, 5]"] - 3["Segment
[567, 618, 5]"] + 2["Path
[567, 618, 6]"] + 3["Segment
[567, 618, 6]"] 4[Solid2d] end subgraph path11 [Path] - 11["Path
[803, 859, 5]"] - 12["Segment
[803, 859, 5]"] + 11["Path
[803, 859, 6]"] + 12["Segment
[803, 859, 6]"] 13[Solid2d] end subgraph path19 [Path] - 19["Path
[984, 1037, 5]"] - 20["Segment
[984, 1037, 5]"] + 19["Path
[984, 1037, 6]"] + 20["Segment
[984, 1037, 6]"] 21[Solid2d] end subgraph path30 [Path] - 30["Path
[1420, 1460, 5]"] - 31["Segment
[1420, 1460, 5]"] + 30["Path
[1420, 1460, 6]"] + 31["Segment
[1420, 1460, 6]"] 32[Solid2d] end subgraph path38 [Path] - 38["Path
[1564, 1615, 5]"] - 39["Segment
[1564, 1615, 5]"] + 38["Path
[1564, 1615, 6]"] + 39["Segment
[1564, 1615, 6]"] 40[Solid2d] end subgraph path47 [Path] - 47["Path
[1748, 1801, 5]"] - 48["Segment
[1748, 1801, 5]"] + 47["Path
[1748, 1801, 6]"] + 48["Segment
[1748, 1801, 6]"] 49[Solid2d] end subgraph path58 [Path] - 58["Path
[2044, 2116, 5]"] - 59["Segment
[2044, 2116, 5]"] + 58["Path
[2044, 2116, 6]"] + 59["Segment
[2044, 2116, 6]"] 60[Solid2d] end subgraph path81 [Path] - 81["Path
[2373, 2404, 5]"] - 82["Segment
[2410, 2430, 5]"] - 83["Segment
[2436, 2456, 5]"] - 84["Segment
[2462, 2483, 5]"] - 85["Segment
[2489, 2545, 5]"] - 86["Segment
[2551, 2558, 5]"] + 81["Path
[2373, 2404, 6]"] + 82["Segment
[2410, 2430, 6]"] + 83["Segment
[2436, 2456, 6]"] + 84["Segment
[2462, 2483, 6]"] + 85["Segment
[2489, 2545, 6]"] + 86["Segment
[2551, 2558, 6]"] 87[Solid2d] end subgraph path106 [Path] - 106["Path
[2860, 2892, 5]"] - 107["Segment
[2898, 2919, 5]"] - 108["Segment
[2925, 2945, 5]"] - 109["Segment
[2951, 2971, 5]"] - 110["Segment
[2977, 3033, 5]"] - 111["Segment
[3039, 3046, 5]"] + 106["Path
[2860, 2892, 6]"] + 107["Segment
[2898, 2919, 6]"] + 108["Segment
[2925, 2945, 6]"] + 109["Segment
[2951, 2971, 6]"] + 110["Segment
[2977, 3033, 6]"] + 111["Segment
[3039, 3046, 6]"] 112[Solid2d] end subgraph path132 [Path] - 132["Path
[350, 406, 4]"] - 133["Segment
[350, 406, 4]"] + 132["Path
[350, 406, 5]"] + 133["Segment
[350, 406, 5]"] 134[Solid2d] end subgraph path135 [Path] - 135["Path
[417, 473, 4]"] - 136["Segment
[417, 473, 4]"] + 135["Path
[417, 473, 5]"] + 136["Segment
[417, 473, 5]"] 137[Solid2d] end subgraph path144 [Path] - 144["Path
[638, 694, 4]"] - 145["Segment
[638, 694, 4]"] + 144["Path
[638, 694, 5]"] + 145["Segment
[638, 694, 5]"] 146[Solid2d] end subgraph path147 [Path] - 147["Path
[705, 761, 4]"] - 148["Segment
[705, 761, 4]"] + 147["Path
[705, 761, 5]"] + 148["Segment
[705, 761, 5]"] 149[Solid2d] end subgraph path156 [Path] - 156["Path
[905, 959, 4]"] - 157["Segment
[905, 959, 4]"] + 156["Path
[905, 959, 5]"] + 157["Segment
[905, 959, 5]"] 158[Solid2d] end subgraph path167 [Path] - 167["Path
[1237, 1297, 4]"] - 168["Segment
[1237, 1297, 4]"] + 167["Path
[1237, 1297, 5]"] + 168["Segment
[1237, 1297, 5]"] 169[Solid2d] end subgraph path179 [Path] - 179["Path
[1655, 1701, 4]"] - 180["Segment
[1707, 1759, 4]"] - 181["Segment
[1765, 1870, 4]"] - 182["Segment
[1876, 1898, 4]"] - 183["Segment
[1904, 1960, 4]"] - 184["Segment
[1966, 1973, 4]"] + 179["Path
[1655, 1701, 5]"] + 180["Segment
[1707, 1759, 5]"] + 181["Segment
[1765, 1870, 5]"] + 182["Segment
[1876, 1898, 5]"] + 183["Segment
[1904, 1960, 5]"] + 184["Segment
[1966, 1973, 5]"] 185[Solid2d] end subgraph path195 [Path] - 195["Path
[2107, 2153, 4]"] - 196["Segment
[2159, 2211, 4]"] - 197["Segment
[2217, 2324, 4]"] - 198["Segment
[2330, 2367, 4]"] - 199["Segment
[2373, 2429, 4]"] - 200["Segment
[2435, 2442, 4]"] + 195["Path
[2107, 2153, 5]"] + 196["Segment
[2159, 2211, 5]"] + 197["Segment
[2217, 2324, 5]"] + 198["Segment
[2330, 2367, 5]"] + 199["Segment
[2373, 2429, 5]"] + 200["Segment
[2435, 2442, 5]"] 201[Solid2d] end subgraph path212 [Path] - 212["Path
[2953, 3000, 4]"] - 213["Segment
[3008, 3348, 4]"] - 214["Segment
[3356, 3388, 4]"] - 215["Segment
[3396, 3740, 4]"] - 216["Segment
[3748, 3804, 4]"] - 217["Segment
[3812, 3819, 4]"] + 212["Path
[2953, 3000, 5]"] + 213["Segment
[3008, 3348, 5]"] + 214["Segment
[3356, 3388, 5]"] + 215["Segment
[3396, 3740, 5]"] + 216["Segment
[3748, 3804, 5]"] + 217["Segment
[3812, 3819, 5]"] 218[Solid2d] end subgraph path235 [Path] - 235["Path
[2953, 3000, 4]"] - 236["Segment
[3008, 3348, 4]"] - 237["Segment
[3356, 3388, 4]"] - 238["Segment
[3396, 3740, 4]"] - 239["Segment
[3748, 3804, 4]"] - 240["Segment
[3812, 3819, 4]"] + 235["Path
[2953, 3000, 5]"] + 236["Segment
[3008, 3348, 5]"] + 237["Segment
[3356, 3388, 5]"] + 238["Segment
[3396, 3740, 5]"] + 239["Segment
[3748, 3804, 5]"] + 240["Segment
[3812, 3819, 5]"] 241[Solid2d] end subgraph path258 [Path] - 258["Path
[4347, 4442, 4]"] - 259["Segment
[4448, 4481, 4]"] - 260["Segment
[4487, 4538, 4]"] - 261["Segment
[4544, 4577, 4]"] - 262["Segment
[4583, 4633, 4]"] - 263["Segment
[4639, 4680, 4]"] - 264["Segment
[4686, 4735, 4]"] - 265["Segment
[4741, 4774, 4]"] - 266["Segment
[4780, 4814, 4]"] - 267["Segment
[4820, 4854, 4]"] - 268["Segment
[4860, 4912, 4]"] - 269["Segment
[4918, 4952, 4]"] - 270["Segment
[4958, 5034, 4]"] - 271["Segment
[5040, 5073, 4]"] - 272["Segment
[5079, 5155, 4]"] - 273["Segment
[5161, 5195, 4]"] - 274["Segment
[5201, 5275, 4]"] - 275["Segment
[5281, 5315, 4]"] - 276["Segment
[5321, 5372, 4]"] - 277["Segment
[5378, 5440, 4]"] - 278["Segment
[5446, 5497, 4]"] - 279["Segment
[5503, 5537, 4]"] - 280["Segment
[5543, 5576, 4]"] - 281["Segment
[5582, 5615, 4]"] - 282["Segment
[5621, 5628, 4]"] + 258["Path
[4347, 4442, 5]"] + 259["Segment
[4448, 4481, 5]"] + 260["Segment
[4487, 4538, 5]"] + 261["Segment
[4544, 4577, 5]"] + 262["Segment
[4583, 4633, 5]"] + 263["Segment
[4639, 4680, 5]"] + 264["Segment
[4686, 4735, 5]"] + 265["Segment
[4741, 4774, 5]"] + 266["Segment
[4780, 4814, 5]"] + 267["Segment
[4820, 4854, 5]"] + 268["Segment
[4860, 4912, 5]"] + 269["Segment
[4918, 4952, 5]"] + 270["Segment
[4958, 5034, 5]"] + 271["Segment
[5040, 5073, 5]"] + 272["Segment
[5079, 5155, 5]"] + 273["Segment
[5161, 5195, 5]"] + 274["Segment
[5201, 5275, 5]"] + 275["Segment
[5281, 5315, 5]"] + 276["Segment
[5321, 5372, 5]"] + 277["Segment
[5378, 5440, 5]"] + 278["Segment
[5446, 5497, 5]"] + 279["Segment
[5503, 5537, 5]"] + 280["Segment
[5543, 5576, 5]"] + 281["Segment
[5582, 5615, 5]"] + 282["Segment
[5621, 5628, 5]"] 283[Solid2d] end subgraph path334 [Path] - 334["Path
[740, 780, 7]"] - 335["Segment
[788, 850, 7]"] - 336["Segment
[858, 894, 7]"] - 337["Segment
[902, 932, 7]"] - 338["Segment
[940, 992, 7]"] - 339["Segment
[1000, 1040, 7]"] - 340["Segment
[1048, 1083, 7]"] - 341["Segment
[1091, 1129, 7]"] - 342["Segment
[1137, 1159, 7]"] - 343["Segment
[1167, 1174, 7]"] + 334["Path
[740, 780, 8]"] + 335["Segment
[788, 850, 8]"] + 336["Segment
[858, 894, 8]"] + 337["Segment
[902, 932, 8]"] + 338["Segment
[940, 992, 8]"] + 339["Segment
[1000, 1040, 8]"] + 340["Segment
[1048, 1083, 8]"] + 341["Segment
[1091, 1129, 8]"] + 342["Segment
[1137, 1159, 8]"] + 343["Segment
[1167, 1174, 8]"] 344[Solid2d] end subgraph path365 [Path] - 365["Path
[507, 588, 6]"] - 366["Segment
[594, 695, 6]"] - 367["Segment
[701, 786, 6]"] - 368["Segment
[792, 876, 6]"] - 369["Segment
[882, 968, 6]"] - 370["Segment
[974, 1059, 6]"] - 371["Segment
[1065, 1151, 6]"] - 372["Segment
[1157, 1280, 6]"] - 373["Segment
[1286, 1372, 6]"] - 374["Segment
[1378, 1513, 6]"] - 375["Segment
[1519, 1605, 6]"] - 376["Segment
[1611, 1735, 6]"] - 377["Segment
[1741, 1827, 6]"] - 378["Segment
[1833, 1918, 6]"] - 379["Segment
[1924, 2010, 6]"] - 380["Segment
[2016, 2101, 6]"] - 381["Segment
[2107, 2192, 6]"] - 382["Segment
[2198, 2205, 6]"] + 365["Path
[507, 588, 7]"] + 366["Segment
[594, 695, 7]"] + 367["Segment
[701, 786, 7]"] + 368["Segment
[792, 876, 7]"] + 369["Segment
[882, 968, 7]"] + 370["Segment
[974, 1059, 7]"] + 371["Segment
[1065, 1151, 7]"] + 372["Segment
[1157, 1280, 7]"] + 373["Segment
[1286, 1372, 7]"] + 374["Segment
[1378, 1513, 7]"] + 375["Segment
[1519, 1605, 7]"] + 376["Segment
[1611, 1735, 7]"] + 377["Segment
[1741, 1827, 7]"] + 378["Segment
[1833, 1918, 7]"] + 379["Segment
[1924, 2010, 7]"] + 380["Segment
[2016, 2101, 7]"] + 381["Segment
[2107, 2192, 7]"] + 382["Segment
[2198, 2205, 7]"] 383[Solid2d] end subgraph path439 [Path] - 439["Path
[483, 540, 8]"] - 440["Segment
[546, 680, 8]"] - 441["Segment
[686, 741, 8]"] - 442["Segment
[747, 844, 8]"] - 443["Segment
[850, 882, 8]"] - 444["Segment
[888, 920, 8]"] - 445["Segment
[926, 957, 8]"] - 446["Segment
[963, 1078, 8]"] - 447["Segment
[1084, 1116, 8]"] - 448["Segment
[1122, 1154, 8]"] - 449["Segment
[1160, 1191, 8]"] - 450["Segment
[1197, 1290, 8]"] - 451["Segment
[1296, 1351, 8]"] - 452["Segment
[1357, 1430, 8]"] - 453["Segment
[1436, 1443, 8]"] + 439["Path
[483, 540, 9]"] + 440["Segment
[546, 680, 9]"] + 441["Segment
[686, 741, 9]"] + 442["Segment
[747, 844, 9]"] + 443["Segment
[850, 882, 9]"] + 444["Segment
[888, 920, 9]"] + 445["Segment
[926, 957, 9]"] + 446["Segment
[963, 1078, 9]"] + 447["Segment
[1084, 1116, 9]"] + 448["Segment
[1122, 1154, 9]"] + 449["Segment
[1160, 1191, 9]"] + 450["Segment
[1197, 1290, 9]"] + 451["Segment
[1296, 1351, 9]"] + 452["Segment
[1357, 1430, 9]"] + 453["Segment
[1436, 1443, 9]"] 454[Solid2d] end - 1["Plane
[544, 561, 5]"] - 5["Sweep Extrusion
[627, 683, 5]"] + 1["Plane
[544, 561, 6]"] + 5["Sweep Extrusion
[627, 683, 6]"] 6[Wall] 7["Cap Start"] 8["Cap End"] 9["SweepEdge Opposite"] 10["SweepEdge Adjacent"] - 14["Sweep Extrusion
[872, 934, 5]"] + 14["Sweep Extrusion
[872, 934, 6]"] 15[Wall] 16["Cap End"] 17["SweepEdge Opposite"] 18["SweepEdge Adjacent"] - 22["Sweep Extrusion
[1184, 1263, 5]"] + 22["Sweep Extrusion
[1184, 1263, 6]"] 23[Wall] 24["SweepEdge Opposite"] 25["SweepEdge Adjacent"] - 26["Sweep Extrusion
[1184, 1263, 5]"] - 27["Sweep Extrusion
[1184, 1263, 5]"] - 28["Sweep Extrusion
[1184, 1263, 5]"] - 29["Sweep Extrusion
[1184, 1263, 5]"] - 33["Sweep Extrusion
[1466, 1499, 5]"] + 26["Sweep Extrusion
[1184, 1263, 6]"] + 27["Sweep Extrusion
[1184, 1263, 6]"] + 28["Sweep Extrusion
[1184, 1263, 6]"] + 29["Sweep Extrusion
[1184, 1263, 6]"] + 33["Sweep Extrusion
[1466, 1499, 6]"] 34[Wall] 35["Cap End"] 36["SweepEdge Opposite"] 37["SweepEdge Adjacent"] - 41["Sweep Extrusion
[1630, 1695, 5]"] + 41["Sweep Extrusion
[1630, 1695, 6]"] 42[Wall] 43["Cap Start"] 44["Cap End"] 45["SweepEdge Opposite"] 46["SweepEdge Adjacent"] - 50["Sweep Extrusion
[1948, 1992, 5]"] + 50["Sweep Extrusion
[1948, 1992, 6]"] 51[Wall] 52["SweepEdge Opposite"] 53["SweepEdge Adjacent"] - 54["Sweep Extrusion
[1948, 1992, 5]"] - 55["Sweep Extrusion
[1948, 1992, 5]"] - 56["Sweep Extrusion
[1948, 1992, 5]"] - 57["Sweep Extrusion
[1948, 1992, 5]"] - 61["Sweep Extrusion
[2271, 2315, 5]"] + 54["Sweep Extrusion
[1948, 1992, 6]"] + 55["Sweep Extrusion
[1948, 1992, 6]"] + 56["Sweep Extrusion
[1948, 1992, 6]"] + 57["Sweep Extrusion
[1948, 1992, 6]"] + 61["Sweep Extrusion
[2271, 2315, 6]"] 62[Wall] 63["Cap End"] 64["SweepEdge Opposite"] 65["SweepEdge Adjacent"] - 66["Sweep Extrusion
[2271, 2315, 5]"] - 67["Sweep Extrusion
[2271, 2315, 5]"] - 68["Sweep Extrusion
[2271, 2315, 5]"] - 69["Sweep Extrusion
[2271, 2315, 5]"] - 70["Sweep Extrusion
[2271, 2315, 5]"] - 71["Sweep Extrusion
[2271, 2315, 5]"] - 72["Sweep Extrusion
[2271, 2315, 5]"] - 73["Sweep Extrusion
[2271, 2315, 5]"] - 74["Sweep Extrusion
[2271, 2315, 5]"] - 75["Sweep Extrusion
[2271, 2315, 5]"] - 76["Sweep Extrusion
[2271, 2315, 5]"] - 77["Sweep Extrusion
[2271, 2315, 5]"] - 78["Sweep Extrusion
[2271, 2315, 5]"] - 79["Sweep Extrusion
[2271, 2315, 5]"] - 80["Sweep Extrusion
[2271, 2315, 5]"] - 88["Sweep Extrusion
[2724, 2792, 5]"] + 66["Sweep Extrusion
[2271, 2315, 6]"] + 67["Sweep Extrusion
[2271, 2315, 6]"] + 68["Sweep Extrusion
[2271, 2315, 6]"] + 69["Sweep Extrusion
[2271, 2315, 6]"] + 70["Sweep Extrusion
[2271, 2315, 6]"] + 71["Sweep Extrusion
[2271, 2315, 6]"] + 72["Sweep Extrusion
[2271, 2315, 6]"] + 73["Sweep Extrusion
[2271, 2315, 6]"] + 74["Sweep Extrusion
[2271, 2315, 6]"] + 75["Sweep Extrusion
[2271, 2315, 6]"] + 76["Sweep Extrusion
[2271, 2315, 6]"] + 77["Sweep Extrusion
[2271, 2315, 6]"] + 78["Sweep Extrusion
[2271, 2315, 6]"] + 79["Sweep Extrusion
[2271, 2315, 6]"] + 80["Sweep Extrusion
[2271, 2315, 6]"] + 88["Sweep Extrusion
[2724, 2792, 6]"] 89[Wall] 90[Wall] 91[Wall] @@ -272,11 +272,11 @@ flowchart LR 99["SweepEdge Adjacent"] 100["SweepEdge Opposite"] 101["SweepEdge Adjacent"] - 102["Sweep Extrusion
[2724, 2792, 5]"] - 103["Sweep Extrusion
[2724, 2792, 5]"] - 104["Sweep Extrusion
[2724, 2792, 5]"] - 105["Sweep Extrusion
[2724, 2792, 5]"] - 113["Sweep Extrusion
[3198, 3272, 5]"] + 102["Sweep Extrusion
[2724, 2792, 6]"] + 103["Sweep Extrusion
[2724, 2792, 6]"] + 104["Sweep Extrusion
[2724, 2792, 6]"] + 105["Sweep Extrusion
[2724, 2792, 6]"] + 113["Sweep Extrusion
[3198, 3272, 6]"] 114[Wall] 115[Wall] 116[Wall] @@ -290,41 +290,41 @@ flowchart LR 124["SweepEdge Adjacent"] 125["SweepEdge Opposite"] 126["SweepEdge Adjacent"] - 127["Sweep Extrusion
[3198, 3272, 5]"] - 128["Sweep Extrusion
[3198, 3272, 5]"] - 129["Sweep Extrusion
[3198, 3272, 5]"] - 130["Sweep Extrusion
[3198, 3272, 5]"] - 131["Plane
[327, 344, 4]"] - 138["Sweep Extrusion
[483, 516, 4]"] + 127["Sweep Extrusion
[3198, 3272, 6]"] + 128["Sweep Extrusion
[3198, 3272, 6]"] + 129["Sweep Extrusion
[3198, 3272, 6]"] + 130["Sweep Extrusion
[3198, 3272, 6]"] + 131["Plane
[327, 344, 5]"] + 138["Sweep Extrusion
[483, 516, 5]"] 139[Wall] 140["Cap Start"] 141["Cap End"] 142["SweepEdge Opposite"] 143["SweepEdge Adjacent"] - 150["Sweep Extrusion
[771, 804, 4]"] + 150["Sweep Extrusion
[771, 804, 5]"] 151[Wall] 152["Cap Start"] 153["Cap End"] 154["SweepEdge Opposite"] 155["SweepEdge Adjacent"] - 159["Sweep Extrusion
[1106, 1140, 4]"] + 159["Sweep Extrusion
[1106, 1140, 5]"] 160[Wall] 161["SweepEdge Opposite"] 162["SweepEdge Adjacent"] - 163["Sweep Extrusion
[1106, 1140, 4]"] - 164["Sweep Extrusion
[1106, 1140, 4]"] - 165["Sweep Extrusion
[1106, 1140, 4]"] - 166["Sweep Extrusion
[1106, 1140, 4]"] - 170["Sweep Extrusion
[1444, 1478, 4]"] + 163["Sweep Extrusion
[1106, 1140, 5]"] + 164["Sweep Extrusion
[1106, 1140, 5]"] + 165["Sweep Extrusion
[1106, 1140, 5]"] + 166["Sweep Extrusion
[1106, 1140, 5]"] + 170["Sweep Extrusion
[1444, 1478, 5]"] 171[Wall] 172["SweepEdge Opposite"] 173["SweepEdge Adjacent"] - 174["Sweep Extrusion
[1444, 1478, 4]"] - 175["Sweep Extrusion
[1444, 1478, 4]"] - 176["Sweep Extrusion
[1444, 1478, 4]"] - 177["Sweep Extrusion
[1444, 1478, 4]"] - 178["Plane
[1632, 1649, 4]"] - 186["Sweep Revolve
[1979, 1998, 4]"] + 174["Sweep Extrusion
[1444, 1478, 5]"] + 175["Sweep Extrusion
[1444, 1478, 5]"] + 176["Sweep Extrusion
[1444, 1478, 5]"] + 177["Sweep Extrusion
[1444, 1478, 5]"] + 178["Plane
[1632, 1649, 5]"] + 186["Sweep Revolve
[1979, 1998, 5]"] 187[Wall] 188[Wall] 189[Wall] @@ -332,8 +332,8 @@ flowchart LR 191["SweepEdge Adjacent"] 192["SweepEdge Adjacent"] 193["SweepEdge Adjacent"] - 194["Plane
[2084, 2101, 4]"] - 202["Sweep Revolve
[2448, 2467, 4]"] + 194["Plane
[2084, 2101, 5]"] + 202["Sweep Revolve
[2448, 2467, 5]"] 203[Wall] 204[Wall] 205[Wall] @@ -342,8 +342,8 @@ flowchart LR 208["SweepEdge Adjacent"] 209["SweepEdge Adjacent"] 210["SweepEdge Adjacent"] - 211["Plane
[2922, 2945, 4]"] - 219["Sweep Extrusion
[3867, 3913, 4]"] + 211["Plane
[2922, 2945, 5]"] + 219["Sweep Extrusion
[3867, 3913, 5]"] 220[Wall] 221[Wall] 222[Wall] @@ -358,8 +358,8 @@ flowchart LR 231["SweepEdge Adjacent"] 232["SweepEdge Opposite"] 233["SweepEdge Adjacent"] - 234["Plane
[2922, 2945, 4]"] - 242["Sweep Extrusion
[3867, 3913, 4]"] + 234["Plane
[2922, 2945, 5]"] + 242["Sweep Extrusion
[3867, 3913, 5]"] 243[Wall] 244[Wall] 245[Wall] @@ -374,8 +374,8 @@ flowchart LR 254["SweepEdge Adjacent"] 255["SweepEdge Opposite"] 256["SweepEdge Adjacent"] - 257["Plane
[4324, 4341, 4]"] - 284["Sweep Revolve
[5634, 5653, 4]"] + 257["Plane
[4324, 4341, 5]"] + 284["Sweep Revolve
[5634, 5653, 5]"] 285[Wall] 286[Wall] 287[Wall] @@ -424,8 +424,8 @@ flowchart LR 330["SweepEdge Adjacent"] 331["SweepEdge Adjacent"] 332["SweepEdge Adjacent"] - 333["Plane
[706, 732, 7]"] - 345["Sweep Revolve
[1182, 1201, 7]"] + 333["Plane
[706, 732, 8]"] + 345["Sweep Revolve
[1182, 1201, 8]"] 346[Wall] 347[Wall] 348[Wall] @@ -444,8 +444,8 @@ flowchart LR 361["SweepEdge Adjacent"] 362["SweepEdge Adjacent"] 363["SweepEdge Adjacent"] - 364["Plane
[484, 501, 6]"] - 384["Sweep Revolve
[2243, 2295, 6]"] + 364["Plane
[484, 501, 7]"] + 384["Sweep Revolve
[2243, 2295, 7]"] 385[Wall] 386[Wall] 387[Wall] @@ -499,8 +499,8 @@ flowchart LR 435["SweepEdge Adjacent"] 436["SweepEdge Opposite"] 437["SweepEdge Adjacent"] - 438["Plane
[460, 477, 8]"] - 455["Sweep Revolve
[1486, 1517, 8]"] + 438["Plane
[460, 477, 9]"] + 455["Sweep Revolve
[1486, 1517, 9]"] 456[Wall] 457[Wall] 458[Wall] @@ -529,17 +529,17 @@ flowchart LR 481["SweepEdge Adjacent"] 482["SweepEdge Adjacent"] 483["SweepEdge Adjacent"] - 484["StartSketchOnFace
[770, 797, 5]"] - 485["StartSketchOnFace
[947, 978, 5]"] - 486["StartSketchOnFace
[1385, 1414, 5]"] - 487["StartSketchOnFace
[1524, 1558, 5]"] - 488["StartSketchOnFace
[1709, 1742, 5]"] - 489["StartSketchOnFace
[2009, 2038, 5]"] - 490["StartSketchOnFace
[2338, 2367, 5]"] - 491["StartSketchOnFace
[2821, 2854, 5]"] - 492["StartSketchOnFace
[603, 632, 4]"] - 493["StartSketchOnFace
[865, 899, 4]"] - 494["StartSketchOnFace
[1202, 1231, 4]"] + 484["StartSketchOnFace
[770, 797, 6]"] + 485["StartSketchOnFace
[947, 978, 6]"] + 486["StartSketchOnFace
[1385, 1414, 6]"] + 487["StartSketchOnFace
[1524, 1558, 6]"] + 488["StartSketchOnFace
[1709, 1742, 6]"] + 489["StartSketchOnFace
[2009, 2038, 6]"] + 490["StartSketchOnFace
[2338, 2367, 6]"] + 491["StartSketchOnFace
[2821, 2854, 6]"] + 492["StartSketchOnFace
[603, 632, 5]"] + 493["StartSketchOnFace
[865, 899, 5]"] + 494["StartSketchOnFace
[1202, 1231, 5]"] 1 --- 2 2 --- 3 2 ---- 5 diff --git a/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/ast.snap b/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/ast.snap index 6430c7a36..83024f310 100644 --- a/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/ast.snap +++ b/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/ast.snap @@ -168,54 +168,65 @@ description: Result of parsing car-wheel-assembly.kcl "label": { "commentStart": 366, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 378, - "elements": [ - { - "commentStart": 379, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - }, - { - "commentStart": 382, - "end": 0, - "raw": "0.5", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.5, - "suffix": "None" - } - }, - { - "commentStart": 387, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - } - ], + "commentStart": 370, "end": 0, + "raw": "0", "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 373, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 377, + "end": 0, + "raw": "0.5", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.5, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 382, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 386, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } } } ], @@ -253,14 +264,14 @@ description: Result of parsing car-wheel-assembly.kcl "type": "ExpressionStatement" }, { - "commentStart": 391, + "commentStart": 389, "end": 0, "expression": { "abs_path": false, - "commentStart": 391, + "commentStart": 389, "end": 0, "name": { - "commentStart": 391, + "commentStart": 389, "end": 0, "name": "carWheel", "start": 0, @@ -276,16 +287,16 @@ description: Result of parsing car-wheel-assembly.kcl "type": "ExpressionStatement" }, { - "commentStart": 400, + "commentStart": 398, "end": 0, "expression": { "body": [ { "abs_path": false, - "commentStart": 400, + "commentStart": 398, "end": 0, "name": { - "commentStart": 400, + "commentStart": 398, "end": 0, "name": "lugNut", "start": 0, @@ -301,14 +312,14 @@ description: Result of parsing car-wheel-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 438, + "commentStart": 436, "end": 0, "name": "arcDegrees", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 451, + "commentStart": 449, "end": 0, "raw": "360", "start": 0, @@ -323,17 +334,17 @@ description: Result of parsing car-wheel-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 463, + "commentStart": 461, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 470, + "commentStart": 468, "elements": [ { - "commentStart": 471, + "commentStart": 469, "end": 0, "raw": "0", "start": 0, @@ -345,7 +356,7 @@ description: Result of parsing car-wheel-assembly.kcl } }, { - "commentStart": 474, + "commentStart": 472, "end": 0, "raw": "1", "start": 0, @@ -357,7 +368,7 @@ description: Result of parsing car-wheel-assembly.kcl } }, { - "commentStart": 477, + "commentStart": 475, "end": 0, "raw": "0", "start": 0, @@ -378,17 +389,17 @@ description: Result of parsing car-wheel-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 488, + "commentStart": 486, "end": 0, "name": "center", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 497, + "commentStart": 495, "elements": [ { - "commentStart": 498, + "commentStart": 496, "end": 0, "raw": "0", "start": 0, @@ -400,7 +411,7 @@ description: Result of parsing car-wheel-assembly.kcl } }, { - "commentStart": 501, + "commentStart": 499, "end": 0, "raw": "0", "start": 0, @@ -412,7 +423,7 @@ description: Result of parsing car-wheel-assembly.kcl } }, { - "commentStart": 504, + "commentStart": 502, "end": 0, "raw": "0", "start": 0, @@ -433,7 +444,7 @@ description: Result of parsing car-wheel-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 515, + "commentStart": 513, "end": 0, "name": "instances", "start": 0, @@ -441,10 +452,10 @@ description: Result of parsing car-wheel-assembly.kcl }, "arg": { "abs_path": false, - "commentStart": 527, + "commentStart": 525, "end": 0, "name": { - "commentStart": 527, + "commentStart": 525, "end": 0, "name": "lugCount", "start": 0, @@ -459,14 +470,14 @@ description: Result of parsing car-wheel-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 544, + "commentStart": 542, "end": 0, "name": "rotateDuplicates", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 563, + "commentStart": 561, "end": 0, "raw": "false", "start": 0, @@ -478,10 +489,10 @@ description: Result of parsing car-wheel-assembly.kcl ], "callee": { "abs_path": false, - "commentStart": 412, + "commentStart": 410, "end": 0, "name": { - "commentStart": 412, + "commentStart": 410, "end": 0, "name": "patternCircular3d", "start": 0, @@ -491,7 +502,7 @@ description: Result of parsing car-wheel-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 412, + "commentStart": 410, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -499,7 +510,7 @@ description: Result of parsing car-wheel-assembly.kcl "unlabeled": null } ], - "commentStart": 400, + "commentStart": 398, "end": 0, "start": 0, "type": "PipeExpression", @@ -510,16 +521,16 @@ description: Result of parsing car-wheel-assembly.kcl "type": "ExpressionStatement" }, { - "commentStart": 577, + "commentStart": 575, "end": 0, "expression": { "body": [ { "abs_path": false, - "commentStart": 577, + "commentStart": 575, "end": 0, "name": { - "commentStart": 577, + "commentStart": 575, "end": 0, "name": "brakeCaliper", "start": 0, @@ -535,65 +546,76 @@ description: Result of parsing car-wheel-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 605, + "commentStart": 603, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 617, - "elements": [ - { - "commentStart": 618, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - }, - { - "commentStart": 621, - "end": 0, - "raw": "0.5", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.5, - "suffix": "None" - } - }, - { - "commentStart": 626, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - } - ], + "commentStart": 607, "end": 0, + "raw": "0", "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 610, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 614, + "end": 0, + "raw": "0.5", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.5, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 619, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 623, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } } } ], "callee": { "abs_path": false, - "commentStart": 595, + "commentStart": 593, "end": 0, "name": { - "commentStart": 595, + "commentStart": 593, "end": 0, "name": "translate", "start": 0, @@ -603,7 +625,7 @@ description: Result of parsing car-wheel-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 595, + "commentStart": 593, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -611,7 +633,7 @@ description: Result of parsing car-wheel-assembly.kcl "unlabeled": null } ], - "commentStart": 577, + "commentStart": 575, "end": 0, "start": 0, "type": "PipeExpression", @@ -622,14 +644,14 @@ description: Result of parsing car-wheel-assembly.kcl "type": "ExpressionStatement" }, { - "commentStart": 630, + "commentStart": 626, "end": 0, "expression": { "abs_path": false, - "commentStart": 630, + "commentStart": 626, "end": 0, "name": { - "commentStart": 630, + "commentStart": 626, "end": 0, "name": "carTire", "start": 0, diff --git a/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/ops.snap b/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/ops.snap index f198d3e0c..c29de27c9 100644 --- a/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/ops.snap +++ b/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/ops.snap @@ -1848,7 +1848,7 @@ description: Operations executed car-wheel-assembly.kcl "functionSourceRange": [ 2620, 4193, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -2235,7 +2235,7 @@ description: Operations executed car-wheel-assembly.kcl "functionSourceRange": [ 2620, 4193, - 4 + 5 ], "unlabeledArg": null, "labeledArgs": {}, @@ -2660,7 +2660,7 @@ description: Operations executed car-wheel-assembly.kcl "functionSourceRange": [ 664, 1291, - 7 + 8 ], "unlabeledArg": null, "labeledArgs": {}, diff --git a/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/program_memory.snap index 611ac68c3..2cbd95c37 100644 --- a/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/car-wheel-assembly/program_memory.snap @@ -5,7 +5,7 @@ description: Variables in memory after executing car-wheel-assembly.kcl { "brakeCaliper": { "type": "Module", - "value": 6 + "value": 7 }, "c1": { "type": "TagIdentifier", @@ -14,15 +14,15 @@ description: Variables in memory after executing car-wheel-assembly.kcl }, "carRotor": { "type": "Module", - "value": 5 + "value": 6 }, "carTire": { "type": "Module", - "value": 8 + "value": 9 }, "carWheel": { "type": "Module", - "value": 4 + "value": 5 }, "lugCount": { "type": "Number", @@ -39,6 +39,6 @@ description: Variables in memory after executing car-wheel-assembly.kcl }, "lugNut": { "type": "Module", - "value": 7 + "value": 8 } } diff --git a/rust/kcl-lib/tests/kcl_samples/color-cube/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/color-cube/artifact_commands.snap index 7bcc0c8dc..5495016cb 100644 --- a/rust/kcl-lib/tests/kcl_samples/color-cube/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/color-cube/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands color-cube.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/cycloidal-gear/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/cycloidal-gear/artifact_commands.snap index b9f4e7e82..520e6ca80 100644 --- a/rust/kcl-lib/tests/kcl_samples/cycloidal-gear/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/cycloidal-gear/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands cycloidal-gear.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/dodecahedron/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/dodecahedron/artifact_commands.snap index f63b70153..53558e1ab 100644 --- a/rust/kcl-lib/tests/kcl_samples/dodecahedron/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/dodecahedron/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands dodecahedron.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/artifact_commands.snap index c3240e555..507f89a8f 100644 --- a/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands dual-basin-utility-sink.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/artifact_graph_flowchart.snap.md index 41fb8abe0..9c4e67619 100644 --- a/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/artifact_graph_flowchart.snap.md @@ -1,119 +1,119 @@ ```mermaid flowchart LR subgraph path2 [Path] - 2["Path
[647, 681, 0]"] - 3["Segment
[687, 717, 0]"] - 4["Segment
[723, 753, 0]"] - 5["Segment
[759, 790, 0]"] - 6["Segment
[796, 852, 0]"] - 7["Segment
[858, 865, 0]"] + 2["Path
[662, 696, 0]"] + 3["Segment
[702, 734, 0]"] + 4["Segment
[740, 772, 0]"] + 5["Segment
[778, 811, 0]"] + 6["Segment
[817, 873, 0]"] + 7["Segment
[879, 886, 0]"] 8[Solid2d] end subgraph path32 [Path] - 32["Path
[1258, 1311, 0]"] - 33["Segment
[1317, 1347, 0]"] - 34["Segment
[1353, 1383, 0]"] - 35["Segment
[1389, 1420, 0]"] - 36["Segment
[1426, 1482, 0]"] - 37["Segment
[1488, 1495, 0]"] + 32["Path
[1279, 1332, 0]"] + 33["Segment
[1338, 1370, 0]"] + 34["Segment
[1376, 1408, 0]"] + 35["Segment
[1414, 1447, 0]"] + 36["Segment
[1453, 1509, 0]"] + 37["Segment
[1515, 1522, 0]"] 38[Solid2d] end subgraph path59 [Path] - 59["Path
[1760, 1813, 0]"] - 60["Segment
[1819, 1849, 0]"] - 61["Segment
[1855, 1885, 0]"] - 62["Segment
[1891, 1922, 0]"] - 63["Segment
[1928, 1984, 0]"] - 64["Segment
[1990, 1997, 0]"] + 59["Path
[1787, 1840, 0]"] + 60["Segment
[1846, 1878, 0]"] + 61["Segment
[1884, 1916, 0]"] + 62["Segment
[1922, 1955, 0]"] + 63["Segment
[1961, 2017, 0]"] + 64["Segment
[2023, 2030, 0]"] 65[Solid2d] end subgraph path83 [Path] - 83["Path
[2391, 2446, 0]"] - 84["Segment
[2452, 2482, 0]"] - 85["Segment
[2488, 2518, 0]"] - 86["Segment
[2524, 2555, 0]"] - 87["Segment
[2561, 2617, 0]"] - 88["Segment
[2623, 2630, 0]"] + 83["Path
[2426, 2481, 0]"] + 84["Segment
[2487, 2519, 0]"] + 85["Segment
[2525, 2557, 0]"] + 86["Segment
[2563, 2596, 0]"] + 87["Segment
[2602, 2658, 0]"] + 88["Segment
[2664, 2671, 0]"] 89[Solid2d] end subgraph path111 [Path] - 111["Path
[2932, 2970, 0]"] - 112["Segment
[2976, 3006, 0]"] - 113["Segment
[3012, 3036, 0]"] - 114["Segment
[3042, 3073, 0]"] - 115["Segment
[3079, 3135, 0]"] - 116["Segment
[3141, 3148, 0]"] + 111["Path
[2973, 3011, 0]"] + 112["Segment
[3017, 3049, 0]"] + 113["Segment
[3055, 3081, 0]"] + 114["Segment
[3087, 3120, 0]"] + 115["Segment
[3126, 3182, 0]"] + 116["Segment
[3188, 3195, 0]"] 117[Solid2d] end subgraph path134 [Path] - 134["Path
[3331, 3384, 0]"] - 135["Segment
[3390, 3420, 0]"] - 136["Segment
[3426, 3456, 0]"] - 137["Segment
[3462, 3493, 0]"] - 138["Segment
[3499, 3555, 0]"] - 139["Segment
[3561, 3568, 0]"] + 134["Path
[3378, 3431, 0]"] + 135["Segment
[3437, 3469, 0]"] + 136["Segment
[3475, 3507, 0]"] + 137["Segment
[3513, 3546, 0]"] + 138["Segment
[3552, 3608, 0]"] + 139["Segment
[3614, 3621, 0]"] 140[Solid2d] end subgraph path158 [Path] - 158["Path
[3794, 3831, 0]"] - 159["Segment
[3837, 3861, 0]"] - 160["Segment
[3867, 3891, 0]"] - 161["Segment
[3897, 3922, 0]"] - 162["Segment
[3928, 3984, 0]"] - 163["Segment
[3990, 3997, 0]"] + 158["Path
[3849, 3886, 0]"] + 159["Segment
[3892, 3918, 0]"] + 160["Segment
[3924, 3950, 0]"] + 161["Segment
[3956, 3983, 0]"] + 162["Segment
[3989, 4045, 0]"] + 163["Segment
[4051, 4058, 0]"] 164[Solid2d] end subgraph path180 [Path] - 180["Path
[4275, 4343, 0]"] - 181["Segment
[4349, 4373, 0]"] - 182["Segment
[4379, 4403, 0]"] - 183["Segment
[4409, 4434, 0]"] - 184["Segment
[4440, 4496, 0]"] - 185["Segment
[4502, 4509, 0]"] + 180["Path
[4340, 4408, 0]"] + 181["Segment
[4414, 4440, 0]"] + 182["Segment
[4446, 4472, 0]"] + 183["Segment
[4478, 4505, 0]"] + 184["Segment
[4511, 4567, 0]"] + 185["Segment
[4573, 4580, 0]"] 186[Solid2d] end subgraph path202 [Path] - 202["Path
[4698, 4794, 0]"] - 203["Segment
[4800, 4841, 0]"] - 204["Segment
[4847, 4887, 0]"] - 205["Segment
[4893, 4935, 0]"] - 206["Segment
[4941, 4997, 0]"] - 207["Segment
[5003, 5010, 0]"] + 202["Path
[4769, 4890, 0]"] + 203["Segment
[4896, 4945, 0]"] + 204["Segment
[4951, 4999, 0]"] + 205["Segment
[5005, 5053, 0]"] + 206["Segment
[5059, 5115, 0]"] + 207["Segment
[5121, 5128, 0]"] 208[Solid2d] end subgraph path225 [Path] - 225["Path
[5538, 5579, 0]"] - 226["Segment
[5585, 5615, 0]"] - 227["Segment
[5621, 5644, 0]"] - 228["Segment
[5650, 5681, 0]"] - 229["Segment
[5687, 5743, 0]"] - 230["Segment
[5749, 5756, 0]"] + 225["Path
[5660, 5701, 0]"] + 226["Segment
[5707, 5739, 0]"] + 227["Segment
[5745, 5770, 0]"] + 228["Segment
[5776, 5809, 0]"] + 229["Segment
[5815, 5871, 0]"] + 230["Segment
[5877, 5884, 0]"] 231[Solid2d] end subgraph path252 [Path] - 252["Path
[6039, 6080, 0]"] - 253["Segment
[6086, 6110, 0]"] - 254["Segment
[6116, 6146, 0]"] - 255["Segment
[6152, 6177, 0]"] - 256["Segment
[6183, 6239, 0]"] - 257["Segment
[6245, 6252, 0]"] + 252["Path
[6171, 6212, 0]"] + 253["Segment
[6218, 6244, 0]"] + 254["Segment
[6250, 6282, 0]"] + 255["Segment
[6288, 6315, 0]"] + 256["Segment
[6321, 6377, 0]"] + 257["Segment
[6383, 6390, 0]"] 258[Solid2d] end subgraph path276 [Path] - 276["Path
[6731, 6781, 0]"] - 277["Segment
[6787, 6822, 0]"] - 278["Segment
[6828, 6912, 0]"] - 279["Segment
[6918, 6952, 0]"] - 280["Segment
[6958, 7050, 0]"] - 281["Segment
[7056, 7090, 0]"] + 276["Path
[6867, 6917, 0]"] + 277["Segment
[6923, 6960, 0]"] + 278["Segment
[6966, 7050, 0]"] + 279["Segment
[7056, 7092, 0]"] + 280["Segment
[7098, 7190, 0]"] + 281["Segment
[7196, 7232, 0]"] end subgraph path283 [Path] - 283["Path
[7153, 7250, 0]"] - 284["Segment
[7153, 7250, 0]"] + 283["Path
[7295, 7406, 0]"] + 284["Segment
[7295, 7406, 0]"] 285[Solid2d] end - 1["Plane
[540, 557, 0]"] - 9["Sweep Extrusion
[1026, 1053, 0]"] + 1["Plane
[555, 572, 0]"] + 9["Sweep Extrusion
[1047, 1074, 0]"] 10[Wall] 11[Wall] 12[Wall] @@ -128,15 +128,15 @@ flowchart LR 21["SweepEdge Adjacent"] 22["SweepEdge Opposite"] 23["SweepEdge Adjacent"] - 24["Sweep Extrusion
[1026, 1053, 0]"] - 25["Sweep Extrusion
[1026, 1053, 0]"] - 26["Sweep Extrusion
[1026, 1053, 0]"] - 27["Sweep Extrusion
[1026, 1053, 0]"] - 28["Sweep Extrusion
[1026, 1053, 0]"] - 29["Sweep Extrusion
[1026, 1053, 0]"] - 30["Sweep Extrusion
[1026, 1053, 0]"] - 31["Plane
[1185, 1239, 0]"] - 39["Sweep Extrusion
[1658, 1692, 0]"] + 24["Sweep Extrusion
[1047, 1074, 0]"] + 25["Sweep Extrusion
[1047, 1074, 0]"] + 26["Sweep Extrusion
[1047, 1074, 0]"] + 27["Sweep Extrusion
[1047, 1074, 0]"] + 28["Sweep Extrusion
[1047, 1074, 0]"] + 29["Sweep Extrusion
[1047, 1074, 0]"] + 30["Sweep Extrusion
[1047, 1074, 0]"] + 31["Plane
[1206, 1260, 0]"] + 39["Sweep Extrusion
[1685, 1719, 0]"] 40[Wall] 41[Wall] 42[Wall] @@ -151,12 +151,12 @@ flowchart LR 51["SweepEdge Adjacent"] 52["SweepEdge Opposite"] 53["SweepEdge Adjacent"] - 54["Sweep Extrusion
[1658, 1692, 0]"] - 55["Sweep Extrusion
[1658, 1692, 0]"] - 56["Sweep Extrusion
[1658, 1692, 0]"] - 57["Sweep Extrusion
[1658, 1692, 0]"] - 58["Sweep Extrusion
[1658, 1692, 0]"] - 66["Sweep Extrusion
[2094, 2128, 0]"] + 54["Sweep Extrusion
[1685, 1719, 0]"] + 55["Sweep Extrusion
[1685, 1719, 0]"] + 56["Sweep Extrusion
[1685, 1719, 0]"] + 57["Sweep Extrusion
[1685, 1719, 0]"] + 58["Sweep Extrusion
[1685, 1719, 0]"] + 66["Sweep Extrusion
[2129, 2163, 0]"] 67[Wall] 68[Wall] 69[Wall] @@ -171,9 +171,9 @@ flowchart LR 78["SweepEdge Adjacent"] 79["SweepEdge Opposite"] 80["SweepEdge Adjacent"] - 81["Sweep Extrusion
[2094, 2128, 0]"] - 82["Plane
[2245, 2296, 0]"] - 90["Sweep Extrusion
[2793, 2828, 0]"] + 81["Sweep Extrusion
[2129, 2163, 0]"] + 82["Plane
[2280, 2331, 0]"] + 90["Sweep Extrusion
[2834, 2869, 0]"] 91[Wall] 92[Wall] 93[Wall] @@ -188,13 +188,13 @@ flowchart LR 102["SweepEdge Adjacent"] 103["SweepEdge Opposite"] 104["SweepEdge Adjacent"] - 105["Sweep Extrusion
[2793, 2828, 0]"] - 106["Sweep Extrusion
[2793, 2828, 0]"] - 107["Sweep Extrusion
[2793, 2828, 0]"] - 108["Sweep Extrusion
[2793, 2828, 0]"] - 109["Sweep Extrusion
[2793, 2828, 0]"] - 110["Plane
[2875, 2912, 0]"] - 118["Sweep Extrusion
[3228, 3263, 0]"] + 105["Sweep Extrusion
[2834, 2869, 0]"] + 106["Sweep Extrusion
[2834, 2869, 0]"] + 107["Sweep Extrusion
[2834, 2869, 0]"] + 108["Sweep Extrusion
[2834, 2869, 0]"] + 109["Sweep Extrusion
[2834, 2869, 0]"] + 110["Plane
[2916, 2953, 0]"] + 118["Sweep Extrusion
[3275, 3310, 0]"] 119[Wall] 120[Wall] 121[Wall] @@ -209,8 +209,8 @@ flowchart LR 130["SweepEdge Adjacent"] 131["SweepEdge Opposite"] 132["SweepEdge Adjacent"] - 133["Sweep Extrusion
[3228, 3263, 0]"] - 141["Sweep Extrusion
[3665, 3700, 0]"] + 133["Sweep Extrusion
[3275, 3310, 0]"] + 141["Sweep Extrusion
[3720, 3755, 0]"] 142[Wall] 143[Wall] 144[Wall] @@ -225,9 +225,9 @@ flowchart LR 153["SweepEdge Adjacent"] 154["SweepEdge Opposite"] 155["SweepEdge Adjacent"] - 156["Sweep Extrusion
[3665, 3700, 0]"] - 157["Plane
[3740, 3777, 0]"] - 165["Sweep Extrusion
[4003, 4036, 0]"] + 156["Sweep Extrusion
[3720, 3755, 0]"] + 157["Plane
[3795, 3832, 0]"] + 165["Sweep Extrusion
[4064, 4097, 0]"] 166[Wall] 167[Wall] 168[Wall] @@ -242,7 +242,7 @@ flowchart LR 177["SweepEdge Adjacent"] 178["SweepEdge Opposite"] 179["SweepEdge Adjacent"] - 187["Sweep Extrusion
[4599, 4626, 0]"] + 187["Sweep Extrusion
[4670, 4697, 0]"] 188[Wall] 189[Wall] 190[Wall] @@ -256,8 +256,8 @@ flowchart LR 198["SweepEdge Adjacent"] 199["SweepEdge Opposite"] 200["SweepEdge Adjacent"] - 201["Sweep Extrusion
[4599, 4626, 0]"] - 209["Sweep Extrusion
[5099, 5127, 0]"] + 201["Sweep Extrusion
[4670, 4697, 0]"] + 209["Sweep Extrusion
[5217, 5245, 0]"] 210[Wall] 211[Wall] 212[Wall] @@ -271,9 +271,9 @@ flowchart LR 220["SweepEdge Adjacent"] 221["SweepEdge Opposite"] 222["SweepEdge Adjacent"] - 223["Sweep Extrusion
[5099, 5127, 0]"] - 224["Plane
[5476, 5525, 0]"] - 232["Sweep Extrusion
[5855, 5883, 0]"] + 223["Sweep Extrusion
[5217, 5245, 0]"] + 224["Plane
[5598, 5647, 0]"] + 232["Sweep Extrusion
[5983, 6011, 0]"] 233[Wall] 234[Wall] 235[Wall] @@ -288,12 +288,12 @@ flowchart LR 244["SweepEdge Adjacent"] 245["SweepEdge Opposite"] 246["SweepEdge Adjacent"] - 247["Sweep Extrusion
[5855, 5883, 0]"] - 248["Sweep Extrusion
[5855, 5883, 0]"] - 249["Sweep Extrusion
[5855, 5883, 0]"] - 250["Sweep Extrusion
[5855, 5883, 0]"] - 251["Sweep Extrusion
[5855, 5883, 0]"] - 259["Sweep Extrusion
[6334, 6362, 0]"] + 247["Sweep Extrusion
[5983, 6011, 0]"] + 248["Sweep Extrusion
[5983, 6011, 0]"] + 249["Sweep Extrusion
[5983, 6011, 0]"] + 250["Sweep Extrusion
[5983, 6011, 0]"] + 251["Sweep Extrusion
[5983, 6011, 0]"] + 259["Sweep Extrusion
[6472, 6500, 0]"] 260[Wall] 261[Wall] 262[Wall] @@ -308,23 +308,23 @@ flowchart LR 271["SweepEdge Adjacent"] 272["SweepEdge Opposite"] 273["SweepEdge Adjacent"] - 274["Sweep Extrusion
[6334, 6362, 0]"] - 275["Plane
[6657, 6708, 0]"] - 282["Plane
[7112, 7129, 0]"] - 286["Sweep Sweep
[7267, 7320, 0]"] + 274["Sweep Extrusion
[6472, 6500, 0]"] + 275["Plane
[6793, 6844, 0]"] + 282["Plane
[7254, 7271, 0]"] + 286["Sweep Sweep
[7420, 7473, 0]"] 287[Wall] 288["Cap Start"] 289["Cap Start"] 290["SweepEdge Opposite"] 291["SweepEdge Adjacent"] - 292["StartSketchOnPlane
[1171, 1240, 0]"] - 293["StartSketchOnPlane
[2231, 2297, 0]"] - 294["StartSketchOnPlane
[2861, 2913, 0]"] - 295["StartSketchOnPlane
[3726, 3778, 0]"] - 296["StartSketchOnFace
[4220, 4256, 0]"] - 297["StartSketchOnFace
[4646, 4680, 0]"] - 298["StartSketchOnPlane
[5462, 5526, 0]"] - 299["StartSketchOnPlane
[6643, 6709, 0]"] + 292["StartSketchOnPlane
[1192, 1261, 0]"] + 293["StartSketchOnPlane
[2266, 2332, 0]"] + 294["StartSketchOnPlane
[2902, 2954, 0]"] + 295["StartSketchOnPlane
[3781, 3833, 0]"] + 296["StartSketchOnFace
[4285, 4321, 0]"] + 297["StartSketchOnFace
[4717, 4751, 0]"] + 298["StartSketchOnPlane
[5584, 5648, 0]"] + 299["StartSketchOnPlane
[6779, 6845, 0]"] 1 --- 2 2 --- 3 2 --- 4 diff --git a/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/ast.snap b/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/ast.snap index 0c1fb94fe..fa981352c 100644 --- a/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/ast.snap +++ b/rust/kcl-lib/tests/kcl_samples/dual-basin-utility-sink/ast.snap @@ -6,19 +6,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "Ok": { "body": [ { - "commentStart": 165, + "commentStart": 178, "declaration": { - "commentStart": 178, + "commentStart": 191, "end": 0, "id": { - "commentStart": 178, + "commentStart": 191, "end": 0, "name": "tableHeight", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 192, + "commentStart": 205, "end": 0, "raw": "850", "start": 0, @@ -42,19 +42,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 196, + "commentStart": 209, "declaration": { - "commentStart": 196, + "commentStart": 209, "end": 0, "id": { - "commentStart": 196, + "commentStart": 209, "end": 0, "name": "tableWidth", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 209, + "commentStart": 222, "end": 0, "raw": "3400", "start": 0, @@ -75,19 +75,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 214, + "commentStart": 227, "declaration": { - "commentStart": 214, + "commentStart": 227, "end": 0, "id": { - "commentStart": 214, + "commentStart": 227, "end": 0, "name": "tableDepth", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 227, + "commentStart": 240, "end": 0, "raw": "400", "start": 0, @@ -108,19 +108,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 230, + "commentStart": 243, "declaration": { - "commentStart": 232, + "commentStart": 245, "end": 0, "id": { - "commentStart": 232, + "commentStart": 245, "end": 0, "name": "profileThickness", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 251, + "commentStart": 264, "end": 0, "raw": "13", "start": 0, @@ -141,19 +141,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 254, + "commentStart": 267, "declaration": { - "commentStart": 254, + "commentStart": 267, "end": 0, "id": { - "commentStart": 254, + "commentStart": 267, "end": 0, "name": "metalThickness", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 271, + "commentStart": 284, "end": 0, "raw": "2", "start": 0, @@ -174,19 +174,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 272, + "commentStart": 285, "declaration": { - "commentStart": 274, + "commentStart": 287, "end": 0, "id": { - "commentStart": 274, + "commentStart": 287, "end": 0, "name": "blockCount", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 287, + "commentStart": 300, "end": 0, "raw": "3", "start": 0, @@ -207,29 +207,29 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 289, + "commentStart": 302, "declaration": { - "commentStart": 289, + "commentStart": 302, "end": 0, "id": { - "commentStart": 289, + "commentStart": 302, "end": 0, "name": "blockWidth", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 303, + "commentStart": 316, "end": 0, "left": { - "commentStart": 303, + "commentStart": 316, "end": 0, "left": { "abs_path": false, - "commentStart": 303, + "commentStart": 316, "end": 0, "name": { - "commentStart": 303, + "commentStart": 316, "end": 0, "name": "tableWidth", "start": 0, @@ -243,10 +243,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 314, + "commentStart": 329, "end": 0, "name": { - "commentStart": 314, + "commentStart": 329, "end": 0, "name": "profileThickness", "start": 0, @@ -263,7 +263,7 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "/", "right": { - "commentStart": 334, + "commentStart": 349, "end": 0, "raw": "3", "start": 0, @@ -288,29 +288,29 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 336, + "commentStart": 351, "declaration": { - "commentStart": 336, + "commentStart": 351, "end": 0, "id": { - "commentStart": 336, + "commentStart": 351, "end": 0, "name": "blockHeight", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 350, + "commentStart": 365, "end": 0, "left": { - "commentStart": 350, + "commentStart": 365, "end": 0, "left": { "abs_path": false, - "commentStart": 350, + "commentStart": 365, "end": 0, "name": { - "commentStart": 350, + "commentStart": 365, "end": 0, "name": "tableHeight", "start": 0, @@ -324,10 +324,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 364, + "commentStart": 379, "end": 0, "name": { - "commentStart": 364, + "commentStart": 379, "end": 0, "name": "metalThickness", "start": 0, @@ -344,7 +344,7 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "-", "right": { - "commentStart": 381, + "commentStart": 396, "end": 0, "raw": "0.5", "start": 0, @@ -369,26 +369,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 385, + "commentStart": 400, "declaration": { - "commentStart": 385, + "commentStart": 400, "end": 0, "id": { - "commentStart": 385, + "commentStart": 400, "end": 0, "name": "blockDepth", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 398, + "commentStart": 413, "end": 0, "left": { "abs_path": false, - "commentStart": 398, + "commentStart": 413, "end": 0, "name": { - "commentStart": 398, + "commentStart": 413, "end": 0, "name": "tableDepth", "start": 0, @@ -402,10 +402,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 411, + "commentStart": 426, "end": 0, "name": { - "commentStart": 411, + "commentStart": 426, "end": 0, "name": "profileThickness", "start": 0, @@ -430,19 +430,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 427, + "commentStart": 442, "declaration": { - "commentStart": 429, + "commentStart": 444, "end": 0, "id": { - "commentStart": 429, + "commentStart": 444, "end": 0, "name": "blockSubdivisionCount", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 453, + "commentStart": 468, "end": 0, "raw": "2", "start": 0, @@ -463,26 +463,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 455, + "commentStart": 470, "declaration": { - "commentStart": 455, + "commentStart": 470, "end": 0, "id": { - "commentStart": 455, + "commentStart": 470, "end": 0, "name": "blockSubdivisionWidth", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 479, + "commentStart": 494, "end": 0, "left": { "abs_path": false, - "commentStart": 479, + "commentStart": 494, "end": 0, "name": { - "commentStart": 479, + "commentStart": 494, "end": 0, "name": "blockWidth", "start": 0, @@ -496,10 +496,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "/", "right": { "abs_path": false, - "commentStart": 492, + "commentStart": 507, "end": 0, "name": { - "commentStart": 492, + "commentStart": 507, "end": 0, "name": "blockSubdivisionCount", "start": 0, @@ -524,12 +524,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 513, + "commentStart": 528, "declaration": { - "commentStart": 527, + "commentStart": 542, "end": 0, "id": { - "commentStart": 527, + "commentStart": 542, "end": 0, "name": "floorPlane", "start": 0, @@ -539,10 +539,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [ { "abs_path": false, - "commentStart": 554, + "commentStart": 569, "end": 0, "name": { - "commentStart": 554, + "commentStart": 569, "end": 0, "name": "XY", "start": 0, @@ -556,10 +556,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 540, + "commentStart": 555, "end": 0, "name": { - "commentStart": 540, + "commentStart": 555, "end": 0, "name": "startSketchOn", "start": 0, @@ -569,7 +569,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 540, + "commentStart": 555, "end": 0, "start": 0, "type": "CallExpression", @@ -590,26 +590,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 557, + "commentStart": 572, "declaration": { - "commentStart": 567, + "commentStart": 582, "end": 0, "id": { - "commentStart": 567, + "commentStart": 582, "end": 0, "name": "legHeight", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 579, + "commentStart": 594, "end": 0, "left": { "abs_path": false, - "commentStart": 579, + "commentStart": 594, "end": 0, "name": { - "commentStart": 579, + "commentStart": 594, "end": 0, "name": "blockHeight", "start": 0, @@ -623,10 +623,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 593, + "commentStart": 608, "end": 0, "name": { - "commentStart": 593, + "commentStart": 608, "end": 0, "name": "profileThickness", "start": 0, @@ -656,26 +656,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 610, + "commentStart": 625, "declaration": { - "commentStart": 610, + "commentStart": 625, "end": 0, "id": { - "commentStart": 610, + "commentStart": 625, "end": 0, "name": "legCount", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 621, + "commentStart": 636, "end": 0, "left": { "abs_path": false, - "commentStart": 621, + "commentStart": 636, "end": 0, "name": { - "commentStart": 621, + "commentStart": 636, "end": 0, "name": "blockCount", "start": 0, @@ -688,7 +688,7 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "+", "right": { - "commentStart": 634, + "commentStart": 649, "end": 0, "raw": "1", "start": 0, @@ -713,12 +713,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 635, + "commentStart": 650, "declaration": { - "commentStart": 637, + "commentStart": 652, "end": 0, "id": { - "commentStart": 637, + "commentStart": 652, "end": 0, "name": "legBody", "start": 0, @@ -729,10 +729,10 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 662, + "commentStart": 677, "elements": [ { - "commentStart": 663, + "commentStart": 678, "end": 0, "raw": "0", "start": 0, @@ -744,7 +744,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 666, + "commentStart": 681, "end": 0, "raw": "0", "start": 0, @@ -763,10 +763,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 670, + "commentStart": 685, "end": 0, "name": { - "commentStart": 670, + "commentStart": 685, "end": 0, "name": "floorPlane", "start": 0, @@ -780,10 +780,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 647, + "commentStart": 662, "end": 0, "name": { - "commentStart": 647, + "commentStart": 662, "end": 0, "name": "startProfileAt", "start": 0, @@ -793,7 +793,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 647, + "commentStart": 662, "end": 0, "start": 0, "type": "CallExpression", @@ -804,7 +804,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 693, + "commentStart": 708, "end": 0, "name": "length", "start": 0, @@ -812,10 +812,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 700, + "commentStart": 717, "end": 0, "name": { - "commentStart": 700, + "commentStart": 717, "end": 0, "name": "profileThickness", "start": 0, @@ -830,10 +830,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 687, + "commentStart": 702, "end": 0, "name": { - "commentStart": 687, + "commentStart": 702, "end": 0, "name": "yLine", "start": 0, @@ -843,7 +843,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 687, + "commentStart": 702, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -855,7 +855,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 729, + "commentStart": 746, "end": 0, "name": "length", "start": 0, @@ -863,10 +863,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 736, + "commentStart": 755, "end": 0, "name": { - "commentStart": 736, + "commentStart": 755, "end": 0, "name": "profileThickness", "start": 0, @@ -881,10 +881,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 723, + "commentStart": 740, "end": 0, "name": { - "commentStart": 723, + "commentStart": 740, "end": 0, "name": "xLine", "start": 0, @@ -894,7 +894,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 723, + "commentStart": 740, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -906,7 +906,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 765, + "commentStart": 784, "end": 0, "name": "length", "start": 0, @@ -915,10 +915,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 773, + "commentStart": 794, "end": 0, "name": { - "commentStart": 773, + "commentStart": 794, "end": 0, "name": "profileThickness", "start": 0, @@ -929,7 +929,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 772, + "commentStart": 793, "end": 0, "operator": "-", "start": 0, @@ -940,10 +940,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 759, + "commentStart": 778, "end": 0, "name": { - "commentStart": 759, + "commentStart": 778, "end": 0, "name": "yLine", "start": 0, @@ -953,7 +953,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 759, + "commentStart": 778, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -965,19 +965,19 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 801, + "commentStart": 822, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 815, + "commentStart": 836, "elements": [ { "arguments": [ { - "commentStart": 830, + "commentStart": 851, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -986,10 +986,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 816, + "commentStart": 837, "end": 0, "name": { - "commentStart": 816, + "commentStart": 837, "end": 0, "name": "profileStartX", "start": 0, @@ -999,7 +999,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 816, + "commentStart": 837, "end": 0, "start": 0, "type": "CallExpression", @@ -1008,7 +1008,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 848, + "commentStart": 869, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -1017,10 +1017,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 834, + "commentStart": 855, "end": 0, "name": { - "commentStart": 834, + "commentStart": 855, "end": 0, "name": "profileStartY", "start": 0, @@ -1030,7 +1030,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 834, + "commentStart": 855, "end": 0, "start": 0, "type": "CallExpression", @@ -1046,10 +1046,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 796, + "commentStart": 817, "end": 0, "name": { - "commentStart": 796, + "commentStart": 817, "end": 0, "name": "line", "start": 0, @@ -1059,7 +1059,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 796, + "commentStart": 817, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1070,10 +1070,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 858, + "commentStart": 879, "end": 0, "name": { - "commentStart": 858, + "commentStart": 879, "end": 0, "name": "close", "start": 0, @@ -1083,7 +1083,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 858, + "commentStart": 879, "end": 0, "start": 0, "type": "CallExpression", @@ -1094,17 +1094,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 887, + "commentStart": 908, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 894, + "commentStart": 915, "elements": [ { - "commentStart": 895, + "commentStart": 916, "end": 0, "raw": "1", "start": 0, @@ -1116,7 +1116,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 898, + "commentStart": 919, "end": 0, "raw": "0", "start": 0, @@ -1137,7 +1137,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 902, + "commentStart": 923, "end": 0, "name": "instances", "start": 0, @@ -1145,10 +1145,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 914, + "commentStart": 935, "end": 0, "name": { - "commentStart": 914, + "commentStart": 935, "end": 0, "name": "legCount", "start": 0, @@ -1163,7 +1163,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 924, + "commentStart": 945, "end": 0, "name": "distance", "start": 0, @@ -1171,10 +1171,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 935, + "commentStart": 956, "end": 0, "name": { - "commentStart": 935, + "commentStart": 956, "end": 0, "name": "blockWidth", "start": 0, @@ -1189,10 +1189,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 871, + "commentStart": 892, "end": 0, "name": { - "commentStart": 871, + "commentStart": 892, "end": 0, "name": "patternLinear2d", "start": 0, @@ -1202,7 +1202,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 871, + "commentStart": 892, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1214,17 +1214,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 968, + "commentStart": 989, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 975, + "commentStart": 996, "elements": [ { - "commentStart": 976, + "commentStart": 997, "end": 0, "raw": "0", "start": 0, @@ -1236,7 +1236,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 979, + "commentStart": 1000, "end": 0, "raw": "1", "start": 0, @@ -1257,14 +1257,14 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 983, + "commentStart": 1004, "end": 0, "name": "instances", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 995, + "commentStart": 1016, "end": 0, "raw": "2", "start": 0, @@ -1279,7 +1279,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 998, + "commentStart": 1019, "end": 0, "name": "distance", "start": 0, @@ -1287,10 +1287,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 1009, + "commentStart": 1030, "end": 0, "name": { - "commentStart": 1009, + "commentStart": 1030, "end": 0, "name": "blockDepth", "start": 0, @@ -1305,10 +1305,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 952, + "commentStart": 973, "end": 0, "name": { - "commentStart": 952, + "commentStart": 973, "end": 0, "name": "patternLinear2d", "start": 0, @@ -1318,7 +1318,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 952, + "commentStart": 973, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1330,7 +1330,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1034, + "commentStart": 1055, "end": 0, "name": "length", "start": 0, @@ -1338,10 +1338,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 1043, + "commentStart": 1064, "end": 0, "name": { - "commentStart": 1043, + "commentStart": 1064, "end": 0, "name": "legHeight", "start": 0, @@ -1356,10 +1356,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1026, + "commentStart": 1047, "end": 0, "name": { - "commentStart": 1026, + "commentStart": 1047, "end": 0, "name": "extrude", "start": 0, @@ -1369,7 +1369,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1026, + "commentStart": 1047, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1377,13 +1377,13 @@ description: Result of parsing dual-basin-utility-sink.kcl "unlabeled": null } ], - "commentStart": 647, + "commentStart": 662, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "8": [ { - "commentStart": 1053, + "commentStart": 1074, "end": 0, "start": 0, "type": "NonCodeNode", @@ -1411,19 +1411,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 1069, + "commentStart": 1090, "declaration": { - "commentStart": 1069, + "commentStart": 1090, "end": 0, "id": { - "commentStart": 1069, + "commentStart": 1090, "end": 0, "name": "lowerBeltHeightAboveTheFloor", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 1100, + "commentStart": 1121, "end": 0, "raw": "150", "start": 0, @@ -1444,26 +1444,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 1104, + "commentStart": 1125, "declaration": { - "commentStart": 1104, + "commentStart": 1125, "end": 0, "id": { - "commentStart": 1104, + "commentStart": 1125, "end": 0, "name": "lowerBeltLengthX", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 1123, + "commentStart": 1144, "end": 0, "left": { "abs_path": false, - "commentStart": 1123, + "commentStart": 1144, "end": 0, "name": { - "commentStart": 1123, + "commentStart": 1144, "end": 0, "name": "blockWidth", "start": 0, @@ -1477,10 +1477,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 1136, + "commentStart": 1157, "end": 0, "name": { - "commentStart": 1136, + "commentStart": 1157, "end": 0, "name": "profileThickness", "start": 0, @@ -1505,12 +1505,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 1152, + "commentStart": 1173, "declaration": { - "commentStart": 1154, + "commentStart": 1175, "end": 0, "id": { - "commentStart": 1154, + "commentStart": 1175, "end": 0, "name": "lowerBeltPlane", "start": 0, @@ -1523,7 +1523,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1201, + "commentStart": 1222, "end": 0, "name": "offset", "start": 0, @@ -1531,10 +1531,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 1210, + "commentStart": 1231, "end": 0, "name": { - "commentStart": 1210, + "commentStart": 1231, "end": 0, "name": "lowerBeltHeightAboveTheFloor", "start": 0, @@ -1549,10 +1549,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1185, + "commentStart": 1206, "end": 0, "name": { - "commentStart": 1185, + "commentStart": 1206, "end": 0, "name": "offsetPlane", "start": 0, @@ -1562,17 +1562,17 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1185, + "commentStart": 1206, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 1197, + "commentStart": 1218, "end": 0, "name": { - "commentStart": 1197, + "commentStart": 1218, "end": 0, "name": "XY", "start": 0, @@ -1587,10 +1587,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1171, + "commentStart": 1192, "end": 0, "name": { - "commentStart": 1171, + "commentStart": 1192, "end": 0, "name": "startSketchOn", "start": 0, @@ -1600,7 +1600,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1171, + "commentStart": 1192, "end": 0, "start": 0, "type": "CallExpression", @@ -1616,12 +1616,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 1241, + "commentStart": 1262, "declaration": { - "commentStart": 1241, + "commentStart": 1262, "end": 0, "id": { - "commentStart": 1241, + "commentStart": 1262, "end": 0, "name": "lowerBeltBodyX", "start": 0, @@ -1632,14 +1632,14 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 1273, + "commentStart": 1294, "elements": [ { "abs_path": false, - "commentStart": 1274, + "commentStart": 1295, "end": 0, "name": { - "commentStart": 1274, + "commentStart": 1295, "end": 0, "name": "profileThickness", "start": 0, @@ -1651,7 +1651,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name" }, { - "commentStart": 1292, + "commentStart": 1313, "end": 0, "raw": "0", "start": 0, @@ -1670,10 +1670,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 1296, + "commentStart": 1317, "end": 0, "name": { - "commentStart": 1296, + "commentStart": 1317, "end": 0, "name": "lowerBeltPlane", "start": 0, @@ -1687,10 +1687,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1258, + "commentStart": 1279, "end": 0, "name": { - "commentStart": 1258, + "commentStart": 1279, "end": 0, "name": "startProfileAt", "start": 0, @@ -1700,7 +1700,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1258, + "commentStart": 1279, "end": 0, "start": 0, "type": "CallExpression", @@ -1711,7 +1711,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1323, + "commentStart": 1344, "end": 0, "name": "length", "start": 0, @@ -1719,10 +1719,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 1330, + "commentStart": 1353, "end": 0, "name": { - "commentStart": 1330, + "commentStart": 1353, "end": 0, "name": "profileThickness", "start": 0, @@ -1737,10 +1737,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1317, + "commentStart": 1338, "end": 0, "name": { - "commentStart": 1317, + "commentStart": 1338, "end": 0, "name": "yLine", "start": 0, @@ -1750,7 +1750,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1317, + "commentStart": 1338, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1762,7 +1762,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1359, + "commentStart": 1382, "end": 0, "name": "length", "start": 0, @@ -1770,10 +1770,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 1366, + "commentStart": 1391, "end": 0, "name": { - "commentStart": 1366, + "commentStart": 1391, "end": 0, "name": "lowerBeltLengthX", "start": 0, @@ -1788,10 +1788,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1353, + "commentStart": 1376, "end": 0, "name": { - "commentStart": 1353, + "commentStart": 1376, "end": 0, "name": "xLine", "start": 0, @@ -1801,7 +1801,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1353, + "commentStart": 1376, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1813,7 +1813,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1395, + "commentStart": 1420, "end": 0, "name": "length", "start": 0, @@ -1822,10 +1822,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 1403, + "commentStart": 1430, "end": 0, "name": { - "commentStart": 1403, + "commentStart": 1430, "end": 0, "name": "profileThickness", "start": 0, @@ -1836,7 +1836,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 1402, + "commentStart": 1429, "end": 0, "operator": "-", "start": 0, @@ -1847,10 +1847,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1389, + "commentStart": 1414, "end": 0, "name": { - "commentStart": 1389, + "commentStart": 1414, "end": 0, "name": "yLine", "start": 0, @@ -1860,7 +1860,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1389, + "commentStart": 1414, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1872,19 +1872,19 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1431, + "commentStart": 1458, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1445, + "commentStart": 1472, "elements": [ { "arguments": [ { - "commentStart": 1460, + "commentStart": 1487, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -1893,10 +1893,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1446, + "commentStart": 1473, "end": 0, "name": { - "commentStart": 1446, + "commentStart": 1473, "end": 0, "name": "profileStartX", "start": 0, @@ -1906,7 +1906,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1446, + "commentStart": 1473, "end": 0, "start": 0, "type": "CallExpression", @@ -1915,7 +1915,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 1478, + "commentStart": 1505, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -1924,10 +1924,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1464, + "commentStart": 1491, "end": 0, "name": { - "commentStart": 1464, + "commentStart": 1491, "end": 0, "name": "profileStartY", "start": 0, @@ -1937,7 +1937,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1464, + "commentStart": 1491, "end": 0, "start": 0, "type": "CallExpression", @@ -1953,10 +1953,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1426, + "commentStart": 1453, "end": 0, "name": { - "commentStart": 1426, + "commentStart": 1453, "end": 0, "name": "line", "start": 0, @@ -1966,7 +1966,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1426, + "commentStart": 1453, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1977,10 +1977,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 1488, + "commentStart": 1515, "end": 0, "name": { - "commentStart": 1488, + "commentStart": 1515, "end": 0, "name": "close", "start": 0, @@ -1990,7 +1990,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1488, + "commentStart": 1515, "end": 0, "start": 0, "type": "CallExpression", @@ -2001,17 +2001,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1517, + "commentStart": 1544, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1524, + "commentStart": 1551, "elements": [ { - "commentStart": 1525, + "commentStart": 1552, "end": 0, "raw": "1", "start": 0, @@ -2023,7 +2023,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 1528, + "commentStart": 1555, "end": 0, "raw": "0", "start": 0, @@ -2044,7 +2044,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1532, + "commentStart": 1559, "end": 0, "name": "instances", "start": 0, @@ -2052,10 +2052,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 1544, + "commentStart": 1571, "end": 0, "name": { - "commentStart": 1544, + "commentStart": 1571, "end": 0, "name": "blockCount", "start": 0, @@ -2070,7 +2070,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1556, + "commentStart": 1583, "end": 0, "name": "distance", "start": 0, @@ -2078,10 +2078,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 1567, + "commentStart": 1594, "end": 0, "name": { - "commentStart": 1567, + "commentStart": 1594, "end": 0, "name": "blockWidth", "start": 0, @@ -2096,10 +2096,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1501, + "commentStart": 1528, "end": 0, "name": { - "commentStart": 1501, + "commentStart": 1528, "end": 0, "name": "patternLinear2d", "start": 0, @@ -2109,7 +2109,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1501, + "commentStart": 1528, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2121,17 +2121,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1600, + "commentStart": 1627, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1607, + "commentStart": 1634, "elements": [ { - "commentStart": 1608, + "commentStart": 1635, "end": 0, "raw": "0", "start": 0, @@ -2143,7 +2143,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 1611, + "commentStart": 1638, "end": 0, "raw": "1", "start": 0, @@ -2164,14 +2164,14 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1615, + "commentStart": 1642, "end": 0, "name": "instances", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1627, + "commentStart": 1654, "end": 0, "raw": "2", "start": 0, @@ -2186,7 +2186,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1630, + "commentStart": 1657, "end": 0, "name": "distance", "start": 0, @@ -2194,10 +2194,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 1641, + "commentStart": 1668, "end": 0, "name": { - "commentStart": 1641, + "commentStart": 1668, "end": 0, "name": "blockDepth", "start": 0, @@ -2212,10 +2212,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1584, + "commentStart": 1611, "end": 0, "name": { - "commentStart": 1584, + "commentStart": 1611, "end": 0, "name": "patternLinear2d", "start": 0, @@ -2225,7 +2225,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1584, + "commentStart": 1611, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2237,7 +2237,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1666, + "commentStart": 1693, "end": 0, "name": "length", "start": 0, @@ -2245,10 +2245,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 1675, + "commentStart": 1702, "end": 0, "name": { - "commentStart": 1675, + "commentStart": 1702, "end": 0, "name": "profileThickness", "start": 0, @@ -2263,10 +2263,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1658, + "commentStart": 1685, "end": 0, "name": { - "commentStart": 1658, + "commentStart": 1685, "end": 0, "name": "extrude", "start": 0, @@ -2276,7 +2276,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1658, + "commentStart": 1685, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2284,7 +2284,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "unlabeled": null } ], - "commentStart": 1258, + "commentStart": 1279, "end": 0, "start": 0, "type": "PipeExpression", @@ -2300,26 +2300,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 1692, + "commentStart": 1719, "declaration": { - "commentStart": 1694, + "commentStart": 1721, "end": 0, "id": { - "commentStart": 1694, + "commentStart": 1721, "end": 0, "name": "lowerBeltLengthY", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 1713, + "commentStart": 1740, "end": 0, "left": { "abs_path": false, - "commentStart": 1713, + "commentStart": 1740, "end": 0, "name": { - "commentStart": 1713, + "commentStart": 1740, "end": 0, "name": "blockDepth", "start": 0, @@ -2333,10 +2333,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 1726, + "commentStart": 1753, "end": 0, "name": { - "commentStart": 1726, + "commentStart": 1753, "end": 0, "name": "profileThickness", "start": 0, @@ -2361,12 +2361,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 1743, + "commentStart": 1770, "declaration": { - "commentStart": 1743, + "commentStart": 1770, "end": 0, "id": { - "commentStart": 1743, + "commentStart": 1770, "end": 0, "name": "lowerBeltBodyY", "start": 0, @@ -2377,10 +2377,10 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 1775, + "commentStart": 1802, "elements": [ { - "commentStart": 1776, + "commentStart": 1803, "end": 0, "raw": "0", "start": 0, @@ -2393,10 +2393,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 1779, + "commentStart": 1806, "end": 0, "name": { - "commentStart": 1779, + "commentStart": 1806, "end": 0, "name": "profileThickness", "start": 0, @@ -2415,10 +2415,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 1798, + "commentStart": 1825, "end": 0, "name": { - "commentStart": 1798, + "commentStart": 1825, "end": 0, "name": "lowerBeltPlane", "start": 0, @@ -2432,10 +2432,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1760, + "commentStart": 1787, "end": 0, "name": { - "commentStart": 1760, + "commentStart": 1787, "end": 0, "name": "startProfileAt", "start": 0, @@ -2445,7 +2445,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1760, + "commentStart": 1787, "end": 0, "start": 0, "type": "CallExpression", @@ -2456,7 +2456,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1825, + "commentStart": 1852, "end": 0, "name": "length", "start": 0, @@ -2464,10 +2464,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 1832, + "commentStart": 1861, "end": 0, "name": { - "commentStart": 1832, + "commentStart": 1861, "end": 0, "name": "lowerBeltLengthY", "start": 0, @@ -2482,10 +2482,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1819, + "commentStart": 1846, "end": 0, "name": { - "commentStart": 1819, + "commentStart": 1846, "end": 0, "name": "yLine", "start": 0, @@ -2495,7 +2495,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1819, + "commentStart": 1846, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2507,7 +2507,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1861, + "commentStart": 1890, "end": 0, "name": "length", "start": 0, @@ -2515,10 +2515,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 1868, + "commentStart": 1899, "end": 0, "name": { - "commentStart": 1868, + "commentStart": 1899, "end": 0, "name": "profileThickness", "start": 0, @@ -2533,10 +2533,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1855, + "commentStart": 1884, "end": 0, "name": { - "commentStart": 1855, + "commentStart": 1884, "end": 0, "name": "xLine", "start": 0, @@ -2546,7 +2546,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1855, + "commentStart": 1884, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2558,7 +2558,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1897, + "commentStart": 1928, "end": 0, "name": "length", "start": 0, @@ -2567,10 +2567,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 1905, + "commentStart": 1938, "end": 0, "name": { - "commentStart": 1905, + "commentStart": 1938, "end": 0, "name": "lowerBeltLengthY", "start": 0, @@ -2581,7 +2581,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 1904, + "commentStart": 1937, "end": 0, "operator": "-", "start": 0, @@ -2592,10 +2592,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1891, + "commentStart": 1922, "end": 0, "name": { - "commentStart": 1891, + "commentStart": 1922, "end": 0, "name": "yLine", "start": 0, @@ -2605,7 +2605,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1891, + "commentStart": 1922, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2617,19 +2617,19 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 1933, + "commentStart": 1966, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1947, + "commentStart": 1980, "elements": [ { "arguments": [ { - "commentStart": 1962, + "commentStart": 1995, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2638,10 +2638,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1948, + "commentStart": 1981, "end": 0, "name": { - "commentStart": 1948, + "commentStart": 1981, "end": 0, "name": "profileStartX", "start": 0, @@ -2651,7 +2651,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1948, + "commentStart": 1981, "end": 0, "start": 0, "type": "CallExpression", @@ -2660,7 +2660,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 1980, + "commentStart": 2013, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2669,10 +2669,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1966, + "commentStart": 1999, "end": 0, "name": { - "commentStart": 1966, + "commentStart": 1999, "end": 0, "name": "profileStartY", "start": 0, @@ -2682,7 +2682,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1966, + "commentStart": 1999, "end": 0, "start": 0, "type": "CallExpression", @@ -2698,10 +2698,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 1928, + "commentStart": 1961, "end": 0, "name": { - "commentStart": 1928, + "commentStart": 1961, "end": 0, "name": "line", "start": 0, @@ -2711,7 +2711,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1928, + "commentStart": 1961, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2722,10 +2722,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 1990, + "commentStart": 2023, "end": 0, "name": { - "commentStart": 1990, + "commentStart": 2023, "end": 0, "name": "close", "start": 0, @@ -2735,7 +2735,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 1990, + "commentStart": 2023, "end": 0, "start": 0, "type": "CallExpression", @@ -2746,17 +2746,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2019, + "commentStart": 2052, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2026, + "commentStart": 2059, "elements": [ { - "commentStart": 2027, + "commentStart": 2060, "end": 0, "raw": "1", "start": 0, @@ -2768,7 +2768,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 2030, + "commentStart": 2063, "end": 0, "raw": "0", "start": 0, @@ -2789,14 +2789,14 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2034, + "commentStart": 2067, "end": 0, "name": "instances", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2046, + "commentStart": 2079, "end": 0, "raw": "2", "start": 0, @@ -2811,21 +2811,21 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2049, + "commentStart": 2082, "end": 0, "name": "distance", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2060, + "commentStart": 2093, "end": 0, "left": { "abs_path": false, - "commentStart": 2060, + "commentStart": 2093, "end": 0, "name": { - "commentStart": 2060, + "commentStart": 2093, "end": 0, "name": "tableWidth", "start": 0, @@ -2839,10 +2839,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 2071, + "commentStart": 2106, "end": 0, "name": { - "commentStart": 2071, + "commentStart": 2106, "end": 0, "name": "profileThickness", "start": 0, @@ -2861,10 +2861,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2003, + "commentStart": 2036, "end": 0, "name": { - "commentStart": 2003, + "commentStart": 2036, "end": 0, "name": "patternLinear2d", "start": 0, @@ -2874,7 +2874,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2003, + "commentStart": 2036, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2886,7 +2886,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2102, + "commentStart": 2137, "end": 0, "name": "length", "start": 0, @@ -2894,10 +2894,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 2111, + "commentStart": 2146, "end": 0, "name": { - "commentStart": 2111, + "commentStart": 2146, "end": 0, "name": "profileThickness", "start": 0, @@ -2912,10 +2912,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2094, + "commentStart": 2129, "end": 0, "name": { - "commentStart": 2094, + "commentStart": 2129, "end": 0, "name": "extrude", "start": 0, @@ -2925,7 +2925,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2094, + "commentStart": 2129, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2933,13 +2933,13 @@ description: Result of parsing dual-basin-utility-sink.kcl "unlabeled": null } ], - "commentStart": 1760, + "commentStart": 1787, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "7": [ { - "commentStart": 2128, + "commentStart": 2163, "end": 0, "start": 0, "type": "NonCodeNode", @@ -2967,26 +2967,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 2141, + "commentStart": 2176, "declaration": { - "commentStart": 2141, + "commentStart": 2176, "end": 0, "id": { - "commentStart": 2141, + "commentStart": 2176, "end": 0, "name": "pillarHeightAboveTheFloor", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 2169, + "commentStart": 2204, "end": 0, "left": { "abs_path": false, - "commentStart": 2169, + "commentStart": 2204, "end": 0, "name": { - "commentStart": 2169, + "commentStart": 2204, "end": 0, "name": "lowerBeltHeightAboveTheFloor", "start": 0, @@ -3000,10 +3000,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 2200, + "commentStart": 2235, "end": 0, "name": { - "commentStart": 2200, + "commentStart": 2235, "end": 0, "name": "profileThickness", "start": 0, @@ -3028,12 +3028,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 2217, + "commentStart": 2252, "declaration": { - "commentStart": 2217, + "commentStart": 2252, "end": 0, "id": { - "commentStart": 2217, + "commentStart": 2252, "end": 0, "name": "pillarPlane", "start": 0, @@ -3046,7 +3046,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2261, + "commentStart": 2296, "end": 0, "name": "offset", "start": 0, @@ -3054,10 +3054,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 2270, + "commentStart": 2305, "end": 0, "name": { - "commentStart": 2270, + "commentStart": 2305, "end": 0, "name": "pillarHeightAboveTheFloor", "start": 0, @@ -3072,10 +3072,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2245, + "commentStart": 2280, "end": 0, "name": { - "commentStart": 2245, + "commentStart": 2280, "end": 0, "name": "offsetPlane", "start": 0, @@ -3085,17 +3085,17 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2245, + "commentStart": 2280, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 2257, + "commentStart": 2292, "end": 0, "name": { - "commentStart": 2257, + "commentStart": 2292, "end": 0, "name": "XY", "start": 0, @@ -3110,10 +3110,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2231, + "commentStart": 2266, "end": 0, "name": { - "commentStart": 2231, + "commentStart": 2266, "end": 0, "name": "startSketchOn", "start": 0, @@ -3123,7 +3123,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2231, + "commentStart": 2266, "end": 0, "start": 0, "type": "CallExpression", @@ -3139,29 +3139,29 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 2298, + "commentStart": 2333, "declaration": { - "commentStart": 2298, + "commentStart": 2333, "end": 0, "id": { - "commentStart": 2298, + "commentStart": 2333, "end": 0, "name": "pillarTotalHeight", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 2318, + "commentStart": 2353, "end": 0, "left": { - "commentStart": 2318, + "commentStart": 2353, "end": 0, "left": { "abs_path": false, - "commentStart": 2318, + "commentStart": 2353, "end": 0, "name": { - "commentStart": 2318, + "commentStart": 2353, "end": 0, "name": "blockHeight", "start": 0, @@ -3175,10 +3175,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 2332, + "commentStart": 2367, "end": 0, "name": { - "commentStart": 2332, + "commentStart": 2367, "end": 0, "name": "profileThickness", "start": 0, @@ -3196,10 +3196,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 2351, + "commentStart": 2386, "end": 0, "name": { - "commentStart": 2351, + "commentStart": 2386, "end": 0, "name": "pillarHeightAboveTheFloor", "start": 0, @@ -3224,12 +3224,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 2376, + "commentStart": 2411, "declaration": { - "commentStart": 2378, + "commentStart": 2413, "end": 0, "id": { - "commentStart": 2378, + "commentStart": 2413, "end": 0, "name": "pillarBody", "start": 0, @@ -3240,14 +3240,14 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 2406, + "commentStart": 2441, "elements": [ { "abs_path": false, - "commentStart": 2407, + "commentStart": 2442, "end": 0, "name": { - "commentStart": 2407, + "commentStart": 2442, "end": 0, "name": "blockSubdivisionWidth", "start": 0, @@ -3259,7 +3259,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name" }, { - "commentStart": 2430, + "commentStart": 2465, "end": 0, "raw": "0", "start": 0, @@ -3278,10 +3278,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 2434, + "commentStart": 2469, "end": 0, "name": { - "commentStart": 2434, + "commentStart": 2469, "end": 0, "name": "pillarPlane", "start": 0, @@ -3295,10 +3295,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2391, + "commentStart": 2426, "end": 0, "name": { - "commentStart": 2391, + "commentStart": 2426, "end": 0, "name": "startProfileAt", "start": 0, @@ -3308,7 +3308,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2391, + "commentStart": 2426, "end": 0, "start": 0, "type": "CallExpression", @@ -3319,7 +3319,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2458, + "commentStart": 2493, "end": 0, "name": "length", "start": 0, @@ -3327,10 +3327,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 2465, + "commentStart": 2502, "end": 0, "name": { - "commentStart": 2465, + "commentStart": 2502, "end": 0, "name": "profileThickness", "start": 0, @@ -3345,10 +3345,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2452, + "commentStart": 2487, "end": 0, "name": { - "commentStart": 2452, + "commentStart": 2487, "end": 0, "name": "yLine", "start": 0, @@ -3358,7 +3358,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2452, + "commentStart": 2487, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -3370,7 +3370,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2494, + "commentStart": 2531, "end": 0, "name": "length", "start": 0, @@ -3378,10 +3378,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 2501, + "commentStart": 2540, "end": 0, "name": { - "commentStart": 2501, + "commentStart": 2540, "end": 0, "name": "profileThickness", "start": 0, @@ -3396,10 +3396,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2488, + "commentStart": 2525, "end": 0, "name": { - "commentStart": 2488, + "commentStart": 2525, "end": 0, "name": "xLine", "start": 0, @@ -3409,7 +3409,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2488, + "commentStart": 2525, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -3421,7 +3421,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2530, + "commentStart": 2569, "end": 0, "name": "length", "start": 0, @@ -3430,10 +3430,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 2538, + "commentStart": 2579, "end": 0, "name": { - "commentStart": 2538, + "commentStart": 2579, "end": 0, "name": "profileThickness", "start": 0, @@ -3444,7 +3444,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 2537, + "commentStart": 2578, "end": 0, "operator": "-", "start": 0, @@ -3455,10 +3455,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2524, + "commentStart": 2563, "end": 0, "name": { - "commentStart": 2524, + "commentStart": 2563, "end": 0, "name": "yLine", "start": 0, @@ -3468,7 +3468,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2524, + "commentStart": 2563, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -3480,19 +3480,19 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2566, + "commentStart": 2607, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2580, + "commentStart": 2621, "elements": [ { "arguments": [ { - "commentStart": 2595, + "commentStart": 2636, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3501,10 +3501,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2581, + "commentStart": 2622, "end": 0, "name": { - "commentStart": 2581, + "commentStart": 2622, "end": 0, "name": "profileStartX", "start": 0, @@ -3514,7 +3514,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2581, + "commentStart": 2622, "end": 0, "start": 0, "type": "CallExpression", @@ -3523,7 +3523,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 2613, + "commentStart": 2654, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3532,10 +3532,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2599, + "commentStart": 2640, "end": 0, "name": { - "commentStart": 2599, + "commentStart": 2640, "end": 0, "name": "profileStartY", "start": 0, @@ -3545,7 +3545,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2599, + "commentStart": 2640, "end": 0, "start": 0, "type": "CallExpression", @@ -3561,10 +3561,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2561, + "commentStart": 2602, "end": 0, "name": { - "commentStart": 2561, + "commentStart": 2602, "end": 0, "name": "line", "start": 0, @@ -3574,7 +3574,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2561, + "commentStart": 2602, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -3585,10 +3585,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 2623, + "commentStart": 2664, "end": 0, "name": { - "commentStart": 2623, + "commentStart": 2664, "end": 0, "name": "close", "start": 0, @@ -3598,7 +3598,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2623, + "commentStart": 2664, "end": 0, "start": 0, "type": "CallExpression", @@ -3609,17 +3609,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2652, + "commentStart": 2693, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2659, + "commentStart": 2700, "elements": [ { - "commentStart": 2660, + "commentStart": 2701, "end": 0, "raw": "1", "start": 0, @@ -3631,7 +3631,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 2663, + "commentStart": 2704, "end": 0, "raw": "0", "start": 0, @@ -3652,7 +3652,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2667, + "commentStart": 2708, "end": 0, "name": "instances", "start": 0, @@ -3660,10 +3660,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 2679, + "commentStart": 2720, "end": 0, "name": { - "commentStart": 2679, + "commentStart": 2720, "end": 0, "name": "blockCount", "start": 0, @@ -3678,7 +3678,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2691, + "commentStart": 2732, "end": 0, "name": "distance", "start": 0, @@ -3686,10 +3686,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 2702, + "commentStart": 2743, "end": 0, "name": { - "commentStart": 2702, + "commentStart": 2743, "end": 0, "name": "blockWidth", "start": 0, @@ -3704,10 +3704,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2636, + "commentStart": 2677, "end": 0, "name": { - "commentStart": 2636, + "commentStart": 2677, "end": 0, "name": "patternLinear2d", "start": 0, @@ -3717,7 +3717,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2636, + "commentStart": 2677, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -3729,17 +3729,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2735, + "commentStart": 2776, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2742, + "commentStart": 2783, "elements": [ { - "commentStart": 2743, + "commentStart": 2784, "end": 0, "raw": "0", "start": 0, @@ -3751,7 +3751,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 2746, + "commentStart": 2787, "end": 0, "raw": "1", "start": 0, @@ -3772,14 +3772,14 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2750, + "commentStart": 2791, "end": 0, "name": "instances", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2762, + "commentStart": 2803, "end": 0, "raw": "2", "start": 0, @@ -3794,7 +3794,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2765, + "commentStart": 2806, "end": 0, "name": "distance", "start": 0, @@ -3802,10 +3802,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 2776, + "commentStart": 2817, "end": 0, "name": { - "commentStart": 2776, + "commentStart": 2817, "end": 0, "name": "blockDepth", "start": 0, @@ -3820,10 +3820,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2719, + "commentStart": 2760, "end": 0, "name": { - "commentStart": 2719, + "commentStart": 2760, "end": 0, "name": "patternLinear2d", "start": 0, @@ -3833,7 +3833,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2719, + "commentStart": 2760, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -3845,7 +3845,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2801, + "commentStart": 2842, "end": 0, "name": "length", "start": 0, @@ -3853,10 +3853,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 2810, + "commentStart": 2851, "end": 0, "name": { - "commentStart": 2810, + "commentStart": 2851, "end": 0, "name": "pillarTotalHeight", "start": 0, @@ -3871,10 +3871,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2793, + "commentStart": 2834, "end": 0, "name": { - "commentStart": 2793, + "commentStart": 2834, "end": 0, "name": "extrude", "start": 0, @@ -3884,7 +3884,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2793, + "commentStart": 2834, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -3892,13 +3892,13 @@ description: Result of parsing dual-basin-utility-sink.kcl "unlabeled": null } ], - "commentStart": 2391, + "commentStart": 2426, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "8": [ { - "commentStart": 2828, + "commentStart": 2869, "end": 0, "start": 0, "type": "NonCodeNode", @@ -3926,12 +3926,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 2844, + "commentStart": 2885, "declaration": { - "commentStart": 2844, + "commentStart": 2885, "end": 0, "id": { - "commentStart": 2844, + "commentStart": 2885, "end": 0, "name": "upperBeltPlane", "start": 0, @@ -3944,7 +3944,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2891, + "commentStart": 2932, "end": 0, "name": "offset", "start": 0, @@ -3952,10 +3952,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 2900, + "commentStart": 2941, "end": 0, "name": { - "commentStart": 2900, + "commentStart": 2941, "end": 0, "name": "blockHeight", "start": 0, @@ -3970,10 +3970,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2875, + "commentStart": 2916, "end": 0, "name": { - "commentStart": 2875, + "commentStart": 2916, "end": 0, "name": "offsetPlane", "start": 0, @@ -3983,17 +3983,17 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2875, + "commentStart": 2916, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 2887, + "commentStart": 2928, "end": 0, "name": { - "commentStart": 2887, + "commentStart": 2928, "end": 0, "name": "XY", "start": 0, @@ -4008,10 +4008,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2861, + "commentStart": 2902, "end": 0, "name": { - "commentStart": 2861, + "commentStart": 2902, "end": 0, "name": "startSketchOn", "start": 0, @@ -4021,7 +4021,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2861, + "commentStart": 2902, "end": 0, "start": 0, "type": "CallExpression", @@ -4037,12 +4037,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 2913, + "commentStart": 2954, "declaration": { - "commentStart": 2915, + "commentStart": 2956, "end": 0, "id": { - "commentStart": 2915, + "commentStart": 2956, "end": 0, "name": "upperBeltBodyX", "start": 0, @@ -4053,10 +4053,10 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 2947, + "commentStart": 2988, "elements": [ { - "commentStart": 2948, + "commentStart": 2989, "end": 0, "raw": "0", "start": 0, @@ -4068,7 +4068,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 2951, + "commentStart": 2992, "end": 0, "raw": "0", "start": 0, @@ -4087,10 +4087,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 2955, + "commentStart": 2996, "end": 0, "name": { - "commentStart": 2955, + "commentStart": 2996, "end": 0, "name": "upperBeltPlane", "start": 0, @@ -4104,10 +4104,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2932, + "commentStart": 2973, "end": 0, "name": { - "commentStart": 2932, + "commentStart": 2973, "end": 0, "name": "startProfileAt", "start": 0, @@ -4117,7 +4117,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2932, + "commentStart": 2973, "end": 0, "start": 0, "type": "CallExpression", @@ -4128,7 +4128,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 2982, + "commentStart": 3023, "end": 0, "name": "length", "start": 0, @@ -4136,10 +4136,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 2989, + "commentStart": 3032, "end": 0, "name": { - "commentStart": 2989, + "commentStart": 3032, "end": 0, "name": "profileThickness", "start": 0, @@ -4154,10 +4154,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 2976, + "commentStart": 3017, "end": 0, "name": { - "commentStart": 2976, + "commentStart": 3017, "end": 0, "name": "yLine", "start": 0, @@ -4167,7 +4167,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 2976, + "commentStart": 3017, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -4179,7 +4179,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3018, + "commentStart": 3061, "end": 0, "name": "length", "start": 0, @@ -4187,10 +4187,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 3025, + "commentStart": 3070, "end": 0, "name": { - "commentStart": 3025, + "commentStart": 3070, "end": 0, "name": "tableWidth", "start": 0, @@ -4205,10 +4205,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3012, + "commentStart": 3055, "end": 0, "name": { - "commentStart": 3012, + "commentStart": 3055, "end": 0, "name": "xLine", "start": 0, @@ -4218,7 +4218,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3012, + "commentStart": 3055, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -4230,7 +4230,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3048, + "commentStart": 3093, "end": 0, "name": "length", "start": 0, @@ -4239,10 +4239,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 3056, + "commentStart": 3103, "end": 0, "name": { - "commentStart": 3056, + "commentStart": 3103, "end": 0, "name": "profileThickness", "start": 0, @@ -4253,7 +4253,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 3055, + "commentStart": 3102, "end": 0, "operator": "-", "start": 0, @@ -4264,10 +4264,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3042, + "commentStart": 3087, "end": 0, "name": { - "commentStart": 3042, + "commentStart": 3087, "end": 0, "name": "yLine", "start": 0, @@ -4277,7 +4277,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3042, + "commentStart": 3087, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -4289,19 +4289,19 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3084, + "commentStart": 3131, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 3098, + "commentStart": 3145, "elements": [ { "arguments": [ { - "commentStart": 3113, + "commentStart": 3160, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -4310,10 +4310,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3099, + "commentStart": 3146, "end": 0, "name": { - "commentStart": 3099, + "commentStart": 3146, "end": 0, "name": "profileStartX", "start": 0, @@ -4323,7 +4323,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3099, + "commentStart": 3146, "end": 0, "start": 0, "type": "CallExpression", @@ -4332,7 +4332,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 3131, + "commentStart": 3178, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -4341,10 +4341,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3117, + "commentStart": 3164, "end": 0, "name": { - "commentStart": 3117, + "commentStart": 3164, "end": 0, "name": "profileStartY", "start": 0, @@ -4354,7 +4354,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3117, + "commentStart": 3164, "end": 0, "start": 0, "type": "CallExpression", @@ -4370,10 +4370,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3079, + "commentStart": 3126, "end": 0, "name": { - "commentStart": 3079, + "commentStart": 3126, "end": 0, "name": "line", "start": 0, @@ -4383,7 +4383,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3079, + "commentStart": 3126, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -4394,10 +4394,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 3141, + "commentStart": 3188, "end": 0, "name": { - "commentStart": 3141, + "commentStart": 3188, "end": 0, "name": "close", "start": 0, @@ -4407,7 +4407,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3141, + "commentStart": 3188, "end": 0, "start": 0, "type": "CallExpression", @@ -4418,17 +4418,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3170, + "commentStart": 3217, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 3177, + "commentStart": 3224, "elements": [ { - "commentStart": 3178, + "commentStart": 3225, "end": 0, "raw": "0", "start": 0, @@ -4440,7 +4440,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 3181, + "commentStart": 3228, "end": 0, "raw": "1", "start": 0, @@ -4461,14 +4461,14 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3185, + "commentStart": 3232, "end": 0, "name": "instances", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 3197, + "commentStart": 3244, "end": 0, "raw": "2", "start": 0, @@ -4483,7 +4483,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3200, + "commentStart": 3247, "end": 0, "name": "distance", "start": 0, @@ -4491,10 +4491,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 3211, + "commentStart": 3258, "end": 0, "name": { - "commentStart": 3211, + "commentStart": 3258, "end": 0, "name": "blockDepth", "start": 0, @@ -4509,10 +4509,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3154, + "commentStart": 3201, "end": 0, "name": { - "commentStart": 3154, + "commentStart": 3201, "end": 0, "name": "patternLinear2d", "start": 0, @@ -4522,7 +4522,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3154, + "commentStart": 3201, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -4534,7 +4534,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3236, + "commentStart": 3283, "end": 0, "name": "length", "start": 0, @@ -4543,10 +4543,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 3246, + "commentStart": 3293, "end": 0, "name": { - "commentStart": 3246, + "commentStart": 3293, "end": 0, "name": "profileThickness", "start": 0, @@ -4557,7 +4557,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 3245, + "commentStart": 3292, "end": 0, "operator": "-", "start": 0, @@ -4568,10 +4568,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3228, + "commentStart": 3275, "end": 0, "name": { - "commentStart": 3228, + "commentStart": 3275, "end": 0, "name": "extrude", "start": 0, @@ -4581,7 +4581,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3228, + "commentStart": 3275, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -4589,7 +4589,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "unlabeled": null } ], - "commentStart": 2932, + "commentStart": 2973, "end": 0, "start": 0, "type": "PipeExpression", @@ -4605,26 +4605,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 3263, + "commentStart": 3310, "declaration": { - "commentStart": 3265, + "commentStart": 3312, "end": 0, "id": { - "commentStart": 3265, + "commentStart": 3312, "end": 0, "name": "upperBeltLengthY", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 3284, + "commentStart": 3331, "end": 0, "left": { "abs_path": false, - "commentStart": 3284, + "commentStart": 3331, "end": 0, "name": { - "commentStart": 3284, + "commentStart": 3331, "end": 0, "name": "blockDepth", "start": 0, @@ -4638,10 +4638,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 3297, + "commentStart": 3344, "end": 0, "name": { - "commentStart": 3297, + "commentStart": 3344, "end": 0, "name": "profileThickness", "start": 0, @@ -4666,12 +4666,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 3314, + "commentStart": 3361, "declaration": { - "commentStart": 3314, + "commentStart": 3361, "end": 0, "id": { - "commentStart": 3314, + "commentStart": 3361, "end": 0, "name": "upperBeltBodyY", "start": 0, @@ -4682,10 +4682,10 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 3346, + "commentStart": 3393, "elements": [ { - "commentStart": 3347, + "commentStart": 3394, "end": 0, "raw": "0", "start": 0, @@ -4698,10 +4698,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 3350, + "commentStart": 3397, "end": 0, "name": { - "commentStart": 3350, + "commentStart": 3397, "end": 0, "name": "profileThickness", "start": 0, @@ -4720,10 +4720,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 3369, + "commentStart": 3416, "end": 0, "name": { - "commentStart": 3369, + "commentStart": 3416, "end": 0, "name": "upperBeltPlane", "start": 0, @@ -4737,10 +4737,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3331, + "commentStart": 3378, "end": 0, "name": { - "commentStart": 3331, + "commentStart": 3378, "end": 0, "name": "startProfileAt", "start": 0, @@ -4750,7 +4750,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3331, + "commentStart": 3378, "end": 0, "start": 0, "type": "CallExpression", @@ -4761,7 +4761,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3396, + "commentStart": 3443, "end": 0, "name": "length", "start": 0, @@ -4769,10 +4769,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 3403, + "commentStart": 3452, "end": 0, "name": { - "commentStart": 3403, + "commentStart": 3452, "end": 0, "name": "upperBeltLengthY", "start": 0, @@ -4787,10 +4787,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3390, + "commentStart": 3437, "end": 0, "name": { - "commentStart": 3390, + "commentStart": 3437, "end": 0, "name": "yLine", "start": 0, @@ -4800,7 +4800,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3390, + "commentStart": 3437, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -4812,7 +4812,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3432, + "commentStart": 3481, "end": 0, "name": "length", "start": 0, @@ -4820,10 +4820,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 3439, + "commentStart": 3490, "end": 0, "name": { - "commentStart": 3439, + "commentStart": 3490, "end": 0, "name": "profileThickness", "start": 0, @@ -4838,10 +4838,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3426, + "commentStart": 3475, "end": 0, "name": { - "commentStart": 3426, + "commentStart": 3475, "end": 0, "name": "xLine", "start": 0, @@ -4851,7 +4851,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3426, + "commentStart": 3475, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -4863,7 +4863,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3468, + "commentStart": 3519, "end": 0, "name": "length", "start": 0, @@ -4872,10 +4872,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 3476, + "commentStart": 3529, "end": 0, "name": { - "commentStart": 3476, + "commentStart": 3529, "end": 0, "name": "upperBeltLengthY", "start": 0, @@ -4886,7 +4886,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 3475, + "commentStart": 3528, "end": 0, "operator": "-", "start": 0, @@ -4897,10 +4897,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3462, + "commentStart": 3513, "end": 0, "name": { - "commentStart": 3462, + "commentStart": 3513, "end": 0, "name": "yLine", "start": 0, @@ -4910,7 +4910,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3462, + "commentStart": 3513, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -4922,19 +4922,19 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3504, + "commentStart": 3557, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 3518, + "commentStart": 3571, "elements": [ { "arguments": [ { - "commentStart": 3533, + "commentStart": 3586, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -4943,10 +4943,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3519, + "commentStart": 3572, "end": 0, "name": { - "commentStart": 3519, + "commentStart": 3572, "end": 0, "name": "profileStartX", "start": 0, @@ -4956,7 +4956,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3519, + "commentStart": 3572, "end": 0, "start": 0, "type": "CallExpression", @@ -4965,7 +4965,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 3551, + "commentStart": 3604, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -4974,10 +4974,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3537, + "commentStart": 3590, "end": 0, "name": { - "commentStart": 3537, + "commentStart": 3590, "end": 0, "name": "profileStartY", "start": 0, @@ -4987,7 +4987,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3537, + "commentStart": 3590, "end": 0, "start": 0, "type": "CallExpression", @@ -5003,10 +5003,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3499, + "commentStart": 3552, "end": 0, "name": { - "commentStart": 3499, + "commentStart": 3552, "end": 0, "name": "line", "start": 0, @@ -5016,7 +5016,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3499, + "commentStart": 3552, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -5027,10 +5027,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 3561, + "commentStart": 3614, "end": 0, "name": { - "commentStart": 3561, + "commentStart": 3614, "end": 0, "name": "close", "start": 0, @@ -5040,7 +5040,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3561, + "commentStart": 3614, "end": 0, "start": 0, "type": "CallExpression", @@ -5051,17 +5051,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3590, + "commentStart": 3643, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 3597, + "commentStart": 3650, "elements": [ { - "commentStart": 3598, + "commentStart": 3651, "end": 0, "raw": "1", "start": 0, @@ -5073,7 +5073,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 3601, + "commentStart": 3654, "end": 0, "raw": "0", "start": 0, @@ -5094,14 +5094,14 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3605, + "commentStart": 3658, "end": 0, "name": "instances", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 3617, + "commentStart": 3670, "end": 0, "raw": "2", "start": 0, @@ -5116,21 +5116,21 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3620, + "commentStart": 3673, "end": 0, "name": "distance", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 3631, + "commentStart": 3684, "end": 0, "left": { "abs_path": false, - "commentStart": 3631, + "commentStart": 3684, "end": 0, "name": { - "commentStart": 3631, + "commentStart": 3684, "end": 0, "name": "tableWidth", "start": 0, @@ -5144,10 +5144,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 3642, + "commentStart": 3697, "end": 0, "name": { - "commentStart": 3642, + "commentStart": 3697, "end": 0, "name": "profileThickness", "start": 0, @@ -5166,10 +5166,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3574, + "commentStart": 3627, "end": 0, "name": { - "commentStart": 3574, + "commentStart": 3627, "end": 0, "name": "patternLinear2d", "start": 0, @@ -5179,7 +5179,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3574, + "commentStart": 3627, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -5191,7 +5191,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3673, + "commentStart": 3728, "end": 0, "name": "length", "start": 0, @@ -5200,10 +5200,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 3683, + "commentStart": 3738, "end": 0, "name": { - "commentStart": 3683, + "commentStart": 3738, "end": 0, "name": "profileThickness", "start": 0, @@ -5214,7 +5214,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 3682, + "commentStart": 3737, "end": 0, "operator": "-", "start": 0, @@ -5225,10 +5225,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3665, + "commentStart": 3720, "end": 0, "name": { - "commentStart": 3665, + "commentStart": 3720, "end": 0, "name": "extrude", "start": 0, @@ -5238,7 +5238,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3665, + "commentStart": 3720, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -5246,13 +5246,13 @@ description: Result of parsing dual-basin-utility-sink.kcl "unlabeled": null } ], - "commentStart": 3331, + "commentStart": 3378, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "7": [ { - "commentStart": 3700, + "commentStart": 3755, "end": 0, "start": 0, "type": "NonCodeNode", @@ -5280,12 +5280,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 3710, + "commentStart": 3765, "declaration": { - "commentStart": 3710, + "commentStart": 3765, "end": 0, "id": { - "commentStart": 3710, + "commentStart": 3765, "end": 0, "name": "tableTopPlane", "start": 0, @@ -5298,7 +5298,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3756, + "commentStart": 3811, "end": 0, "name": "offset", "start": 0, @@ -5306,10 +5306,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 3765, + "commentStart": 3820, "end": 0, "name": { - "commentStart": 3765, + "commentStart": 3820, "end": 0, "name": "tableHeight", "start": 0, @@ -5324,10 +5324,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3740, + "commentStart": 3795, "end": 0, "name": { - "commentStart": 3740, + "commentStart": 3795, "end": 0, "name": "offsetPlane", "start": 0, @@ -5337,17 +5337,17 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3740, + "commentStart": 3795, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 3752, + "commentStart": 3807, "end": 0, "name": { - "commentStart": 3752, + "commentStart": 3807, "end": 0, "name": "XY", "start": 0, @@ -5362,10 +5362,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3726, + "commentStart": 3781, "end": 0, "name": { - "commentStart": 3726, + "commentStart": 3781, "end": 0, "name": "startSketchOn", "start": 0, @@ -5375,7 +5375,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3726, + "commentStart": 3781, "end": 0, "start": 0, "type": "CallExpression", @@ -5391,12 +5391,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 3779, + "commentStart": 3834, "declaration": { - "commentStart": 3779, + "commentStart": 3834, "end": 0, "id": { - "commentStart": 3779, + "commentStart": 3834, "end": 0, "name": "tableTopBody", "start": 0, @@ -5407,10 +5407,10 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 3809, + "commentStart": 3864, "elements": [ { - "commentStart": 3810, + "commentStart": 3865, "end": 0, "raw": "0", "start": 0, @@ -5422,7 +5422,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 3813, + "commentStart": 3868, "end": 0, "raw": "0", "start": 0, @@ -5441,10 +5441,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 3817, + "commentStart": 3872, "end": 0, "name": { - "commentStart": 3817, + "commentStart": 3872, "end": 0, "name": "tableTopPlane", "start": 0, @@ -5458,10 +5458,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3794, + "commentStart": 3849, "end": 0, "name": { - "commentStart": 3794, + "commentStart": 3849, "end": 0, "name": "startProfileAt", "start": 0, @@ -5471,7 +5471,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3794, + "commentStart": 3849, "end": 0, "start": 0, "type": "CallExpression", @@ -5482,7 +5482,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3843, + "commentStart": 3898, "end": 0, "name": "length", "start": 0, @@ -5490,10 +5490,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 3850, + "commentStart": 3907, "end": 0, "name": { - "commentStart": 3850, + "commentStart": 3907, "end": 0, "name": "tableDepth", "start": 0, @@ -5508,10 +5508,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3837, + "commentStart": 3892, "end": 0, "name": { - "commentStart": 3837, + "commentStart": 3892, "end": 0, "name": "yLine", "start": 0, @@ -5521,7 +5521,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3837, + "commentStart": 3892, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -5533,7 +5533,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3873, + "commentStart": 3930, "end": 0, "name": "length", "start": 0, @@ -5541,10 +5541,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 3880, + "commentStart": 3939, "end": 0, "name": { - "commentStart": 3880, + "commentStart": 3939, "end": 0, "name": "tableWidth", "start": 0, @@ -5559,10 +5559,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3867, + "commentStart": 3924, "end": 0, "name": { - "commentStart": 3867, + "commentStart": 3924, "end": 0, "name": "xLine", "start": 0, @@ -5572,7 +5572,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3867, + "commentStart": 3924, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -5584,7 +5584,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3903, + "commentStart": 3962, "end": 0, "name": "length", "start": 0, @@ -5593,10 +5593,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 3911, + "commentStart": 3972, "end": 0, "name": { - "commentStart": 3911, + "commentStart": 3972, "end": 0, "name": "tableDepth", "start": 0, @@ -5607,7 +5607,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 3910, + "commentStart": 3971, "end": 0, "operator": "-", "start": 0, @@ -5618,10 +5618,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3897, + "commentStart": 3956, "end": 0, "name": { - "commentStart": 3897, + "commentStart": 3956, "end": 0, "name": "yLine", "start": 0, @@ -5631,7 +5631,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3897, + "commentStart": 3956, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -5643,19 +5643,19 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 3933, + "commentStart": 3994, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 3947, + "commentStart": 4008, "elements": [ { "arguments": [ { - "commentStart": 3962, + "commentStart": 4023, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -5664,10 +5664,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3948, + "commentStart": 4009, "end": 0, "name": { - "commentStart": 3948, + "commentStart": 4009, "end": 0, "name": "profileStartX", "start": 0, @@ -5677,7 +5677,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3948, + "commentStart": 4009, "end": 0, "start": 0, "type": "CallExpression", @@ -5686,7 +5686,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 3980, + "commentStart": 4041, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -5695,10 +5695,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3966, + "commentStart": 4027, "end": 0, "name": { - "commentStart": 3966, + "commentStart": 4027, "end": 0, "name": "profileStartY", "start": 0, @@ -5708,7 +5708,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3966, + "commentStart": 4027, "end": 0, "start": 0, "type": "CallExpression", @@ -5724,10 +5724,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 3928, + "commentStart": 3989, "end": 0, "name": { - "commentStart": 3928, + "commentStart": 3989, "end": 0, "name": "line", "start": 0, @@ -5737,7 +5737,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3928, + "commentStart": 3989, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -5748,10 +5748,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 3990, + "commentStart": 4051, "end": 0, "name": { - "commentStart": 3990, + "commentStart": 4051, "end": 0, "name": "close", "start": 0, @@ -5761,7 +5761,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 3990, + "commentStart": 4051, "end": 0, "start": 0, "type": "CallExpression", @@ -5772,7 +5772,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 4011, + "commentStart": 4072, "end": 0, "name": "length", "start": 0, @@ -5781,10 +5781,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 4021, + "commentStart": 4082, "end": 0, "name": { - "commentStart": 4021, + "commentStart": 4082, "end": 0, "name": "metalThickness", "start": 0, @@ -5795,7 +5795,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 4020, + "commentStart": 4081, "end": 0, "operator": "-", "start": 0, @@ -5806,10 +5806,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4003, + "commentStart": 4064, "end": 0, "name": { - "commentStart": 4003, + "commentStart": 4064, "end": 0, "name": "extrude", "start": 0, @@ -5819,7 +5819,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4003, + "commentStart": 4064, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -5827,7 +5827,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "unlabeled": null } ], - "commentStart": 3794, + "commentStart": 3849, "end": 0, "start": 0, "type": "PipeExpression", @@ -5843,19 +5843,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 4036, + "commentStart": 4097, "declaration": { - "commentStart": 4038, + "commentStart": 4099, "end": 0, "id": { - "commentStart": 4038, + "commentStart": 4099, "end": 0, "name": "sinkCount", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 4050, + "commentStart": 4111, "end": 0, "raw": "2", "start": 0, @@ -5876,19 +5876,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 4052, + "commentStart": 4113, "declaration": { - "commentStart": 4052, + "commentStart": 4113, "end": 0, "id": { - "commentStart": 4052, + "commentStart": 4113, "end": 0, "name": "sinkWidth", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 4064, + "commentStart": 4125, "end": 0, "raw": "1000", "start": 0, @@ -5909,19 +5909,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 4069, + "commentStart": 4130, "declaration": { - "commentStart": 4069, + "commentStart": 4130, "end": 0, "id": { - "commentStart": 4069, + "commentStart": 4130, "end": 0, "name": "sinkLength", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 4082, + "commentStart": 4143, "end": 0, "raw": "250", "start": 0, @@ -5942,19 +5942,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 4086, + "commentStart": 4147, "declaration": { - "commentStart": 4086, + "commentStart": 4147, "end": 0, "id": { - "commentStart": 4086, + "commentStart": 4147, "end": 0, "name": "sinkDepth", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 4098, + "commentStart": 4159, "end": 0, "raw": "200", "start": 0, @@ -5975,19 +5975,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 4102, + "commentStart": 4163, "declaration": { - "commentStart": 4102, + "commentStart": 4163, "end": 0, "id": { - "commentStart": 4102, + "commentStart": 4163, "end": 0, "name": "sinkOffsetFront", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 4120, + "commentStart": 4181, "end": 0, "raw": "40", "start": 0, @@ -6008,19 +6008,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 4123, + "commentStart": 4184, "declaration": { - "commentStart": 4123, + "commentStart": 4184, "end": 0, "id": { - "commentStart": 4123, + "commentStart": 4184, "end": 0, "name": "sinkOffsetLeft", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 4140, + "commentStart": 4201, "end": 0, "raw": "350", "start": 0, @@ -6041,29 +6041,29 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 4144, + "commentStart": 4205, "declaration": { - "commentStart": 4144, + "commentStart": 4205, "end": 0, "id": { - "commentStart": 4144, + "commentStart": 4205, "end": 0, "name": "sinkSpacing", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 4158, + "commentStart": 4219, "end": 0, "left": { - "commentStart": 4158, + "commentStart": 4219, "end": 0, "left": { "abs_path": false, - "commentStart": 4158, + "commentStart": 4219, "end": 0, "name": { - "commentStart": 4158, + "commentStart": 4219, "end": 0, "name": "tableWidth", "start": 0, @@ -6077,10 +6077,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 4171, + "commentStart": 4232, "end": 0, "name": { - "commentStart": 4171, + "commentStart": 4232, "end": 0, "name": "sinkWidth", "start": 0, @@ -6097,14 +6097,14 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "-", "right": { - "commentStart": 4183, + "commentStart": 4245, "end": 0, "left": { "abs_path": false, - "commentStart": 4183, + "commentStart": 4245, "end": 0, "name": { - "commentStart": 4183, + "commentStart": 4245, "end": 0, "name": "sinkOffsetLeft", "start": 0, @@ -6117,7 +6117,7 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "*", "right": { - "commentStart": 4198, + "commentStart": 4262, "end": 0, "raw": "2", "start": 0, @@ -6146,12 +6146,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 4199, + "commentStart": 4264, "declaration": { - "commentStart": 4201, + "commentStart": 4266, "end": 0, "id": { - "commentStart": 4201, + "commentStart": 4266, "end": 0, "name": "sinkPlaneOutside", "start": 0, @@ -6161,10 +6161,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [ { "abs_path": false, - "commentStart": 4234, + "commentStart": 4299, "end": 0, "name": { - "commentStart": 4234, + "commentStart": 4299, "end": 0, "name": "tableTopBody", "start": 0, @@ -6176,7 +6176,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name" }, { - "commentStart": 4248, + "commentStart": 4313, "end": 0, "raw": "'START'", "start": 0, @@ -6187,10 +6187,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4220, + "commentStart": 4285, "end": 0, "name": { - "commentStart": 4220, + "commentStart": 4285, "end": 0, "name": "startSketchOn", "start": 0, @@ -6200,7 +6200,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4220, + "commentStart": 4285, "end": 0, "start": 0, "type": "CallExpression", @@ -6216,12 +6216,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 4257, + "commentStart": 4322, "declaration": { - "commentStart": 4257, + "commentStart": 4322, "end": 0, "id": { - "commentStart": 4257, + "commentStart": 4322, "end": 0, "name": "sinkBodyOutside", "start": 0, @@ -6232,15 +6232,15 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 4290, + "commentStart": 4355, "elements": [ { "argument": { "abs_path": false, - "commentStart": 4292, + "commentStart": 4357, "end": 0, "name": { - "commentStart": 4292, + "commentStart": 4357, "end": 0, "name": "sinkOffsetLeft", "start": 0, @@ -6251,7 +6251,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 4291, + "commentStart": 4356, "end": 0, "operator": "-", "start": 0, @@ -6260,10 +6260,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 4308, + "commentStart": 4373, "end": 0, "name": { - "commentStart": 4308, + "commentStart": 4373, "end": 0, "name": "sinkOffsetFront", "start": 0, @@ -6282,10 +6282,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 4326, + "commentStart": 4391, "end": 0, "name": { - "commentStart": 4326, + "commentStart": 4391, "end": 0, "name": "sinkPlaneOutside", "start": 0, @@ -6299,10 +6299,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4275, + "commentStart": 4340, "end": 0, "name": { - "commentStart": 4275, + "commentStart": 4340, "end": 0, "name": "startProfileAt", "start": 0, @@ -6312,7 +6312,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4275, + "commentStart": 4340, "end": 0, "start": 0, "type": "CallExpression", @@ -6323,7 +6323,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 4355, + "commentStart": 4420, "end": 0, "name": "length", "start": 0, @@ -6331,10 +6331,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 4362, + "commentStart": 4429, "end": 0, "name": { - "commentStart": 4362, + "commentStart": 4429, "end": 0, "name": "sinkLength", "start": 0, @@ -6349,10 +6349,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4349, + "commentStart": 4414, "end": 0, "name": { - "commentStart": 4349, + "commentStart": 4414, "end": 0, "name": "yLine", "start": 0, @@ -6362,7 +6362,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4349, + "commentStart": 4414, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -6374,7 +6374,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 4385, + "commentStart": 4452, "end": 0, "name": "length", "start": 0, @@ -6383,10 +6383,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 4393, + "commentStart": 4462, "end": 0, "name": { - "commentStart": 4393, + "commentStart": 4462, "end": 0, "name": "sinkWidth", "start": 0, @@ -6397,7 +6397,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 4392, + "commentStart": 4461, "end": 0, "operator": "-", "start": 0, @@ -6408,10 +6408,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4379, + "commentStart": 4446, "end": 0, "name": { - "commentStart": 4379, + "commentStart": 4446, "end": 0, "name": "xLine", "start": 0, @@ -6421,7 +6421,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4379, + "commentStart": 4446, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -6433,7 +6433,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 4415, + "commentStart": 4484, "end": 0, "name": "length", "start": 0, @@ -6442,10 +6442,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 4423, + "commentStart": 4494, "end": 0, "name": { - "commentStart": 4423, + "commentStart": 4494, "end": 0, "name": "sinkLength", "start": 0, @@ -6456,7 +6456,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 4422, + "commentStart": 4493, "end": 0, "operator": "-", "start": 0, @@ -6467,10 +6467,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4409, + "commentStart": 4478, "end": 0, "name": { - "commentStart": 4409, + "commentStart": 4478, "end": 0, "name": "yLine", "start": 0, @@ -6480,7 +6480,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4409, + "commentStart": 4478, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -6492,19 +6492,19 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 4445, + "commentStart": 4516, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 4459, + "commentStart": 4530, "elements": [ { "arguments": [ { - "commentStart": 4474, + "commentStart": 4545, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -6513,10 +6513,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4460, + "commentStart": 4531, "end": 0, "name": { - "commentStart": 4460, + "commentStart": 4531, "end": 0, "name": "profileStartX", "start": 0, @@ -6526,7 +6526,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4460, + "commentStart": 4531, "end": 0, "start": 0, "type": "CallExpression", @@ -6535,7 +6535,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 4492, + "commentStart": 4563, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -6544,10 +6544,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4478, + "commentStart": 4549, "end": 0, "name": { - "commentStart": 4478, + "commentStart": 4549, "end": 0, "name": "profileStartY", "start": 0, @@ -6557,7 +6557,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4478, + "commentStart": 4549, "end": 0, "start": 0, "type": "CallExpression", @@ -6573,10 +6573,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4440, + "commentStart": 4511, "end": 0, "name": { - "commentStart": 4440, + "commentStart": 4511, "end": 0, "name": "line", "start": 0, @@ -6586,7 +6586,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4440, + "commentStart": 4511, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -6597,10 +6597,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 4502, + "commentStart": 4573, "end": 0, "name": { - "commentStart": 4502, + "commentStart": 4573, "end": 0, "name": "close", "start": 0, @@ -6610,7 +6610,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4502, + "commentStart": 4573, "end": 0, "start": 0, "type": "CallExpression", @@ -6621,18 +6621,18 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 4531, + "commentStart": 4602, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 4538, + "commentStart": 4609, "elements": [ { "argument": { - "commentStart": 4540, + "commentStart": 4611, "end": 0, "raw": "1", "start": 0, @@ -6643,7 +6643,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "suffix": "None" } }, - "commentStart": 4539, + "commentStart": 4610, "end": 0, "operator": "-", "start": 0, @@ -6651,7 +6651,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "UnaryExpression" }, { - "commentStart": 4543, + "commentStart": 4614, "end": 0, "raw": "0", "start": 0, @@ -6672,7 +6672,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 4547, + "commentStart": 4618, "end": 0, "name": "instances", "start": 0, @@ -6680,10 +6680,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 4559, + "commentStart": 4630, "end": 0, "name": { - "commentStart": 4559, + "commentStart": 4630, "end": 0, "name": "sinkCount", "start": 0, @@ -6698,7 +6698,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 4570, + "commentStart": 4641, "end": 0, "name": "distance", "start": 0, @@ -6706,10 +6706,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 4581, + "commentStart": 4652, "end": 0, "name": { - "commentStart": 4581, + "commentStart": 4652, "end": 0, "name": "sinkSpacing", "start": 0, @@ -6724,10 +6724,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4515, + "commentStart": 4586, "end": 0, "name": { - "commentStart": 4515, + "commentStart": 4586, "end": 0, "name": "patternLinear2d", "start": 0, @@ -6737,7 +6737,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4515, + "commentStart": 4586, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -6749,7 +6749,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 4607, + "commentStart": 4678, "end": 0, "name": "length", "start": 0, @@ -6757,10 +6757,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 4616, + "commentStart": 4687, "end": 0, "name": { - "commentStart": 4616, + "commentStart": 4687, "end": 0, "name": "sinkDepth", "start": 0, @@ -6775,10 +6775,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4599, + "commentStart": 4670, "end": 0, "name": { - "commentStart": 4599, + "commentStart": 4670, "end": 0, "name": "extrude", "start": 0, @@ -6788,7 +6788,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4599, + "commentStart": 4670, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -6796,7 +6796,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "unlabeled": null } ], - "commentStart": 4275, + "commentStart": 4340, "end": 0, "start": 0, "type": "PipeExpression", @@ -6812,12 +6812,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 4626, + "commentStart": 4697, "declaration": { - "commentStart": 4628, + "commentStart": 4699, "end": 0, "id": { - "commentStart": 4628, + "commentStart": 4699, "end": 0, "name": "sinkPlaneInside", "start": 0, @@ -6827,10 +6827,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [ { "abs_path": false, - "commentStart": 4660, + "commentStart": 4731, "end": 0, "name": { - "commentStart": 4660, + "commentStart": 4731, "end": 0, "name": "tableTopBody", "start": 0, @@ -6842,7 +6842,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name" }, { - "commentStart": 4674, + "commentStart": 4745, "end": 0, "raw": "'END'", "start": 0, @@ -6853,10 +6853,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4646, + "commentStart": 4717, "end": 0, "name": { - "commentStart": 4646, + "commentStart": 4717, "end": 0, "name": "startSketchOn", "start": 0, @@ -6866,7 +6866,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4646, + "commentStart": 4717, "end": 0, "start": 0, "type": "CallExpression", @@ -6882,12 +6882,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 4681, + "commentStart": 4752, "declaration": { - "commentStart": 4681, + "commentStart": 4752, "end": 0, "id": { - "commentStart": 4681, + "commentStart": 4752, "end": 0, "name": "sinkBodyInside", "start": 0, @@ -6898,17 +6898,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 4713, + "commentStart": 4784, "elements": [ { - "commentStart": 4714, + "commentStart": 4793, "end": 0, "left": { "abs_path": false, - "commentStart": 4714, + "commentStart": 4793, "end": 0, "name": { - "commentStart": 4714, + "commentStart": 4793, "end": 0, "name": "sinkOffsetLeft", "start": 0, @@ -6922,10 +6922,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 4729, + "commentStart": 4810, "end": 0, "name": { - "commentStart": 4729, + "commentStart": 4810, "end": 0, "name": "metalThickness", "start": 0, @@ -6941,14 +6941,14 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "BinaryExpression" }, { - "commentStart": 4745, + "commentStart": 4833, "end": 0, "left": { "abs_path": false, - "commentStart": 4745, + "commentStart": 4833, "end": 0, "name": { - "commentStart": 4745, + "commentStart": 4833, "end": 0, "name": "sinkOffsetFront", "start": 0, @@ -6962,10 +6962,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 4761, + "commentStart": 4851, "end": 0, "name": { - "commentStart": 4761, + "commentStart": 4851, "end": 0, "name": "metalThickness", "start": 0, @@ -6988,10 +6988,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 4778, + "commentStart": 4874, "end": 0, "name": { - "commentStart": 4778, + "commentStart": 4874, "end": 0, "name": "sinkPlaneInside", "start": 0, @@ -7005,10 +7005,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4698, + "commentStart": 4769, "end": 0, "name": { - "commentStart": 4698, + "commentStart": 4769, "end": 0, "name": "startProfileAt", "start": 0, @@ -7018,7 +7018,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4698, + "commentStart": 4769, "end": 0, "start": 0, "type": "CallExpression", @@ -7029,21 +7029,21 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 4806, + "commentStart": 4902, "end": 0, "name": "length", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 4813, + "commentStart": 4911, "end": 0, "left": { "abs_path": false, - "commentStart": 4813, + "commentStart": 4911, "end": 0, "name": { - "commentStart": 4813, + "commentStart": 4911, "end": 0, "name": "sinkLength", "start": 0, @@ -7056,14 +7056,14 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "-", "right": { - "commentStart": 4824, + "commentStart": 4925, "end": 0, "left": { "abs_path": false, - "commentStart": 4824, + "commentStart": 4925, "end": 0, "name": { - "commentStart": 4824, + "commentStart": 4925, "end": 0, "name": "metalThickness", "start": 0, @@ -7076,7 +7076,7 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "*", "right": { - "commentStart": 4839, + "commentStart": 4942, "end": 0, "raw": "2", "start": 0, @@ -7099,10 +7099,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4800, + "commentStart": 4896, "end": 0, "name": { - "commentStart": 4800, + "commentStart": 4896, "end": 0, "name": "yLine", "start": 0, @@ -7112,7 +7112,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4800, + "commentStart": 4896, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -7124,21 +7124,21 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 4853, + "commentStart": 4957, "end": 0, "name": "length", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 4860, + "commentStart": 4966, "end": 0, "left": { "abs_path": false, - "commentStart": 4860, + "commentStart": 4966, "end": 0, "name": { - "commentStart": 4860, + "commentStart": 4966, "end": 0, "name": "sinkWidth", "start": 0, @@ -7151,14 +7151,14 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "-", "right": { - "commentStart": 4870, + "commentStart": 4979, "end": 0, "left": { "abs_path": false, - "commentStart": 4870, + "commentStart": 4979, "end": 0, "name": { - "commentStart": 4870, + "commentStart": 4979, "end": 0, "name": "metalThickness", "start": 0, @@ -7171,7 +7171,7 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "*", "right": { - "commentStart": 4885, + "commentStart": 4996, "end": 0, "raw": "2", "start": 0, @@ -7194,10 +7194,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4847, + "commentStart": 4951, "end": 0, "name": { - "commentStart": 4847, + "commentStart": 4951, "end": 0, "name": "xLine", "start": 0, @@ -7207,7 +7207,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4847, + "commentStart": 4951, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -7219,22 +7219,22 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 4899, + "commentStart": 5011, "end": 0, "name": "length", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 4906, + "commentStart": 5020, "end": 0, "left": { "argument": { "abs_path": false, - "commentStart": 4907, + "commentStart": 5021, "end": 0, "name": { - "commentStart": 4907, + "commentStart": 5021, "end": 0, "name": "sinkLength", "start": 0, @@ -7245,7 +7245,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 4906, + "commentStart": 5020, "end": 0, "operator": "-", "start": 0, @@ -7254,14 +7254,14 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "+", "right": { - "commentStart": 4918, + "commentStart": 5034, "end": 0, "left": { "abs_path": false, - "commentStart": 4918, + "commentStart": 5034, "end": 0, "name": { - "commentStart": 4918, + "commentStart": 5034, "end": 0, "name": "metalThickness", "start": 0, @@ -7274,7 +7274,7 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "*", "right": { - "commentStart": 4933, + "commentStart": 5051, "end": 0, "raw": "2", "start": 0, @@ -7297,10 +7297,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4893, + "commentStart": 5005, "end": 0, "name": { - "commentStart": 4893, + "commentStart": 5005, "end": 0, "name": "yLine", "start": 0, @@ -7310,7 +7310,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4893, + "commentStart": 5005, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -7322,19 +7322,19 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 4946, + "commentStart": 5064, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 4960, + "commentStart": 5078, "elements": [ { "arguments": [ { - "commentStart": 4975, + "commentStart": 5093, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -7343,10 +7343,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4961, + "commentStart": 5079, "end": 0, "name": { - "commentStart": 4961, + "commentStart": 5079, "end": 0, "name": "profileStartX", "start": 0, @@ -7356,7 +7356,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4961, + "commentStart": 5079, "end": 0, "start": 0, "type": "CallExpression", @@ -7365,7 +7365,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 4993, + "commentStart": 5111, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -7374,10 +7374,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4979, + "commentStart": 5097, "end": 0, "name": { - "commentStart": 4979, + "commentStart": 5097, "end": 0, "name": "profileStartY", "start": 0, @@ -7387,7 +7387,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4979, + "commentStart": 5097, "end": 0, "start": 0, "type": "CallExpression", @@ -7403,10 +7403,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 4941, + "commentStart": 5059, "end": 0, "name": { - "commentStart": 4941, + "commentStart": 5059, "end": 0, "name": "line", "start": 0, @@ -7416,7 +7416,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 4941, + "commentStart": 5059, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -7427,10 +7427,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 5003, + "commentStart": 5121, "end": 0, "name": { - "commentStart": 5003, + "commentStart": 5121, "end": 0, "name": "close", "start": 0, @@ -7440,7 +7440,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5003, + "commentStart": 5121, "end": 0, "start": 0, "type": "CallExpression", @@ -7451,17 +7451,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 5032, + "commentStart": 5150, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 5039, + "commentStart": 5157, "elements": [ { - "commentStart": 5040, + "commentStart": 5158, "end": 0, "raw": "1", "start": 0, @@ -7473,7 +7473,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 5043, + "commentStart": 5161, "end": 0, "raw": "0", "start": 0, @@ -7494,7 +7494,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 5047, + "commentStart": 5165, "end": 0, "name": "instances", "start": 0, @@ -7502,10 +7502,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 5059, + "commentStart": 5177, "end": 0, "name": { - "commentStart": 5059, + "commentStart": 5177, "end": 0, "name": "sinkCount", "start": 0, @@ -7520,7 +7520,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 5070, + "commentStart": 5188, "end": 0, "name": "distance", "start": 0, @@ -7528,10 +7528,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 5081, + "commentStart": 5199, "end": 0, "name": { - "commentStart": 5081, + "commentStart": 5199, "end": 0, "name": "sinkSpacing", "start": 0, @@ -7546,10 +7546,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 5016, + "commentStart": 5134, "end": 0, "name": { - "commentStart": 5016, + "commentStart": 5134, "end": 0, "name": "patternLinear2d", "start": 0, @@ -7559,7 +7559,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5016, + "commentStart": 5134, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -7571,7 +7571,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 5107, + "commentStart": 5225, "end": 0, "name": "length", "start": 0, @@ -7580,10 +7580,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 5117, + "commentStart": 5235, "end": 0, "name": { - "commentStart": 5117, + "commentStart": 5235, "end": 0, "name": "sinkDepth", "start": 0, @@ -7594,7 +7594,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 5116, + "commentStart": 5234, "end": 0, "operator": "-", "start": 0, @@ -7605,10 +7605,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 5099, + "commentStart": 5217, "end": 0, "name": { - "commentStart": 5099, + "commentStart": 5217, "end": 0, "name": "extrude", "start": 0, @@ -7618,7 +7618,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5099, + "commentStart": 5217, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -7626,13 +7626,13 @@ description: Result of parsing dual-basin-utility-sink.kcl "unlabeled": null } ], - "commentStart": 4698, + "commentStart": 4769, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "7": [ { - "commentStart": 5129, + "commentStart": 5245, "end": 0, "start": 0, "type": "NonCodeNode", @@ -7660,19 +7660,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 5146, + "commentStart": 5262, "declaration": { - "commentStart": 5146, + "commentStart": 5262, "end": 0, "id": { - "commentStart": 5146, + "commentStart": 5262, "end": 0, "name": "doorGap", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 5156, + "commentStart": 5272, "end": 0, "raw": "2", "start": 0, @@ -7693,29 +7693,29 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 5158, + "commentStart": 5274, "declaration": { - "commentStart": 5158, + "commentStart": 5274, "end": 0, "id": { - "commentStart": 5158, + "commentStart": 5274, "end": 0, "name": "doorWidth", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 5170, + "commentStart": 5286, "end": 0, "left": { - "commentStart": 5170, + "commentStart": 5286, "end": 0, "left": { "abs_path": false, - "commentStart": 5170, + "commentStart": 5286, "end": 0, "name": { - "commentStart": 5170, + "commentStart": 5286, "end": 0, "name": "blockSubdivisionWidth", "start": 0, @@ -7729,10 +7729,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 5194, + "commentStart": 5310, "end": 0, "name": { - "commentStart": 5194, + "commentStart": 5310, "end": 0, "name": "profileThickness", "start": 0, @@ -7749,14 +7749,14 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "-", "right": { - "commentStart": 5213, + "commentStart": 5330, "end": 0, "left": { "abs_path": false, - "commentStart": 5213, + "commentStart": 5330, "end": 0, "name": { - "commentStart": 5213, + "commentStart": 5330, "end": 0, "name": "doorGap", "start": 0, @@ -7769,7 +7769,7 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "*", "right": { - "commentStart": 5221, + "commentStart": 5340, "end": 0, "raw": "2", "start": 0, @@ -7798,26 +7798,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 5223, + "commentStart": 5343, "declaration": { - "commentStart": 5223, + "commentStart": 5343, "end": 0, "id": { - "commentStart": 5223, + "commentStart": 5343, "end": 0, "name": "doorStart", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 5235, + "commentStart": 5355, "end": 0, "left": { "abs_path": false, - "commentStart": 5235, + "commentStart": 5355, "end": 0, "name": { - "commentStart": 5235, + "commentStart": 5355, "end": 0, "name": "profileThickness", "start": 0, @@ -7831,10 +7831,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 5252, + "commentStart": 5374, "end": 0, "name": { - "commentStart": 5252, + "commentStart": 5374, "end": 0, "name": "doorGap", "start": 0, @@ -7859,26 +7859,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 5260, + "commentStart": 5382, "declaration": { - "commentStart": 5260, + "commentStart": 5382, "end": 0, "id": { - "commentStart": 5260, + "commentStart": 5382, "end": 0, "name": "doorHeightAboveTheFloor", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 5286, + "commentStart": 5408, "end": 0, "left": { "abs_path": false, - "commentStart": 5286, + "commentStart": 5408, "end": 0, "name": { - "commentStart": 5286, + "commentStart": 5408, "end": 0, "name": "pillarHeightAboveTheFloor", "start": 0, @@ -7892,10 +7892,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 5314, + "commentStart": 5436, "end": 0, "name": { - "commentStart": 5314, + "commentStart": 5436, "end": 0, "name": "doorGap", "start": 0, @@ -7920,32 +7920,32 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 5322, + "commentStart": 5444, "declaration": { - "commentStart": 5322, + "commentStart": 5444, "end": 0, "id": { - "commentStart": 5322, + "commentStart": 5444, "end": 0, "name": "doorHeight", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 5335, + "commentStart": 5457, "end": 0, "left": { - "commentStart": 5335, + "commentStart": 5457, "end": 0, "left": { - "commentStart": 5335, + "commentStart": 5457, "end": 0, "left": { "abs_path": false, - "commentStart": 5335, + "commentStart": 5457, "end": 0, "name": { - "commentStart": 5335, + "commentStart": 5457, "end": 0, "name": "blockHeight", "start": 0, @@ -7959,10 +7959,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 5349, + "commentStart": 5471, "end": 0, "name": { - "commentStart": 5349, + "commentStart": 5471, "end": 0, "name": "doorHeightAboveTheFloor", "start": 0, @@ -7980,10 +7980,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 5375, + "commentStart": 5497, "end": 0, "name": { - "commentStart": 5375, + "commentStart": 5497, "end": 0, "name": "profileThickness", "start": 0, @@ -8001,10 +8001,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 5394, + "commentStart": 5516, "end": 0, "name": { - "commentStart": 5394, + "commentStart": 5516, "end": 0, "name": "doorGap", "start": 0, @@ -8029,26 +8029,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 5402, + "commentStart": 5524, "declaration": { - "commentStart": 5402, + "commentStart": 5524, "end": 0, "id": { - "commentStart": 5402, + "commentStart": 5524, "end": 0, "name": "doorCount", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 5414, + "commentStart": 5536, "end": 0, "left": { "abs_path": false, - "commentStart": 5414, + "commentStart": 5536, "end": 0, "name": { - "commentStart": 5414, + "commentStart": 5536, "end": 0, "name": "blockCount", "start": 0, @@ -8062,10 +8062,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "*", "right": { "abs_path": false, - "commentStart": 5427, + "commentStart": 5549, "end": 0, "name": { - "commentStart": 5427, + "commentStart": 5549, "end": 0, "name": "blockSubdivisionCount", "start": 0, @@ -8090,12 +8090,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 5448, + "commentStart": 5570, "declaration": { - "commentStart": 5450, + "commentStart": 5572, "end": 0, "id": { - "commentStart": 5450, + "commentStart": 5572, "end": 0, "name": "doorPlane", "start": 0, @@ -8108,7 +8108,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 5492, + "commentStart": 5614, "end": 0, "name": "offset", "start": 0, @@ -8116,10 +8116,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 5501, + "commentStart": 5623, "end": 0, "name": { - "commentStart": 5501, + "commentStart": 5623, "end": 0, "name": "doorHeightAboveTheFloor", "start": 0, @@ -8134,10 +8134,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 5476, + "commentStart": 5598, "end": 0, "name": { - "commentStart": 5476, + "commentStart": 5598, "end": 0, "name": "offsetPlane", "start": 0, @@ -8147,17 +8147,17 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5476, + "commentStart": 5598, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 5488, + "commentStart": 5610, "end": 0, "name": { - "commentStart": 5488, + "commentStart": 5610, "end": 0, "name": "XY", "start": 0, @@ -8172,10 +8172,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 5462, + "commentStart": 5584, "end": 0, "name": { - "commentStart": 5462, + "commentStart": 5584, "end": 0, "name": "startSketchOn", "start": 0, @@ -8185,7 +8185,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5462, + "commentStart": 5584, "end": 0, "start": 0, "type": "CallExpression", @@ -8201,12 +8201,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 5527, + "commentStart": 5649, "declaration": { - "commentStart": 5527, + "commentStart": 5649, "end": 0, "id": { - "commentStart": 5527, + "commentStart": 5649, "end": 0, "name": "doorBody", "start": 0, @@ -8217,14 +8217,14 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 5553, + "commentStart": 5675, "elements": [ { "abs_path": false, - "commentStart": 5554, + "commentStart": 5676, "end": 0, "name": { - "commentStart": 5554, + "commentStart": 5676, "end": 0, "name": "doorStart", "start": 0, @@ -8236,7 +8236,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name" }, { - "commentStart": 5565, + "commentStart": 5687, "end": 0, "raw": "0", "start": 0, @@ -8255,10 +8255,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 5569, + "commentStart": 5691, "end": 0, "name": { - "commentStart": 5569, + "commentStart": 5691, "end": 0, "name": "doorPlane", "start": 0, @@ -8272,10 +8272,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 5538, + "commentStart": 5660, "end": 0, "name": { - "commentStart": 5538, + "commentStart": 5660, "end": 0, "name": "startProfileAt", "start": 0, @@ -8285,7 +8285,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5538, + "commentStart": 5660, "end": 0, "start": 0, "type": "CallExpression", @@ -8296,7 +8296,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 5591, + "commentStart": 5713, "end": 0, "name": "length", "start": 0, @@ -8304,10 +8304,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 5598, + "commentStart": 5722, "end": 0, "name": { - "commentStart": 5598, + "commentStart": 5722, "end": 0, "name": "profileThickness", "start": 0, @@ -8322,10 +8322,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 5585, + "commentStart": 5707, "end": 0, "name": { - "commentStart": 5585, + "commentStart": 5707, "end": 0, "name": "yLine", "start": 0, @@ -8335,7 +8335,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5585, + "commentStart": 5707, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -8347,7 +8347,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 5627, + "commentStart": 5751, "end": 0, "name": "length", "start": 0, @@ -8355,10 +8355,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 5634, + "commentStart": 5760, "end": 0, "name": { - "commentStart": 5634, + "commentStart": 5760, "end": 0, "name": "doorWidth", "start": 0, @@ -8373,10 +8373,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 5621, + "commentStart": 5745, "end": 0, "name": { - "commentStart": 5621, + "commentStart": 5745, "end": 0, "name": "xLine", "start": 0, @@ -8386,7 +8386,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5621, + "commentStart": 5745, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -8398,7 +8398,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 5656, + "commentStart": 5782, "end": 0, "name": "length", "start": 0, @@ -8407,10 +8407,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 5664, + "commentStart": 5792, "end": 0, "name": { - "commentStart": 5664, + "commentStart": 5792, "end": 0, "name": "profileThickness", "start": 0, @@ -8421,7 +8421,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 5663, + "commentStart": 5791, "end": 0, "operator": "-", "start": 0, @@ -8432,10 +8432,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 5650, + "commentStart": 5776, "end": 0, "name": { - "commentStart": 5650, + "commentStart": 5776, "end": 0, "name": "yLine", "start": 0, @@ -8445,7 +8445,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5650, + "commentStart": 5776, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -8457,19 +8457,19 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 5692, + "commentStart": 5820, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 5706, + "commentStart": 5834, "elements": [ { "arguments": [ { - "commentStart": 5721, + "commentStart": 5849, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -8478,10 +8478,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 5707, + "commentStart": 5835, "end": 0, "name": { - "commentStart": 5707, + "commentStart": 5835, "end": 0, "name": "profileStartX", "start": 0, @@ -8491,7 +8491,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5707, + "commentStart": 5835, "end": 0, "start": 0, "type": "CallExpression", @@ -8500,7 +8500,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 5739, + "commentStart": 5867, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -8509,10 +8509,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 5725, + "commentStart": 5853, "end": 0, "name": { - "commentStart": 5725, + "commentStart": 5853, "end": 0, "name": "profileStartY", "start": 0, @@ -8522,7 +8522,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5725, + "commentStart": 5853, "end": 0, "start": 0, "type": "CallExpression", @@ -8538,10 +8538,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 5687, + "commentStart": 5815, "end": 0, "name": { - "commentStart": 5687, + "commentStart": 5815, "end": 0, "name": "line", "start": 0, @@ -8551,7 +8551,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5687, + "commentStart": 5815, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -8562,10 +8562,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 5749, + "commentStart": 5877, "end": 0, "name": { - "commentStart": 5749, + "commentStart": 5877, "end": 0, "name": "close", "start": 0, @@ -8575,7 +8575,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5749, + "commentStart": 5877, "end": 0, "start": 0, "type": "CallExpression", @@ -8586,17 +8586,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 5778, + "commentStart": 5906, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 5785, + "commentStart": 5913, "elements": [ { - "commentStart": 5786, + "commentStart": 5914, "end": 0, "raw": "1", "start": 0, @@ -8608,7 +8608,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 5789, + "commentStart": 5917, "end": 0, "raw": "0", "start": 0, @@ -8629,7 +8629,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 5793, + "commentStart": 5921, "end": 0, "name": "instances", "start": 0, @@ -8637,10 +8637,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 5805, + "commentStart": 5933, "end": 0, "name": { - "commentStart": 5805, + "commentStart": 5933, "end": 0, "name": "doorCount", "start": 0, @@ -8655,7 +8655,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 5816, + "commentStart": 5944, "end": 0, "name": "distance", "start": 0, @@ -8663,10 +8663,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 5827, + "commentStart": 5955, "end": 0, "name": { - "commentStart": 5827, + "commentStart": 5955, "end": 0, "name": "blockSubdivisionWidth", "start": 0, @@ -8681,10 +8681,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 5762, + "commentStart": 5890, "end": 0, "name": { - "commentStart": 5762, + "commentStart": 5890, "end": 0, "name": "patternLinear2d", "start": 0, @@ -8694,7 +8694,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5762, + "commentStart": 5890, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -8706,7 +8706,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 5863, + "commentStart": 5991, "end": 0, "name": "length", "start": 0, @@ -8714,10 +8714,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 5872, + "commentStart": 6000, "end": 0, "name": { - "commentStart": 5872, + "commentStart": 6000, "end": 0, "name": "doorHeight", "start": 0, @@ -8732,10 +8732,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 5855, + "commentStart": 5983, "end": 0, "name": { - "commentStart": 5855, + "commentStart": 5983, "end": 0, "name": "extrude", "start": 0, @@ -8745,7 +8745,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 5855, + "commentStart": 5983, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -8753,13 +8753,13 @@ description: Result of parsing dual-basin-utility-sink.kcl "unlabeled": null } ], - "commentStart": 5538, + "commentStart": 5660, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "7": [ { - "commentStart": 5883, + "commentStart": 6011, "end": 0, "start": 0, "type": "NonCodeNode", @@ -8787,29 +8787,29 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 5900, + "commentStart": 6028, "declaration": { - "commentStart": 5900, + "commentStart": 6028, "end": 0, "id": { - "commentStart": 5900, + "commentStart": 6028, "end": 0, "name": "panelWidth", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 5913, + "commentStart": 6041, "end": 0, "left": { - "commentStart": 5913, + "commentStart": 6041, "end": 0, "left": { "abs_path": false, - "commentStart": 5913, + "commentStart": 6041, "end": 0, "name": { - "commentStart": 5913, + "commentStart": 6041, "end": 0, "name": "blockDepth", "start": 0, @@ -8823,10 +8823,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 5926, + "commentStart": 6054, "end": 0, "name": { - "commentStart": 5926, + "commentStart": 6054, "end": 0, "name": "profileThickness", "start": 0, @@ -8843,14 +8843,14 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "-", "right": { - "commentStart": 5945, + "commentStart": 6074, "end": 0, "left": { "abs_path": false, - "commentStart": 5945, + "commentStart": 6074, "end": 0, "name": { - "commentStart": 5945, + "commentStart": 6074, "end": 0, "name": "doorGap", "start": 0, @@ -8863,7 +8863,7 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "*", "right": { - "commentStart": 5953, + "commentStart": 6084, "end": 0, "raw": "2", "start": 0, @@ -8892,26 +8892,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 5955, + "commentStart": 6087, "declaration": { - "commentStart": 5955, + "commentStart": 6087, "end": 0, "id": { - "commentStart": 5955, + "commentStart": 6087, "end": 0, "name": "panelCount", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 5968, + "commentStart": 6100, "end": 0, "left": { "abs_path": false, - "commentStart": 5968, + "commentStart": 6100, "end": 0, "name": { - "commentStart": 5968, + "commentStart": 6100, "end": 0, "name": "doorCount", "start": 0, @@ -8924,7 +8924,7 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "+", "right": { - "commentStart": 5980, + "commentStart": 6112, "end": 0, "raw": "1", "start": 0, @@ -8949,26 +8949,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 5982, + "commentStart": 6114, "declaration": { - "commentStart": 5982, + "commentStart": 6114, "end": 0, "id": { - "commentStart": 5982, + "commentStart": 6114, "end": 0, "name": "panelSpacing", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 5997, + "commentStart": 6129, "end": 0, "left": { "abs_path": false, - "commentStart": 5997, + "commentStart": 6129, "end": 0, "name": { - "commentStart": 5997, + "commentStart": 6129, "end": 0, "name": "tableWidth", "start": 0, @@ -8982,10 +8982,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 6010, + "commentStart": 6142, "end": 0, "name": { - "commentStart": 6010, + "commentStart": 6142, "end": 0, "name": "profileThickness", "start": 0, @@ -9010,12 +9010,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 6027, + "commentStart": 6159, "declaration": { - "commentStart": 6027, + "commentStart": 6159, "end": 0, "id": { - "commentStart": 6027, + "commentStart": 6159, "end": 0, "name": "panelBody", "start": 0, @@ -9026,10 +9026,10 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 6054, + "commentStart": 6186, "elements": [ { - "commentStart": 6055, + "commentStart": 6187, "end": 0, "raw": "0", "start": 0, @@ -9042,10 +9042,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 6058, + "commentStart": 6190, "end": 0, "name": { - "commentStart": 6058, + "commentStart": 6190, "end": 0, "name": "doorStart", "start": 0, @@ -9064,10 +9064,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 6070, + "commentStart": 6202, "end": 0, "name": { - "commentStart": 6070, + "commentStart": 6202, "end": 0, "name": "doorPlane", "start": 0, @@ -9081,10 +9081,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 6039, + "commentStart": 6171, "end": 0, "name": { - "commentStart": 6039, + "commentStart": 6171, "end": 0, "name": "startProfileAt", "start": 0, @@ -9094,7 +9094,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6039, + "commentStart": 6171, "end": 0, "start": 0, "type": "CallExpression", @@ -9105,7 +9105,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 6092, + "commentStart": 6224, "end": 0, "name": "length", "start": 0, @@ -9113,10 +9113,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 6099, + "commentStart": 6233, "end": 0, "name": { - "commentStart": 6099, + "commentStart": 6233, "end": 0, "name": "panelWidth", "start": 0, @@ -9131,10 +9131,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 6086, + "commentStart": 6218, "end": 0, "name": { - "commentStart": 6086, + "commentStart": 6218, "end": 0, "name": "yLine", "start": 0, @@ -9144,7 +9144,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6086, + "commentStart": 6218, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -9156,7 +9156,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 6122, + "commentStart": 6256, "end": 0, "name": "length", "start": 0, @@ -9164,10 +9164,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 6129, + "commentStart": 6265, "end": 0, "name": { - "commentStart": 6129, + "commentStart": 6265, "end": 0, "name": "profileThickness", "start": 0, @@ -9182,10 +9182,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 6116, + "commentStart": 6250, "end": 0, "name": { - "commentStart": 6116, + "commentStart": 6250, "end": 0, "name": "xLine", "start": 0, @@ -9195,7 +9195,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6116, + "commentStart": 6250, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -9207,7 +9207,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 6158, + "commentStart": 6294, "end": 0, "name": "length", "start": 0, @@ -9216,10 +9216,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 6166, + "commentStart": 6304, "end": 0, "name": { - "commentStart": 6166, + "commentStart": 6304, "end": 0, "name": "panelWidth", "start": 0, @@ -9230,7 +9230,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 6165, + "commentStart": 6303, "end": 0, "operator": "-", "start": 0, @@ -9241,10 +9241,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 6152, + "commentStart": 6288, "end": 0, "name": { - "commentStart": 6152, + "commentStart": 6288, "end": 0, "name": "yLine", "start": 0, @@ -9254,7 +9254,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6152, + "commentStart": 6288, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -9266,19 +9266,19 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 6188, + "commentStart": 6326, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 6202, + "commentStart": 6340, "elements": [ { "arguments": [ { - "commentStart": 6217, + "commentStart": 6355, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -9287,10 +9287,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 6203, + "commentStart": 6341, "end": 0, "name": { - "commentStart": 6203, + "commentStart": 6341, "end": 0, "name": "profileStartX", "start": 0, @@ -9300,7 +9300,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6203, + "commentStart": 6341, "end": 0, "start": 0, "type": "CallExpression", @@ -9309,7 +9309,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 6235, + "commentStart": 6373, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -9318,10 +9318,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 6221, + "commentStart": 6359, "end": 0, "name": { - "commentStart": 6221, + "commentStart": 6359, "end": 0, "name": "profileStartY", "start": 0, @@ -9331,7 +9331,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6221, + "commentStart": 6359, "end": 0, "start": 0, "type": "CallExpression", @@ -9347,10 +9347,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 6183, + "commentStart": 6321, "end": 0, "name": { - "commentStart": 6183, + "commentStart": 6321, "end": 0, "name": "line", "start": 0, @@ -9360,7 +9360,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6183, + "commentStart": 6321, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -9371,10 +9371,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 6245, + "commentStart": 6383, "end": 0, "name": { - "commentStart": 6245, + "commentStart": 6383, "end": 0, "name": "close", "start": 0, @@ -9384,7 +9384,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6245, + "commentStart": 6383, "end": 0, "start": 0, "type": "CallExpression", @@ -9395,17 +9395,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 6274, + "commentStart": 6412, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 6281, + "commentStart": 6419, "elements": [ { - "commentStart": 6282, + "commentStart": 6420, "end": 0, "raw": "1", "start": 0, @@ -9417,7 +9417,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 6285, + "commentStart": 6423, "end": 0, "raw": "0", "start": 0, @@ -9438,14 +9438,14 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 6289, + "commentStart": 6427, "end": 0, "name": "instances", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 6301, + "commentStart": 6439, "end": 0, "raw": "2", "start": 0, @@ -9460,7 +9460,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 6304, + "commentStart": 6442, "end": 0, "name": "distance", "start": 0, @@ -9468,10 +9468,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 6315, + "commentStart": 6453, "end": 0, "name": { - "commentStart": 6315, + "commentStart": 6453, "end": 0, "name": "panelSpacing", "start": 0, @@ -9486,10 +9486,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 6258, + "commentStart": 6396, "end": 0, "name": { - "commentStart": 6258, + "commentStart": 6396, "end": 0, "name": "patternLinear2d", "start": 0, @@ -9499,7 +9499,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6258, + "commentStart": 6396, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -9511,7 +9511,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 6342, + "commentStart": 6480, "end": 0, "name": "length", "start": 0, @@ -9519,10 +9519,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 6351, + "commentStart": 6489, "end": 0, "name": { - "commentStart": 6351, + "commentStart": 6489, "end": 0, "name": "doorHeight", "start": 0, @@ -9537,10 +9537,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 6334, + "commentStart": 6472, "end": 0, "name": { - "commentStart": 6334, + "commentStart": 6472, "end": 0, "name": "extrude", "start": 0, @@ -9550,7 +9550,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6334, + "commentStart": 6472, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -9558,13 +9558,13 @@ description: Result of parsing dual-basin-utility-sink.kcl "unlabeled": null } ], - "commentStart": 6039, + "commentStart": 6171, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "7": [ { - "commentStart": 6364, + "commentStart": 6500, "end": 0, "start": 0, "type": "NonCodeNode", @@ -9592,19 +9592,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 6376, + "commentStart": 6512, "declaration": { - "commentStart": 6376, + "commentStart": 6512, "end": 0, "id": { - "commentStart": 6376, + "commentStart": 6512, "end": 0, "name": "handleDepth", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 6390, + "commentStart": 6526, "end": 0, "raw": "40", "start": 0, @@ -9625,19 +9625,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 6393, + "commentStart": 6529, "declaration": { - "commentStart": 6393, + "commentStart": 6529, "end": 0, "id": { - "commentStart": 6393, + "commentStart": 6529, "end": 0, "name": "handleWidth", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 6407, + "commentStart": 6543, "end": 0, "raw": "120", "start": 0, @@ -9658,19 +9658,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 6411, + "commentStart": 6547, "declaration": { - "commentStart": 6411, + "commentStart": 6547, "end": 0, "id": { - "commentStart": 6411, + "commentStart": 6547, "end": 0, "name": "handleFillet", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 6426, + "commentStart": 6562, "end": 0, "raw": "20", "start": 0, @@ -9691,19 +9691,19 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 6429, + "commentStart": 6565, "declaration": { - "commentStart": 6429, + "commentStart": 6565, "end": 0, "id": { - "commentStart": 6429, + "commentStart": 6565, "end": 0, "name": "handleHeightAboveTheFloor", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 6457, + "commentStart": 6593, "end": 0, "raw": "780", "start": 0, @@ -9724,29 +9724,29 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 6461, + "commentStart": 6597, "declaration": { - "commentStart": 6461, + "commentStart": 6597, "end": 0, "id": { - "commentStart": 6461, + "commentStart": 6597, "end": 0, "name": "handleOffset", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 6476, + "commentStart": 6612, "end": 0, "left": { - "commentStart": 6476, + "commentStart": 6612, "end": 0, "left": { "abs_path": false, - "commentStart": 6476, + "commentStart": 6612, "end": 0, "name": { - "commentStart": 6476, + "commentStart": 6612, "end": 0, "name": "doorStart", "start": 0, @@ -9759,14 +9759,14 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "+", "right": { - "commentStart": 6488, + "commentStart": 6624, "end": 0, "left": { "abs_path": false, - "commentStart": 6488, + "commentStart": 6624, "end": 0, "name": { - "commentStart": 6488, + "commentStart": 6624, "end": 0, "name": "doorWidth", "start": 0, @@ -9779,7 +9779,7 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "/", "right": { - "commentStart": 6500, + "commentStart": 6636, "end": 0, "raw": "2", "start": 0, @@ -9800,14 +9800,14 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "-", "right": { - "commentStart": 6505, + "commentStart": 6641, "end": 0, "left": { "abs_path": false, - "commentStart": 6505, + "commentStart": 6641, "end": 0, "name": { - "commentStart": 6505, + "commentStart": 6641, "end": 0, "name": "handleWidth", "start": 0, @@ -9820,7 +9820,7 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "/", "right": { - "commentStart": 6519, + "commentStart": 6655, "end": 0, "raw": "2", "start": 0, @@ -9849,26 +9849,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 6522, + "commentStart": 6658, "declaration": { - "commentStart": 6522, + "commentStart": 6658, "end": 0, "id": { - "commentStart": 6522, + "commentStart": 6658, "end": 0, "name": "handleLengthSegmentA", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 6545, + "commentStart": 6681, "end": 0, "left": { "abs_path": false, - "commentStart": 6545, + "commentStart": 6681, "end": 0, "name": { - "commentStart": 6545, + "commentStart": 6681, "end": 0, "name": "handleDepth", "start": 0, @@ -9882,10 +9882,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 6559, + "commentStart": 6695, "end": 0, "name": { - "commentStart": 6559, + "commentStart": 6695, "end": 0, "name": "handleFillet", "start": 0, @@ -9910,26 +9910,26 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 6572, + "commentStart": 6708, "declaration": { - "commentStart": 6572, + "commentStart": 6708, "end": 0, "id": { - "commentStart": 6572, + "commentStart": 6708, "end": 0, "name": "handleLengthSegmentB", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 6595, + "commentStart": 6731, "end": 0, "left": { "abs_path": false, - "commentStart": 6595, + "commentStart": 6731, "end": 0, "name": { - "commentStart": 6595, + "commentStart": 6731, "end": 0, "name": "handleWidth", "start": 0, @@ -9942,14 +9942,14 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "-", "right": { - "commentStart": 6610, + "commentStart": 6746, "end": 0, "left": { "abs_path": false, - "commentStart": 6610, + "commentStart": 6746, "end": 0, "name": { - "commentStart": 6610, + "commentStart": 6746, "end": 0, "name": "handleFillet", "start": 0, @@ -9962,7 +9962,7 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "operator": "*", "right": { - "commentStart": 6625, + "commentStart": 6761, "end": 0, "raw": "2", "start": 0, @@ -9991,12 +9991,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 6627, + "commentStart": 6763, "declaration": { - "commentStart": 6629, + "commentStart": 6765, "end": 0, "id": { - "commentStart": 6629, + "commentStart": 6765, "end": 0, "name": "handlePlane", "start": 0, @@ -10009,7 +10009,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 6673, + "commentStart": 6809, "end": 0, "name": "offset", "start": 0, @@ -10017,10 +10017,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 6682, + "commentStart": 6818, "end": 0, "name": { - "commentStart": 6682, + "commentStart": 6818, "end": 0, "name": "handleHeightAboveTheFloor", "start": 0, @@ -10035,10 +10035,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 6657, + "commentStart": 6793, "end": 0, "name": { - "commentStart": 6657, + "commentStart": 6793, "end": 0, "name": "offsetPlane", "start": 0, @@ -10048,17 +10048,17 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6657, + "commentStart": 6793, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 6669, + "commentStart": 6805, "end": 0, "name": { - "commentStart": 6669, + "commentStart": 6805, "end": 0, "name": "XY", "start": 0, @@ -10073,10 +10073,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 6643, + "commentStart": 6779, "end": 0, "name": { - "commentStart": 6643, + "commentStart": 6779, "end": 0, "name": "startSketchOn", "start": 0, @@ -10086,7 +10086,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6643, + "commentStart": 6779, "end": 0, "start": 0, "type": "CallExpression", @@ -10102,12 +10102,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 6709, + "commentStart": 6845, "declaration": { - "commentStart": 6711, + "commentStart": 6847, "end": 0, "id": { - "commentStart": 6711, + "commentStart": 6847, "end": 0, "name": "handleProfilePath", "start": 0, @@ -10118,13 +10118,13 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 6746, + "commentStart": 6882, "elements": [ { - "commentStart": 6747, + "commentStart": 6883, "end": 0, "left": { - "commentStart": 6747, + "commentStart": 6883, "end": 0, "raw": "0", "start": 0, @@ -10138,10 +10138,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 6751, + "commentStart": 6887, "end": 0, "name": { - "commentStart": 6751, + "commentStart": 6887, "end": 0, "name": "handleOffset", "start": 0, @@ -10157,7 +10157,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "BinaryExpression" }, { - "commentStart": 6765, + "commentStart": 6901, "end": 0, "raw": "0", "start": 0, @@ -10176,10 +10176,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 6769, + "commentStart": 6905, "end": 0, "name": { - "commentStart": 6769, + "commentStart": 6905, "end": 0, "name": "handlePlane", "start": 0, @@ -10193,10 +10193,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 6731, + "commentStart": 6867, "end": 0, "name": { - "commentStart": 6731, + "commentStart": 6867, "end": 0, "name": "startProfileAt", "start": 0, @@ -10206,7 +10206,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6731, + "commentStart": 6867, "end": 0, "start": 0, "type": "CallExpression", @@ -10217,7 +10217,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 6793, + "commentStart": 6929, "end": 0, "name": "length", "start": 0, @@ -10226,10 +10226,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 6801, + "commentStart": 6939, "end": 0, "name": { - "commentStart": 6801, + "commentStart": 6939, "end": 0, "name": "handleLengthSegmentA", "start": 0, @@ -10240,7 +10240,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 6800, + "commentStart": 6938, "end": 0, "operator": "-", "start": 0, @@ -10251,10 +10251,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 6787, + "commentStart": 6923, "end": 0, "name": { - "commentStart": 6787, + "commentStart": 6923, "end": 0, "name": "yLine", "start": 0, @@ -10264,7 +10264,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6787, + "commentStart": 6923, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -10274,17 +10274,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "arguments": [ { - "commentStart": 6844, + "commentStart": 6982, "elements": [ { - "commentStart": 6853, + "commentStart": 6991, "end": 0, "left": { "abs_path": false, - "commentStart": 6853, + "commentStart": 6991, "end": 0, "name": { - "commentStart": 6853, + "commentStart": 6991, "end": 0, "name": "handleFillet", "start": 0, @@ -10298,10 +10298,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 6868, + "commentStart": 7006, "end": 0, "name": { - "commentStart": 6868, + "commentStart": 7006, "end": 0, "name": "handleOffset", "start": 0, @@ -10319,10 +10319,10 @@ description: Result of parsing dual-basin-utility-sink.kcl { "argument": { "abs_path": false, - "commentStart": 6890, + "commentStart": 7028, "end": 0, "name": { - "commentStart": 6890, + "commentStart": 7028, "end": 0, "name": "handleDepth", "start": 0, @@ -10333,162 +10333,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "Name", "type": "Name" }, - "commentStart": 6889, - "end": 0, - "operator": "-", - "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" - } - ], - "end": 0, - "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" - }, - { - "commentStart": 6910, - "end": 0, - "start": 0, - "type": "PipeSubstitution", - "type": "PipeSubstitution" - } - ], - "callee": { - "abs_path": false, - "commentStart": 6828, - "end": 0, - "name": { - "commentStart": 6828, - "end": 0, - "name": "tangentialArcTo", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name" - }, - "commentStart": 6828, - "end": 0, - "start": 0, - "type": "CallExpression", - "type": "CallExpression" - }, - { - "arguments": [ - { - "type": "LabeledArg", - "label": { - "commentStart": 6924, - "end": 0, - "name": "length", - "start": 0, - "type": "Identifier" - }, - "arg": { - "abs_path": false, - "commentStart": 6931, - "end": 0, - "name": { - "commentStart": 6931, - "end": 0, - "name": "handleLengthSegmentB", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - } - } - ], - "callee": { - "abs_path": false, - "commentStart": 6918, - "end": 0, - "name": { - "commentStart": 6918, - "end": 0, - "name": "xLine", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name" - }, - "commentStart": 6918, - "end": 0, - "start": 0, - "type": "CallExpressionKw", - "type": "CallExpressionKw", - "unlabeled": null - }, - { - "arguments": [ - { - "commentStart": 6974, - "elements": [ - { - "commentStart": 6983, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 6983, - "end": 0, - "name": { - "commentStart": 6983, - "end": 0, - "name": "handleOffset", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "+", - "right": { - "abs_path": false, - "commentStart": 6998, - "end": 0, - "name": { - "commentStart": 6998, - "end": 0, - "name": "handleWidth", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - { - "argument": { - "abs_path": false, - "commentStart": 7019, - "end": 0, - "name": { - "commentStart": 7019, - "end": 0, - "name": "handleLengthSegmentA", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "commentStart": 7018, + "commentStart": 7027, "end": 0, "operator": "-", "start": 0, @@ -10511,10 +10356,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 6958, + "commentStart": 6966, "end": 0, "name": { - "commentStart": 6958, + "commentStart": 6966, "end": 0, "name": "tangentialArcTo", "start": 0, @@ -10524,7 +10369,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 6958, + "commentStart": 6966, "end": 0, "start": 0, "type": "CallExpression", @@ -10543,12 +10388,12 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 7069, + "commentStart": 7071, "end": 0, "name": { - "commentStart": 7069, + "commentStart": 7071, "end": 0, - "name": "handleLengthSegmentA", + "name": "handleLengthSegmentB", "start": 0, "type": "Identifier" }, @@ -10566,7 +10411,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "name": { "commentStart": 7056, "end": 0, - "name": "yLine", + "name": "xLine", "start": 0, "type": "Identifier" }, @@ -10580,9 +10425,164 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": null + }, + { + "arguments": [ + { + "commentStart": 7114, + "elements": [ + { + "commentStart": 7123, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 7123, + "end": 0, + "name": { + "commentStart": 7123, + "end": 0, + "name": "handleOffset", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "+", + "right": { + "abs_path": false, + "commentStart": 7138, + "end": 0, + "name": { + "commentStart": 7138, + "end": 0, + "name": "handleWidth", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + { + "argument": { + "abs_path": false, + "commentStart": 7159, + "end": 0, + "name": { + "commentStart": 7159, + "end": 0, + "name": "handleLengthSegmentA", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "commentStart": 7158, + "end": 0, + "operator": "-", + "start": 0, + "type": "UnaryExpression", + "type": "UnaryExpression" + } + ], + "end": 0, + "start": 0, + "type": "ArrayExpression", + "type": "ArrayExpression" + }, + { + "commentStart": 7188, + "end": 0, + "start": 0, + "type": "PipeSubstitution", + "type": "PipeSubstitution" + } + ], + "callee": { + "abs_path": false, + "commentStart": 7098, + "end": 0, + "name": { + "commentStart": 7098, + "end": 0, + "name": "tangentialArcTo", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name" + }, + "commentStart": 7098, + "end": 0, + "start": 0, + "type": "CallExpression", + "type": "CallExpression" + }, + { + "arguments": [ + { + "type": "LabeledArg", + "label": { + "commentStart": 7202, + "end": 0, + "name": "length", + "start": 0, + "type": "Identifier" + }, + "arg": { + "abs_path": false, + "commentStart": 7211, + "end": 0, + "name": { + "commentStart": 7211, + "end": 0, + "name": "handleLengthSegmentA", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + } + } + ], + "callee": { + "abs_path": false, + "commentStart": 7196, + "end": 0, + "name": { + "commentStart": 7196, + "end": 0, + "name": "yLine", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name" + }, + "commentStart": 7196, + "end": 0, + "start": 0, + "type": "CallExpressionKw", + "type": "CallExpressionKw", + "unlabeled": null } ], - "commentStart": 6731, + "commentStart": 6867, "end": 0, "start": 0, "type": "PipeExpression", @@ -10598,12 +10598,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 7091, + "commentStart": 7233, "declaration": { - "commentStart": 7091, + "commentStart": 7233, "end": 0, "id": { - "commentStart": 7091, + "commentStart": 7233, "end": 0, "name": "handleSectionPlane", "start": 0, @@ -10613,10 +10613,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "arguments": [ { "abs_path": false, - "commentStart": 7126, + "commentStart": 7268, "end": 0, "name": { - "commentStart": 7126, + "commentStart": 7268, "end": 0, "name": "XZ", "start": 0, @@ -10630,10 +10630,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 7112, + "commentStart": 7254, "end": 0, "name": { - "commentStart": 7112, + "commentStart": 7254, "end": 0, "name": "startSketchOn", "start": 0, @@ -10643,7 +10643,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 7112, + "commentStart": 7254, "end": 0, "start": 0, "type": "CallExpression", @@ -10659,12 +10659,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 7130, + "commentStart": 7272, "declaration": { - "commentStart": 7130, + "commentStart": 7272, "end": 0, "id": { - "commentStart": 7130, + "commentStart": 7272, "end": 0, "name": "handleProfileSection", "start": 0, @@ -10675,21 +10675,21 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 7185, + "commentStart": 7327, "end": 0, "name": "center", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 7194, + "commentStart": 7336, "elements": [ { "abs_path": false, - "commentStart": 7195, + "commentStart": 7342, "end": 0, "name": { - "commentStart": 7195, + "commentStart": 7342, "end": 0, "name": "handleOffset", "start": 0, @@ -10702,10 +10702,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, { "abs_path": false, - "commentStart": 7209, + "commentStart": 7360, "end": 0, "name": { - "commentStart": 7209, + "commentStart": 7360, "end": 0, "name": "handleHeightAboveTheFloor", "start": 0, @@ -10726,14 +10726,14 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 7239, + "commentStart": 7393, "end": 0, "name": "radius", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 7248, + "commentStart": 7402, "end": 0, "raw": "2", "start": 0, @@ -10748,10 +10748,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 7153, + "commentStart": 7295, "end": 0, "name": { - "commentStart": 7153, + "commentStart": 7295, "end": 0, "name": "circle", "start": 0, @@ -10761,17 +10761,17 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 7153, + "commentStart": 7295, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 7163, + "commentStart": 7305, "end": 0, "name": { - "commentStart": 7163, + "commentStart": 7305, "end": 0, "name": "handleSectionPlane", "start": 0, @@ -10793,12 +10793,12 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "VariableDeclaration" }, { - "commentStart": 7254, + "commentStart": 7407, "declaration": { - "commentStart": 7254, + "commentStart": 7407, "end": 0, "id": { - "commentStart": 7254, + "commentStart": 7407, "end": 0, "name": "handleBody", "start": 0, @@ -10811,7 +10811,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 7295, + "commentStart": 7448, "end": 0, "name": "path", "start": 0, @@ -10819,10 +10819,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 7302, + "commentStart": 7455, "end": 0, "name": { - "commentStart": 7302, + "commentStart": 7455, "end": 0, "name": "handleProfilePath", "start": 0, @@ -10837,10 +10837,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 7267, + "commentStart": 7420, "end": 0, "name": { - "commentStart": 7267, + "commentStart": 7420, "end": 0, "name": "sweep", "start": 0, @@ -10850,17 +10850,17 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 7267, + "commentStart": 7420, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 7273, + "commentStart": 7426, "end": 0, "name": { - "commentStart": 7273, + "commentStart": 7426, "end": 0, "name": "handleProfileSection", "start": 0, @@ -10877,17 +10877,17 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 7342, + "commentStart": 7495, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 7349, + "commentStart": 7502, "elements": [ { - "commentStart": 7350, + "commentStart": 7503, "end": 0, "raw": "1", "start": 0, @@ -10899,7 +10899,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 7353, + "commentStart": 7506, "end": 0, "raw": "0", "start": 0, @@ -10911,7 +10911,7 @@ description: Result of parsing dual-basin-utility-sink.kcl } }, { - "commentStart": 7356, + "commentStart": 7509, "end": 0, "raw": "0", "start": 0, @@ -10932,7 +10932,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 7360, + "commentStart": 7513, "end": 0, "name": "instances", "start": 0, @@ -10940,10 +10940,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 7372, + "commentStart": 7525, "end": 0, "name": { - "commentStart": 7372, + "commentStart": 7525, "end": 0, "name": "doorCount", "start": 0, @@ -10958,7 +10958,7 @@ description: Result of parsing dual-basin-utility-sink.kcl { "type": "LabeledArg", "label": { - "commentStart": 7383, + "commentStart": 7536, "end": 0, "name": "distance", "start": 0, @@ -10966,10 +10966,10 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "arg": { "abs_path": false, - "commentStart": 7394, + "commentStart": 7547, "end": 0, "name": { - "commentStart": 7394, + "commentStart": 7547, "end": 0, "name": "blockSubdivisionWidth", "start": 0, @@ -10984,10 +10984,10 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "callee": { "abs_path": false, - "commentStart": 7326, + "commentStart": 7479, "end": 0, "name": { - "commentStart": 7326, + "commentStart": 7479, "end": 0, "name": "patternLinear3d", "start": 0, @@ -10997,7 +10997,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "start": 0, "type": "Name" }, - "commentStart": 7326, + "commentStart": 7479, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -11005,7 +11005,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "unlabeled": null } ], - "commentStart": 7267, + "commentStart": 7420, "end": 0, "start": 0, "type": "PipeExpression", @@ -11028,18 +11028,25 @@ description: Result of parsing dual-basin-utility-sink.kcl "commentStart": 0, "end": 0, "name": { - "commentStart": 133, + "commentStart": 146, "end": 0, "name": "settings", "start": 0, "type": "Identifier" }, + "preComments": [ + "// Dual-Basin Utility Sink", + "// A stainless steel sink unit with dual rectangular basins and six under-counter storage compartments.", + "", + "", + "// set units" + ], "properties": [ { - "commentStart": 142, + "commentStart": 155, "end": 0, "key": { - "commentStart": 142, + "commentStart": 155, "end": 0, "name": "defaultLengthUnit", "start": 0, @@ -11049,10 +11056,10 @@ description: Result of parsing dual-basin-utility-sink.kcl "type": "ObjectProperty", "value": { "abs_path": false, - "commentStart": 162, + "commentStart": 175, "end": 0, "name": { - "commentStart": 162, + "commentStart": 175, "end": 0, "name": "mm", "start": 0, @@ -11073,7 +11080,7 @@ description: Result of parsing dual-basin-utility-sink.kcl "nonCodeNodes": { "2": [ { - "commentStart": 230, + "commentStart": 243, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11084,7 +11091,7 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "4": [ { - "commentStart": 272, + "commentStart": 285, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11095,7 +11102,7 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "8": [ { - "commentStart": 427, + "commentStart": 442, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11106,7 +11113,7 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "13": [ { - "commentStart": 635, + "commentStart": 650, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11117,7 +11124,7 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "16": [ { - "commentStart": 1152, + "commentStart": 1173, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11128,7 +11135,7 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "18": [ { - "commentStart": 1692, + "commentStart": 1719, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11139,7 +11146,7 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "23": [ { - "commentStart": 2376, + "commentStart": 2411, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11150,7 +11157,7 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "25": [ { - "commentStart": 2913, + "commentStart": 2954, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11161,7 +11168,7 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "26": [ { - "commentStart": 3263, + "commentStart": 3310, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11172,7 +11179,7 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "30": [ { - "commentStart": 4036, + "commentStart": 4097, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11183,7 +11190,7 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "37": [ { - "commentStart": 4199, + "commentStart": 4264, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11194,7 +11201,7 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "39": [ { - "commentStart": 4626, + "commentStart": 4697, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11205,7 +11212,7 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "47": [ { - "commentStart": 5448, + "commentStart": 5570, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11216,7 +11223,7 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "60": [ { - "commentStart": 6627, + "commentStart": 6763, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11227,7 +11234,7 @@ description: Result of parsing dual-basin-utility-sink.kcl ], "61": [ { - "commentStart": 6709, + "commentStart": 6845, "end": 0, "start": 0, "type": "NonCodeNode", @@ -11239,38 +11246,7 @@ description: Result of parsing dual-basin-utility-sink.kcl }, "startNodes": [ { - "commentStart": 0, - "end": 0, - "start": 0, - "type": "NonCodeNode", - "value": { - "type": "blockComment", - "value": "Dual-Basin Utility Sink", - "style": "line" - } - }, - { - "commentStart": 27, - "end": 0, - "start": 0, - "type": "NonCodeNode", - "value": { - "type": "blockComment", - "value": "A stainless steel sink unit with dual rectangular basins and six under-counter storage compartments.", - "style": "line" - } - }, - { - "commentStart": 130, - "end": 0, - "start": 0, - "type": "NonCodeNode", - "value": { - "type": "newLine" - } - }, - { - "commentStart": 165, + "commentStart": 178, "end": 0, "start": 0, "type": "NonCodeNode", diff --git a/rust/kcl-lib/tests/kcl_samples/enclosure/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/enclosure/artifact_commands.snap index 11a7529ad..334e24779 100644 --- a/rust/kcl-lib/tests/kcl_samples/enclosure/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/enclosure/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands enclosure.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/exhaust-manifold/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/exhaust-manifold/artifact_commands.snap index e7fea3b8a..4968f640a 100644 --- a/rust/kcl-lib/tests/kcl_samples/exhaust-manifold/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/exhaust-manifold/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands exhaust-manifold.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/flange/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/flange/artifact_commands.snap index 835610aa2..c13d2870a 100644 --- a/rust/kcl-lib/tests/kcl_samples/flange/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/flange/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands flange.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/focusrite-scarlett-mounting-bracket/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/focusrite-scarlett-mounting-bracket/artifact_commands.snap index bc02edbea..44bcedd6c 100644 --- a/rust/kcl-lib/tests/kcl_samples/focusrite-scarlett-mounting-bracket/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/focusrite-scarlett-mounting-bracket/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands focusrite-scarlett-mounting-bracket.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/food-service-spatula/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/food-service-spatula/artifact_commands.snap index 1538a9aa0..c20d6b22b 100644 --- a/rust/kcl-lib/tests/kcl_samples/food-service-spatula/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/food-service-spatula/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands food-service-spatula.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/french-press/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/french-press/artifact_commands.snap index 5508e13f0..3182990a1 100644 --- a/rust/kcl-lib/tests/kcl_samples/french-press/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/french-press/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands french-press.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/gear-rack/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/gear-rack/artifact_commands.snap index faf4d0f4c..f789357f8 100644 --- a/rust/kcl-lib/tests/kcl_samples/gear-rack/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/gear-rack/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands gear-rack.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/gear/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/gear/artifact_commands.snap index 70d533196..0097d3c9b 100644 --- a/rust/kcl-lib/tests/kcl_samples/gear/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/gear/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands gear.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate-magnets/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate-magnets/artifact_commands.snap index 44c76df75..7f7b50489 100644 --- a/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate-magnets/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate-magnets/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands gridfinity-baseplate-magnets.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate/artifact_commands.snap index 84bf27b5a..2d73345a0 100644 --- a/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/gridfinity-baseplate/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands gridfinity-baseplate.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/gridfinity-bins-stacking-lip/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/gridfinity-bins-stacking-lip/artifact_commands.snap index abaa5ce87..d0566743f 100644 --- a/rust/kcl-lib/tests/kcl_samples/gridfinity-bins-stacking-lip/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/gridfinity-bins-stacking-lip/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands gridfinity-bins-stacking-lip.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/gridfinity-bins/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/gridfinity-bins/artifact_commands.snap index d03ddbd80..1698809ec 100644 --- a/rust/kcl-lib/tests/kcl_samples/gridfinity-bins/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/gridfinity-bins/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands gridfinity-bins.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/hex-nut/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/hex-nut/artifact_commands.snap index 27e46fe6a..906fc6cf7 100644 --- a/rust/kcl-lib/tests/kcl_samples/hex-nut/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/hex-nut/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands hex-nut.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/i-beam/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/i-beam/artifact_commands.snap index 3f41ea273..82ddc2934 100644 --- a/rust/kcl-lib/tests/kcl_samples/i-beam/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/i-beam/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands i-beam.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/i-beam/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/kcl_samples/i-beam/artifact_graph_flowchart.snap.md index 2364b74d4..26a9cf10f 100644 --- a/rust/kcl-lib/tests/kcl_samples/i-beam/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/kcl_samples/i-beam/artifact_graph_flowchart.snap.md @@ -1,15 +1,15 @@ ```mermaid flowchart LR subgraph path2 [Path] - 2["Path
[469, 507, 0]"] - 3["Segment
[513, 544, 0]"] - 4["Segment
[550, 582, 0]"] - 5["Segment
[588, 638, 0]"] - 6["Segment
[644, 698, 0]"] - 7["Segment
[704, 726, 0]"] + 2["Path
[471, 509, 0]"] + 3["Segment
[515, 546, 0]"] + 4["Segment
[552, 584, 0]"] + 5["Segment
[590, 640, 0]"] + 6["Segment
[646, 700, 0]"] + 7["Segment
[706, 728, 0]"] end - 1["Plane
[445, 463, 0]"] - 8["Sweep Extrusion
[798, 826, 0]"] + 1["Plane
[447, 465, 0]"] + 8["Sweep Extrusion
[800, 828, 0]"] 1 --- 2 2 --- 3 2 --- 4 diff --git a/rust/kcl-lib/tests/kcl_samples/i-beam/ast.snap b/rust/kcl-lib/tests/kcl_samples/i-beam/ast.snap index 5a8c3cd0a..81bcd767c 100644 --- a/rust/kcl-lib/tests/kcl_samples/i-beam/ast.snap +++ b/rust/kcl-lib/tests/kcl_samples/i-beam/ast.snap @@ -37,10 +37,10 @@ description: Result of parsing i-beam.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 203, + "commentStart": 205, "end": 0, "name": { - "commentStart": 203, + "commentStart": 205, "end": 0, "name": "ft", "start": 0, @@ -50,7 +50,7 @@ description: Result of parsing i-beam.kcl "start": 0, "type": "Name" }, - "commentStart": 203, + "commentStart": 205, "end": 0, "start": 0, "type": "CallExpression", @@ -73,19 +73,19 @@ description: Result of parsing i-beam.kcl "type": "VariableDeclaration" }, { - "commentStart": 208, + "commentStart": 210, "declaration": { - "commentStart": 208, + "commentStart": 210, "end": 0, "id": { - "commentStart": 208, + "commentStart": 210, "end": 0, "name": "beamHeight", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 221, + "commentStart": 223, "end": 0, "raw": "4", "start": 0, @@ -106,19 +106,19 @@ description: Result of parsing i-beam.kcl "type": "VariableDeclaration" }, { - "commentStart": 223, + "commentStart": 225, "declaration": { - "commentStart": 223, + "commentStart": 225, "end": 0, "id": { - "commentStart": 223, + "commentStart": 225, "end": 0, "name": "flangeWidth", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 237, + "commentStart": 239, "end": 0, "raw": "2.663", "start": 0, @@ -139,19 +139,19 @@ description: Result of parsing i-beam.kcl "type": "VariableDeclaration" }, { - "commentStart": 243, + "commentStart": 245, "declaration": { - "commentStart": 243, + "commentStart": 245, "end": 0, "id": { - "commentStart": 243, + "commentStart": 245, "end": 0, "name": "flangeThickness", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 261, + "commentStart": 263, "end": 0, "raw": "0.293", "start": 0, @@ -172,19 +172,19 @@ description: Result of parsing i-beam.kcl "type": "VariableDeclaration" }, { - "commentStart": 267, + "commentStart": 269, "declaration": { - "commentStart": 267, + "commentStart": 269, "end": 0, "id": { - "commentStart": 267, + "commentStart": 269, "end": 0, "name": "webThickness", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 282, + "commentStart": 284, "end": 0, "raw": "0.193", "start": 0, @@ -205,19 +205,19 @@ description: Result of parsing i-beam.kcl "type": "VariableDeclaration" }, { - "commentStart": 288, + "commentStart": 290, "declaration": { - "commentStart": 288, + "commentStart": 290, "end": 0, "id": { - "commentStart": 288, + "commentStart": 290, "end": 0, "name": "rootRadius", "start": 0, "type": "Identifier" }, "init": { - "commentStart": 301, + "commentStart": 303, "end": 0, "raw": "0.457", "start": 0, @@ -238,12 +238,12 @@ description: Result of parsing i-beam.kcl "type": "VariableDeclaration" }, { - "commentStart": 306, + "commentStart": 308, "declaration": { - "commentStart": 433, + "commentStart": 435, "end": 0, "id": { - "commentStart": 433, + "commentStart": 435, "end": 0, "name": "sketch001", "start": 0, @@ -256,10 +256,10 @@ description: Result of parsing i-beam.kcl { "argument": { "abs_path": false, - "commentStart": 460, + "commentStart": 462, "end": 0, "name": { - "commentStart": 460, + "commentStart": 462, "end": 0, "name": "XZ", "start": 0, @@ -270,7 +270,7 @@ description: Result of parsing i-beam.kcl "type": "Name", "type": "Name" }, - "commentStart": 459, + "commentStart": 461, "end": 0, "operator": "-", "start": 0, @@ -280,10 +280,10 @@ description: Result of parsing i-beam.kcl ], "callee": { "abs_path": false, - "commentStart": 445, + "commentStart": 447, "end": 0, "name": { - "commentStart": 445, + "commentStart": 447, "end": 0, "name": "startSketchOn", "start": 0, @@ -293,7 +293,7 @@ description: Result of parsing i-beam.kcl "start": 0, "type": "Name" }, - "commentStart": 445, + "commentStart": 447, "end": 0, "start": 0, "type": "CallExpression", @@ -302,10 +302,10 @@ description: Result of parsing i-beam.kcl { "arguments": [ { - "commentStart": 484, + "commentStart": 486, "elements": [ { - "commentStart": 485, + "commentStart": 487, "end": 0, "raw": "0", "start": 0, @@ -317,14 +317,14 @@ description: Result of parsing i-beam.kcl } }, { - "commentStart": 488, + "commentStart": 490, "end": 0, "left": { "abs_path": false, - "commentStart": 488, + "commentStart": 490, "end": 0, "name": { - "commentStart": 488, + "commentStart": 490, "end": 0, "name": "beamHeight", "start": 0, @@ -337,7 +337,7 @@ description: Result of parsing i-beam.kcl }, "operator": "/", "right": { - "commentStart": 501, + "commentStart": 503, "end": 0, "raw": "2", "start": 0, @@ -359,7 +359,7 @@ description: Result of parsing i-beam.kcl "type": "ArrayExpression" }, { - "commentStart": 505, + "commentStart": 507, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -368,10 +368,10 @@ description: Result of parsing i-beam.kcl ], "callee": { "abs_path": false, - "commentStart": 469, + "commentStart": 471, "end": 0, "name": { - "commentStart": 469, + "commentStart": 471, "end": 0, "name": "startProfileAt", "start": 0, @@ -381,7 +381,7 @@ description: Result of parsing i-beam.kcl "start": 0, "type": "Name" }, - "commentStart": 469, + "commentStart": 471, "end": 0, "start": 0, "type": "CallExpression", @@ -392,21 +392,21 @@ description: Result of parsing i-beam.kcl { "type": "LabeledArg", "label": { - "commentStart": 519, + "commentStart": 521, "end": 0, "name": "length", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 528, + "commentStart": 530, "end": 0, "left": { "abs_path": false, - "commentStart": 528, + "commentStart": 530, "end": 0, "name": { - "commentStart": 528, + "commentStart": 530, "end": 0, "name": "flangeWidth", "start": 0, @@ -419,7 +419,7 @@ description: Result of parsing i-beam.kcl }, "operator": "/", "right": { - "commentStart": 542, + "commentStart": 544, "end": 0, "raw": "2", "start": 0, @@ -438,10 +438,10 @@ description: Result of parsing i-beam.kcl ], "callee": { "abs_path": false, - "commentStart": 513, + "commentStart": 515, "end": 0, "name": { - "commentStart": 513, + "commentStart": 515, "end": 0, "name": "xLine", "start": 0, @@ -451,7 +451,7 @@ description: Result of parsing i-beam.kcl "start": 0, "type": "Name" }, - "commentStart": 513, + "commentStart": 515, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -463,7 +463,7 @@ description: Result of parsing i-beam.kcl { "type": "LabeledArg", "label": { - "commentStart": 556, + "commentStart": 558, "end": 0, "name": "length", "start": 0, @@ -472,10 +472,10 @@ description: Result of parsing i-beam.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 566, + "commentStart": 568, "end": 0, "name": { - "commentStart": 566, + "commentStart": 568, "end": 0, "name": "flangeThickness", "start": 0, @@ -486,7 +486,7 @@ description: Result of parsing i-beam.kcl "type": "Name", "type": "Name" }, - "commentStart": 565, + "commentStart": 567, "end": 0, "operator": "-", "start": 0, @@ -497,10 +497,10 @@ description: Result of parsing i-beam.kcl ], "callee": { "abs_path": false, - "commentStart": 550, + "commentStart": 552, "end": 0, "name": { - "commentStart": 550, + "commentStart": 552, "end": 0, "name": "yLine", "start": 0, @@ -510,7 +510,7 @@ description: Result of parsing i-beam.kcl "start": 0, "type": "Name" }, - "commentStart": 550, + "commentStart": 552, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -522,24 +522,24 @@ description: Result of parsing i-beam.kcl { "type": "LabeledArg", "label": { - "commentStart": 594, + "commentStart": 596, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 608, + "commentStart": 610, "end": 0, "left": { - "commentStart": 608, + "commentStart": 610, "end": 0, "left": { "abs_path": false, - "commentStart": 608, + "commentStart": 610, "end": 0, "name": { - "commentStart": 608, + "commentStart": 610, "end": 0, "name": "webThickness", "start": 0, @@ -552,7 +552,7 @@ description: Result of parsing i-beam.kcl }, "operator": "/", "right": { - "commentStart": 623, + "commentStart": 625, "end": 0, "raw": "2", "start": 0, @@ -570,10 +570,10 @@ description: Result of parsing i-beam.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 627, + "commentStart": 629, "end": 0, "name": { - "commentStart": 627, + "commentStart": 629, "end": 0, "name": "rootRadius", "start": 0, @@ -592,10 +592,10 @@ description: Result of parsing i-beam.kcl ], "callee": { "abs_path": false, - "commentStart": 588, + "commentStart": 590, "end": 0, "name": { - "commentStart": 588, + "commentStart": 590, "end": 0, "name": "xLine", "start": 0, @@ -605,7 +605,7 @@ description: Result of parsing i-beam.kcl "start": 0, "type": "Name" }, - "commentStart": 588, + "commentStart": 590, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -615,14 +615,14 @@ description: Result of parsing i-beam.kcl { "arguments": [ { - "commentStart": 658, + "commentStart": 660, "end": 0, "properties": [ { - "commentStart": 660, + "commentStart": 662, "end": 0, "key": { - "commentStart": 660, + "commentStart": 662, "end": 0, "name": "radius", "start": 0, @@ -632,10 +632,10 @@ description: Result of parsing i-beam.kcl "type": "ObjectProperty", "value": { "abs_path": false, - "commentStart": 669, + "commentStart": 671, "end": 0, "name": { - "commentStart": 669, + "commentStart": 671, "end": 0, "name": "rootRadius", "start": 0, @@ -648,10 +648,10 @@ description: Result of parsing i-beam.kcl } }, { - "commentStart": 681, + "commentStart": 683, "end": 0, "key": { - "commentStart": 681, + "commentStart": 683, "end": 0, "name": "offset", "start": 0, @@ -660,7 +660,7 @@ description: Result of parsing i-beam.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 690, + "commentStart": 692, "end": 0, "raw": "90", "start": 0, @@ -678,7 +678,7 @@ description: Result of parsing i-beam.kcl "type": "ObjectExpression" }, { - "commentStart": 696, + "commentStart": 698, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -687,10 +687,10 @@ description: Result of parsing i-beam.kcl ], "callee": { "abs_path": false, - "commentStart": 644, + "commentStart": 646, "end": 0, "name": { - "commentStart": 644, + "commentStart": 646, "end": 0, "name": "tangentialArc", "start": 0, @@ -700,7 +700,7 @@ description: Result of parsing i-beam.kcl "start": 0, "type": "Name" }, - "commentStart": 644, + "commentStart": 646, "end": 0, "start": 0, "type": "CallExpression", @@ -711,14 +711,14 @@ description: Result of parsing i-beam.kcl { "type": "LabeledArg", "label": { - "commentStart": 710, + "commentStart": 712, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 724, + "commentStart": 726, "end": 0, "raw": "0", "start": 0, @@ -733,10 +733,10 @@ description: Result of parsing i-beam.kcl ], "callee": { "abs_path": false, - "commentStart": 704, + "commentStart": 706, "end": 0, "name": { - "commentStart": 704, + "commentStart": 706, "end": 0, "name": "yLine", "start": 0, @@ -746,7 +746,7 @@ description: Result of parsing i-beam.kcl "start": 0, "type": "Name" }, - "commentStart": 704, + "commentStart": 706, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -756,14 +756,14 @@ description: Result of parsing i-beam.kcl { "arguments": [ { - "commentStart": 741, + "commentStart": 743, "end": 0, "properties": [ { - "commentStart": 743, + "commentStart": 745, "end": 0, "key": { - "commentStart": 743, + "commentStart": 745, "end": 0, "name": "axis", "start": 0, @@ -772,7 +772,7 @@ description: Result of parsing i-beam.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 750, + "commentStart": 752, "end": 0, "raw": "'X'", "start": 0, @@ -787,7 +787,7 @@ description: Result of parsing i-beam.kcl "type": "ObjectExpression" }, { - "commentStart": 757, + "commentStart": 759, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -796,10 +796,10 @@ description: Result of parsing i-beam.kcl ], "callee": { "abs_path": false, - "commentStart": 732, + "commentStart": 734, "end": 0, "name": { - "commentStart": 732, + "commentStart": 734, "end": 0, "name": "mirror2d", "start": 0, @@ -809,7 +809,7 @@ description: Result of parsing i-beam.kcl "start": 0, "type": "Name" }, - "commentStart": 732, + "commentStart": 734, "end": 0, "start": 0, "type": "CallExpression", @@ -818,14 +818,14 @@ description: Result of parsing i-beam.kcl { "arguments": [ { - "commentStart": 774, + "commentStart": 776, "end": 0, "properties": [ { - "commentStart": 776, + "commentStart": 778, "end": 0, "key": { - "commentStart": 776, + "commentStart": 778, "end": 0, "name": "axis", "start": 0, @@ -834,7 +834,7 @@ description: Result of parsing i-beam.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 783, + "commentStart": 785, "end": 0, "raw": "'Y'", "start": 0, @@ -849,7 +849,7 @@ description: Result of parsing i-beam.kcl "type": "ObjectExpression" }, { - "commentStart": 790, + "commentStart": 792, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -858,10 +858,10 @@ description: Result of parsing i-beam.kcl ], "callee": { "abs_path": false, - "commentStart": 765, + "commentStart": 767, "end": 0, "name": { - "commentStart": 765, + "commentStart": 767, "end": 0, "name": "mirror2d", "start": 0, @@ -871,7 +871,7 @@ description: Result of parsing i-beam.kcl "start": 0, "type": "Name" }, - "commentStart": 765, + "commentStart": 767, "end": 0, "start": 0, "type": "CallExpression", @@ -882,7 +882,7 @@ description: Result of parsing i-beam.kcl { "type": "LabeledArg", "label": { - "commentStart": 806, + "commentStart": 808, "end": 0, "name": "length", "start": 0, @@ -890,10 +890,10 @@ description: Result of parsing i-beam.kcl }, "arg": { "abs_path": false, - "commentStart": 815, + "commentStart": 817, "end": 0, "name": { - "commentStart": 815, + "commentStart": 817, "end": 0, "name": "beamLength", "start": 0, @@ -908,10 +908,10 @@ description: Result of parsing i-beam.kcl ], "callee": { "abs_path": false, - "commentStart": 798, + "commentStart": 800, "end": 0, "name": { - "commentStart": 798, + "commentStart": 800, "end": 0, "name": "extrude", "start": 0, @@ -921,7 +921,7 @@ description: Result of parsing i-beam.kcl "start": 0, "type": "Name" }, - "commentStart": 798, + "commentStart": 800, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -929,7 +929,7 @@ description: Result of parsing i-beam.kcl "unlabeled": null } ], - "commentStart": 445, + "commentStart": 447, "end": 0, "start": 0, "type": "PipeExpression", @@ -1021,4 +1021,4 @@ description: Result of parsing i-beam.kcl }, "start": 0 } -} \ No newline at end of file +} diff --git a/rust/kcl-lib/tests/kcl_samples/keyboard/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/keyboard/artifact_commands.snap index 704efd8f5..b715a9bec 100644 --- a/rust/kcl-lib/tests/kcl_samples/keyboard/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/keyboard/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands keyboard.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/kitt/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/kitt/artifact_commands.snap index 31d5fbc5e..27f8b072f 100644 --- a/rust/kcl-lib/tests/kcl_samples/kitt/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/kitt/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands kitt.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/lego/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/lego/artifact_commands.snap index 181d73a78..c00b95574 100644 --- a/rust/kcl-lib/tests/kcl_samples/lego/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/lego/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands lego.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/makeup-mirror/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/makeup-mirror/artifact_commands.snap index 714331e8b..938ecf4ba 100644 --- a/rust/kcl-lib/tests/kcl_samples/makeup-mirror/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/makeup-mirror/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands makeup-mirror.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/makeup-mirror/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/kcl_samples/makeup-mirror/artifact_graph_flowchart.snap.md index 563ec92d4..0c5243f57 100644 --- a/rust/kcl-lib/tests/kcl_samples/makeup-mirror/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/kcl_samples/makeup-mirror/artifact_graph_flowchart.snap.md @@ -46,17 +46,17 @@ flowchart LR 84[Solid2d] end subgraph path92 [Path] - 92["Path
[1553, 1616, 0]"] - 93["Segment
[1553, 1616, 0]"] + 92["Path
[1555, 1618, 0]"] + 93["Segment
[1555, 1618, 0]"] 94[Solid2d] end subgraph path101 [Path] - 101["Path
[1662, 1716, 0]"] - 102["Segment
[1724, 1748, 0]"] - 103["Segment
[1756, 1870, 0]"] - 104["Segment
[1878, 1902, 0]"] - 105["Segment
[1910, 2041, 0]"] - 106["Segment
[2049, 2056, 0]"] + 101["Path
[1664, 1720, 0]"] + 102["Segment
[1728, 1752, 0]"] + 103["Segment
[1760, 1878, 0]"] + 104["Segment
[1886, 1910, 0]"] + 105["Segment
[1918, 2086, 0]"] + 106["Segment
[2094, 2101, 0]"] 107[Solid2d] end 1["Plane
[484, 511, 0]"] @@ -122,14 +122,14 @@ flowchart LR 88["Cap End"] 89["SweepEdge Opposite"] 90["SweepEdge Adjacent"] - 91["Plane
[1489, 1539, 0]"] - 95["Sweep Extrusion
[1624, 1647, 0]"] + 91["Plane
[1491, 1541, 0]"] + 95["Sweep Extrusion
[1626, 1649, 0]"] 96[Wall] 97["Cap Start"] 98["Cap End"] 99["SweepEdge Opposite"] 100["SweepEdge Adjacent"] - 108["Sweep Extrusion
[2064, 2087, 0]"] + 108["Sweep Extrusion
[2109, 2132, 0]"] 109[Wall] 110[Wall] 111[Wall] @@ -151,7 +151,7 @@ flowchart LR 127["StartSketchOnPlane
[470, 512, 0]"] 128["StartSketchOnPlane
[470, 512, 0]"] 129["StartSketchOnPlane
[470, 512, 0]"] - 130["StartSketchOnPlane
[1475, 1540, 0]"] + 130["StartSketchOnPlane
[1475, 1542, 0]"] 1 --- 2 2 --- 3 2 ---- 5 diff --git a/rust/kcl-lib/tests/kcl_samples/makeup-mirror/ast.snap b/rust/kcl-lib/tests/kcl_samples/makeup-mirror/ast.snap index 4c7510d45..f86ac1796 100644 --- a/rust/kcl-lib/tests/kcl_samples/makeup-mirror/ast.snap +++ b/rust/kcl-lib/tests/kcl_samples/makeup-mirror/ast.snap @@ -2366,21 +2366,21 @@ description: Result of parsing makeup-mirror.kcl { "type": "LabeledArg", "label": { - "commentStart": 1508, + "commentStart": 1510, "end": 0, "name": "offset", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1517, + "commentStart": 1519, "end": 0, "left": { "abs_path": false, - "commentStart": 1517, + "commentStart": 1519, "end": 0, "name": { - "commentStart": 1517, + "commentStart": 1519, "end": 0, "name": "offsetY", "start": 0, @@ -2393,14 +2393,14 @@ description: Result of parsing makeup-mirror.kcl }, "operator": "-", "right": { - "commentStart": 1528, + "commentStart": 1530, "end": 0, "left": { "abs_path": false, - "commentStart": 1528, + "commentStart": 1530, "end": 0, "name": { - "commentStart": 1528, + "commentStart": 1530, "end": 0, "name": "tiefe", "start": 0, @@ -2413,7 +2413,7 @@ description: Result of parsing makeup-mirror.kcl }, "operator": "/", "right": { - "commentStart": 1536, + "commentStart": 1538, "end": 0, "raw": "2", "start": 0, @@ -2436,10 +2436,10 @@ description: Result of parsing makeup-mirror.kcl ], "callee": { "abs_path": false, - "commentStart": 1489, + "commentStart": 1491, "end": 0, "name": { - "commentStart": 1489, + "commentStart": 1491, "end": 0, "name": "offsetPlane", "start": 0, @@ -2449,17 +2449,17 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "Name" }, - "commentStart": 1489, + "commentStart": 1491, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 1501, + "commentStart": 1503, "end": 0, "name": { - "commentStart": 1501, + "commentStart": 1503, "end": 0, "name": "plane", "start": 0, @@ -2503,12 +2503,12 @@ description: Result of parsing makeup-mirror.kcl "type": "VariableDeclaration" }, { - "commentStart": 1543, + "commentStart": 1545, "declaration": { - "commentStart": 1543, + "commentStart": 1545, "end": 0, "id": { - "commentStart": 1543, + "commentStart": 1545, "end": 0, "name": "armBody", "start": 0, @@ -2521,21 +2521,21 @@ description: Result of parsing makeup-mirror.kcl { "type": "LabeledArg", "label": { - "commentStart": 1570, + "commentStart": 1572, "end": 0, "name": "center", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1579, + "commentStart": 1581, "elements": [ { "abs_path": false, - "commentStart": 1580, + "commentStart": 1582, "end": 0, "name": { - "commentStart": 1580, + "commentStart": 1582, "end": 0, "name": "offsetX", "start": 0, @@ -2548,10 +2548,10 @@ description: Result of parsing makeup-mirror.kcl }, { "abs_path": false, - "commentStart": 1589, + "commentStart": 1591, "end": 0, "name": { - "commentStart": 1589, + "commentStart": 1591, "end": 0, "name": "altitude", "start": 0, @@ -2572,7 +2572,7 @@ description: Result of parsing makeup-mirror.kcl { "type": "LabeledArg", "label": { - "commentStart": 1600, + "commentStart": 1602, "end": 0, "name": "radius", "start": 0, @@ -2580,10 +2580,10 @@ description: Result of parsing makeup-mirror.kcl }, "arg": { "abs_path": false, - "commentStart": 1609, + "commentStart": 1611, "end": 0, "name": { - "commentStart": 1609, + "commentStart": 1611, "end": 0, "name": "radius", "start": 0, @@ -2598,10 +2598,10 @@ description: Result of parsing makeup-mirror.kcl ], "callee": { "abs_path": false, - "commentStart": 1553, + "commentStart": 1555, "end": 0, "name": { - "commentStart": 1553, + "commentStart": 1555, "end": 0, "name": "circle", "start": 0, @@ -2611,17 +2611,17 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "Name" }, - "commentStart": 1553, + "commentStart": 1555, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 1560, + "commentStart": 1562, "end": 0, "name": { - "commentStart": 1560, + "commentStart": 1562, "end": 0, "name": "armPlane", "start": 0, @@ -2638,7 +2638,7 @@ description: Result of parsing makeup-mirror.kcl { "type": "LabeledArg", "label": { - "commentStart": 1632, + "commentStart": 1634, "end": 0, "name": "length", "start": 0, @@ -2646,10 +2646,10 @@ description: Result of parsing makeup-mirror.kcl }, "arg": { "abs_path": false, - "commentStart": 1641, + "commentStart": 1643, "end": 0, "name": { - "commentStart": 1641, + "commentStart": 1643, "end": 0, "name": "tiefe", "start": 0, @@ -2664,10 +2664,10 @@ description: Result of parsing makeup-mirror.kcl ], "callee": { "abs_path": false, - "commentStart": 1624, + "commentStart": 1626, "end": 0, "name": { - "commentStart": 1624, + "commentStart": 1626, "end": 0, "name": "extrude", "start": 0, @@ -2677,7 +2677,7 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "Name" }, - "commentStart": 1624, + "commentStart": 1626, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2685,7 +2685,7 @@ description: Result of parsing makeup-mirror.kcl "unlabeled": null } ], - "commentStart": 1553, + "commentStart": 1555, "end": 0, "start": 0, "type": "PipeExpression", @@ -2701,12 +2701,12 @@ description: Result of parsing makeup-mirror.kcl "type": "VariableDeclaration" }, { - "commentStart": 1647, + "commentStart": 1649, "declaration": { - "commentStart": 1651, + "commentStart": 1653, "end": 0, "id": { - "commentStart": 1651, + "commentStart": 1653, "end": 0, "name": "archBody", "start": 0, @@ -2717,17 +2717,17 @@ description: Result of parsing makeup-mirror.kcl { "arguments": [ { - "commentStart": 1677, + "commentStart": 1679, "elements": [ { - "commentStart": 1678, + "commentStart": 1680, "end": 0, "left": { "abs_path": false, - "commentStart": 1678, + "commentStart": 1680, "end": 0, "name": { - "commentStart": 1678, + "commentStart": 1680, "end": 0, "name": "offsetX", "start": 0, @@ -2741,10 +2741,10 @@ description: Result of parsing makeup-mirror.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 1686, + "commentStart": 1690, "end": 0, "name": { - "commentStart": 1686, + "commentStart": 1690, "end": 0, "name": "gestellR", "start": 0, @@ -2761,10 +2761,10 @@ description: Result of parsing makeup-mirror.kcl }, { "abs_path": false, - "commentStart": 1696, + "commentStart": 1700, "end": 0, "name": { - "commentStart": 1696, + "commentStart": 1700, "end": 0, "name": "altitude", "start": 0, @@ -2783,10 +2783,10 @@ description: Result of parsing makeup-mirror.kcl }, { "abs_path": false, - "commentStart": 1707, + "commentStart": 1711, "end": 0, "name": { - "commentStart": 1707, + "commentStart": 1711, "end": 0, "name": "armPlane", "start": 0, @@ -2800,10 +2800,10 @@ description: Result of parsing makeup-mirror.kcl ], "callee": { "abs_path": false, - "commentStart": 1662, + "commentStart": 1664, "end": 0, "name": { - "commentStart": 1662, + "commentStart": 1664, "end": 0, "name": "startProfileAt", "start": 0, @@ -2813,7 +2813,7 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "Name" }, - "commentStart": 1662, + "commentStart": 1664, "end": 0, "start": 0, "type": "CallExpression", @@ -2824,7 +2824,7 @@ description: Result of parsing makeup-mirror.kcl { "type": "LabeledArg", "label": { - "commentStart": 1730, + "commentStart": 1734, "end": 0, "name": "length", "start": 0, @@ -2832,10 +2832,10 @@ description: Result of parsing makeup-mirror.kcl }, "arg": { "abs_path": false, - "commentStart": 1739, + "commentStart": 1743, "end": 0, "name": { - "commentStart": 1739, + "commentStart": 1743, "end": 0, "name": "gestellD", "start": 0, @@ -2850,10 +2850,10 @@ description: Result of parsing makeup-mirror.kcl ], "callee": { "abs_path": false, - "commentStart": 1724, + "commentStart": 1728, "end": 0, "name": { - "commentStart": 1724, + "commentStart": 1728, "end": 0, "name": "xLine", "start": 0, @@ -2863,7 +2863,7 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "Name" }, - "commentStart": 1724, + "commentStart": 1728, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2873,14 +2873,14 @@ description: Result of parsing makeup-mirror.kcl { "arguments": [ { - "commentStart": 1762, + "commentStart": 1766, "end": 0, "properties": [ { - "commentStart": 1773, + "commentStart": 1777, "end": 0, "key": { - "commentStart": 1773, + "commentStart": 1777, "end": 0, "name": "interior", "start": 0, @@ -2889,14 +2889,14 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 1784, + "commentStart": 1788, "elements": [ { "abs_path": false, - "commentStart": 1785, + "commentStart": 1789, "end": 0, "name": { - "commentStart": 1785, + "commentStart": 1789, "end": 0, "name": "offsetX", "start": 0, @@ -2908,14 +2908,14 @@ description: Result of parsing makeup-mirror.kcl "type": "Name" }, { - "commentStart": 1794, + "commentStart": 1798, "end": 0, "left": { "abs_path": false, - "commentStart": 1794, + "commentStart": 1798, "end": 0, "name": { - "commentStart": 1794, + "commentStart": 1798, "end": 0, "name": "altitude", "start": 0, @@ -2929,10 +2929,10 @@ description: Result of parsing makeup-mirror.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 1803, + "commentStart": 1809, "end": 0, "name": { - "commentStart": 1803, + "commentStart": 1809, "end": 0, "name": "gestellR", "start": 0, @@ -2955,10 +2955,10 @@ description: Result of parsing makeup-mirror.kcl } }, { - "commentStart": 1823, + "commentStart": 1829, "end": 0, "key": { - "commentStart": 1823, + "commentStart": 1829, "end": 0, "name": "end", "start": 0, @@ -2967,17 +2967,17 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 1829, + "commentStart": 1835, "elements": [ { - "commentStart": 1830, + "commentStart": 1836, "end": 0, "left": { "abs_path": false, - "commentStart": 1830, + "commentStart": 1836, "end": 0, "name": { - "commentStart": 1830, + "commentStart": 1836, "end": 0, "name": "offsetX", "start": 0, @@ -2991,10 +2991,10 @@ description: Result of parsing makeup-mirror.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 1838, + "commentStart": 1846, "end": 0, "name": { - "commentStart": 1838, + "commentStart": 1846, "end": 0, "name": "gestellR", "start": 0, @@ -3011,10 +3011,10 @@ description: Result of parsing makeup-mirror.kcl }, { "abs_path": false, - "commentStart": 1848, + "commentStart": 1856, "end": 0, "name": { - "commentStart": 1848, + "commentStart": 1856, "end": 0, "name": "altitude", "start": 0, @@ -3038,7 +3038,7 @@ description: Result of parsing makeup-mirror.kcl "type": "ObjectExpression" }, { - "commentStart": 1868, + "commentStart": 1876, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3047,10 +3047,10 @@ description: Result of parsing makeup-mirror.kcl ], "callee": { "abs_path": false, - "commentStart": 1756, + "commentStart": 1760, "end": 0, "name": { - "commentStart": 1756, + "commentStart": 1760, "end": 0, "name": "arcTo", "start": 0, @@ -3060,7 +3060,7 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "Name" }, - "commentStart": 1756, + "commentStart": 1760, "end": 0, "start": 0, "type": "CallExpression", @@ -3071,7 +3071,7 @@ description: Result of parsing makeup-mirror.kcl { "type": "LabeledArg", "label": { - "commentStart": 1884, + "commentStart": 1892, "end": 0, "name": "length", "start": 0, @@ -3079,10 +3079,10 @@ description: Result of parsing makeup-mirror.kcl }, "arg": { "abs_path": false, - "commentStart": 1893, + "commentStart": 1901, "end": 0, "name": { - "commentStart": 1893, + "commentStart": 1901, "end": 0, "name": "gestellD", "start": 0, @@ -3097,10 +3097,10 @@ description: Result of parsing makeup-mirror.kcl ], "callee": { "abs_path": false, - "commentStart": 1878, + "commentStart": 1886, "end": 0, "name": { - "commentStart": 1878, + "commentStart": 1886, "end": 0, "name": "xLine", "start": 0, @@ -3110,7 +3110,7 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "Name" }, - "commentStart": 1878, + "commentStart": 1886, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -3120,14 +3120,14 @@ description: Result of parsing makeup-mirror.kcl { "arguments": [ { - "commentStart": 1916, + "commentStart": 1924, "end": 0, "properties": [ { - "commentStart": 1927, + "commentStart": 1935, "end": 0, "key": { - "commentStart": 1927, + "commentStart": 1935, "end": 0, "name": "interior", "start": 0, @@ -3136,14 +3136,14 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 1938, + "commentStart": 1946, "elements": [ { "abs_path": false, - "commentStart": 1939, + "commentStart": 1959, "end": 0, "name": { - "commentStart": 1939, + "commentStart": 1959, "end": 0, "name": "offsetX", "start": 0, @@ -3155,17 +3155,17 @@ description: Result of parsing makeup-mirror.kcl "type": "Name" }, { - "commentStart": 1948, + "commentStart": 1979, "end": 0, "left": { - "commentStart": 1948, + "commentStart": 1979, "end": 0, "left": { "abs_path": false, - "commentStart": 1948, + "commentStart": 1979, "end": 0, "name": { - "commentStart": 1948, + "commentStart": 1979, "end": 0, "name": "altitude", "start": 0, @@ -3179,10 +3179,10 @@ description: Result of parsing makeup-mirror.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 1957, + "commentStart": 1990, "end": 0, "name": { - "commentStart": 1957, + "commentStart": 1990, "end": 0, "name": "gestellR", "start": 0, @@ -3200,10 +3200,10 @@ description: Result of parsing makeup-mirror.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 1966, + "commentStart": 2001, "end": 0, "name": { - "commentStart": 1966, + "commentStart": 2001, "end": 0, "name": "gestellD", "start": 0, @@ -3226,10 +3226,10 @@ description: Result of parsing makeup-mirror.kcl } }, { - "commentStart": 1986, + "commentStart": 2031, "end": 0, "key": { - "commentStart": 1986, + "commentStart": 2031, "end": 0, "name": "end", "start": 0, @@ -3238,12 +3238,12 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 1992, + "commentStart": 2037, "elements": [ { "arguments": [ { - "commentStart": 2007, + "commentStart": 2052, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3252,10 +3252,10 @@ description: Result of parsing makeup-mirror.kcl ], "callee": { "abs_path": false, - "commentStart": 1993, + "commentStart": 2038, "end": 0, "name": { - "commentStart": 1993, + "commentStart": 2038, "end": 0, "name": "profileStartX", "start": 0, @@ -3265,7 +3265,7 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "Name" }, - "commentStart": 1993, + "commentStart": 2038, "end": 0, "start": 0, "type": "CallExpression", @@ -3274,7 +3274,7 @@ description: Result of parsing makeup-mirror.kcl { "arguments": [ { - "commentStart": 2025, + "commentStart": 2070, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3283,10 +3283,10 @@ description: Result of parsing makeup-mirror.kcl ], "callee": { "abs_path": false, - "commentStart": 2011, + "commentStart": 2056, "end": 0, "name": { - "commentStart": 2011, + "commentStart": 2056, "end": 0, "name": "profileStartY", "start": 0, @@ -3296,7 +3296,7 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "Name" }, - "commentStart": 2011, + "commentStart": 2056, "end": 0, "start": 0, "type": "CallExpression", @@ -3315,7 +3315,7 @@ description: Result of parsing makeup-mirror.kcl "type": "ObjectExpression" }, { - "commentStart": 2039, + "commentStart": 2084, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3324,10 +3324,10 @@ description: Result of parsing makeup-mirror.kcl ], "callee": { "abs_path": false, - "commentStart": 1910, + "commentStart": 1918, "end": 0, "name": { - "commentStart": 1910, + "commentStart": 1918, "end": 0, "name": "arcTo", "start": 0, @@ -3337,7 +3337,7 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "Name" }, - "commentStart": 1910, + "commentStart": 1918, "end": 0, "start": 0, "type": "CallExpression", @@ -3347,10 +3347,10 @@ description: Result of parsing makeup-mirror.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 2049, + "commentStart": 2094, "end": 0, "name": { - "commentStart": 2049, + "commentStart": 2094, "end": 0, "name": "close", "start": 0, @@ -3360,7 +3360,7 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "Name" }, - "commentStart": 2049, + "commentStart": 2094, "end": 0, "start": 0, "type": "CallExpression", @@ -3371,7 +3371,7 @@ description: Result of parsing makeup-mirror.kcl { "type": "LabeledArg", "label": { - "commentStart": 2072, + "commentStart": 2117, "end": 0, "name": "length", "start": 0, @@ -3379,10 +3379,10 @@ description: Result of parsing makeup-mirror.kcl }, "arg": { "abs_path": false, - "commentStart": 2081, + "commentStart": 2126, "end": 0, "name": { - "commentStart": 2081, + "commentStart": 2126, "end": 0, "name": "tiefe", "start": 0, @@ -3397,10 +3397,10 @@ description: Result of parsing makeup-mirror.kcl ], "callee": { "abs_path": false, - "commentStart": 2064, + "commentStart": 2109, "end": 0, "name": { - "commentStart": 2064, + "commentStart": 2109, "end": 0, "name": "extrude", "start": 0, @@ -3410,7 +3410,7 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "Name" }, - "commentStart": 2064, + "commentStart": 2109, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -3418,7 +3418,7 @@ description: Result of parsing makeup-mirror.kcl "unlabeled": null } ], - "commentStart": 1662, + "commentStart": 1664, "end": 0, "start": 0, "type": "PipeExpression", @@ -3436,10 +3436,10 @@ description: Result of parsing makeup-mirror.kcl { "argument": { "abs_path": false, - "commentStart": 2097, + "commentStart": 2142, "end": 0, "name": { - "commentStart": 2097, + "commentStart": 2142, "end": 0, "name": "armBody", "start": 0, @@ -3450,7 +3450,7 @@ description: Result of parsing makeup-mirror.kcl "type": "Name", "type": "Name" }, - "commentStart": 2090, + "commentStart": 2135, "end": 0, "start": 0, "type": "ReturnStatement", @@ -3463,7 +3463,7 @@ description: Result of parsing makeup-mirror.kcl "nonCodeNodes": { "1": [ { - "commentStart": 1647, + "commentStart": 1649, "end": 0, "start": 0, "type": "NonCodeNode", @@ -3580,12 +3580,12 @@ description: Result of parsing makeup-mirror.kcl "type": "VariableDeclaration" }, { - "commentStart": 2106, + "commentStart": 2151, "declaration": { - "commentStart": 2108, + "commentStart": 2153, "end": 0, "id": { - "commentStart": 2108, + "commentStart": 2153, "end": 0, "name": "mirror", "start": 0, @@ -3595,10 +3595,10 @@ description: Result of parsing makeup-mirror.kcl "arguments": [ { "abs_path": false, - "commentStart": 2126, + "commentStart": 2171, "end": 0, "name": { - "commentStart": 2126, + "commentStart": 2171, "end": 0, "name": "XZ", "start": 0, @@ -3611,10 +3611,10 @@ description: Result of parsing makeup-mirror.kcl }, { "abs_path": false, - "commentStart": 2130, + "commentStart": 2175, "end": 0, "name": { - "commentStart": 2130, + "commentStart": 2175, "end": 0, "name": "armLength", "start": 0, @@ -3627,10 +3627,10 @@ description: Result of parsing makeup-mirror.kcl }, { "abs_path": false, - "commentStart": 2141, + "commentStart": 2186, "end": 0, "name": { - "commentStart": 2141, + "commentStart": 2186, "end": 0, "name": "armLength", "start": 0, @@ -3642,26 +3642,26 @@ description: Result of parsing makeup-mirror.kcl "type": "Name" }, { - "commentStart": 2152, + "commentStart": 2197, "end": 0, "left": { - "commentStart": 2152, + "commentStart": 2197, "end": 0, "left": { - "commentStart": 2152, + "commentStart": 2197, "end": 0, "left": { - "commentStart": 2152, + "commentStart": 2197, "end": 0, "left": { - "commentStart": 2152, + "commentStart": 2197, "end": 0, "left": { "abs_path": false, - "commentStart": 2152, + "commentStart": 2197, "end": 0, "name": { - "commentStart": 2152, + "commentStart": 2197, "end": 0, "name": "hingeHeight", "start": 0, @@ -3674,7 +3674,7 @@ description: Result of parsing makeup-mirror.kcl }, "operator": "*", "right": { - "commentStart": 2166, + "commentStart": 2211, "end": 0, "raw": "4", "start": 0, @@ -3691,14 +3691,14 @@ description: Result of parsing makeup-mirror.kcl }, "operator": "+", "right": { - "commentStart": 2170, + "commentStart": 2215, "end": 0, "left": { "abs_path": false, - "commentStart": 2170, + "commentStart": 2215, "end": 0, "name": { - "commentStart": 2170, + "commentStart": 2215, "end": 0, "name": "hingeGap", "start": 0, @@ -3711,7 +3711,7 @@ description: Result of parsing makeup-mirror.kcl }, "operator": "*", "right": { - "commentStart": 2181, + "commentStart": 2226, "end": 0, "raw": "3", "start": 0, @@ -3733,10 +3733,10 @@ description: Result of parsing makeup-mirror.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 2185, + "commentStart": 2230, "end": 0, "name": { - "commentStart": 2185, + "commentStart": 2230, "end": 0, "name": "mirrorRadius", "start": 0, @@ -3754,10 +3754,10 @@ description: Result of parsing makeup-mirror.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 2198, + "commentStart": 2245, "end": 0, "name": { - "commentStart": 2198, + "commentStart": 2245, "end": 0, "name": "archToMirrorGap", "start": 0, @@ -3775,10 +3775,10 @@ description: Result of parsing makeup-mirror.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 2214, + "commentStart": 2263, "end": 0, "name": { - "commentStart": 2214, + "commentStart": 2263, "end": 0, "name": "archThickness", "start": 0, @@ -3795,10 +3795,10 @@ description: Result of parsing makeup-mirror.kcl }, { "abs_path": false, - "commentStart": 2229, + "commentStart": 2278, "end": 0, "name": { - "commentStart": 2229, + "commentStart": 2278, "end": 0, "name": "mirrorRadius", "start": 0, @@ -3811,10 +3811,10 @@ description: Result of parsing makeup-mirror.kcl }, { "abs_path": false, - "commentStart": 2243, + "commentStart": 2292, "end": 0, "name": { - "commentStart": 2243, + "commentStart": 2292, "end": 0, "name": "mirrorThickness", "start": 0, @@ -3827,10 +3827,10 @@ description: Result of parsing makeup-mirror.kcl }, { "abs_path": false, - "commentStart": 2260, + "commentStart": 2309, "end": 0, "name": { - "commentStart": 2260, + "commentStart": 2309, "end": 0, "name": "archRadius", "start": 0, @@ -3843,10 +3843,10 @@ description: Result of parsing makeup-mirror.kcl }, { "abs_path": false, - "commentStart": 2272, + "commentStart": 2321, "end": 0, "name": { - "commentStart": 2272, + "commentStart": 2321, "end": 0, "name": "archThickness", "start": 0, @@ -3860,10 +3860,10 @@ description: Result of parsing makeup-mirror.kcl ], "callee": { "abs_path": false, - "commentStart": 2117, + "commentStart": 2162, "end": 0, "name": { - "commentStart": 2117, + "commentStart": 2162, "end": 0, "name": "mirrorFn", "start": 0, @@ -3873,7 +3873,7 @@ description: Result of parsing makeup-mirror.kcl "start": 0, "type": "Name" }, - "commentStart": 2117, + "commentStart": 2162, "end": 0, "start": 0, "type": "CallExpression", @@ -3992,7 +3992,7 @@ description: Result of parsing makeup-mirror.kcl ], "21": [ { - "commentStart": 2106, + "commentStart": 2151, "end": 0, "start": 0, "type": "NonCodeNode", diff --git a/rust/kcl-lib/tests/kcl_samples/makeup-mirror/ops.snap b/rust/kcl-lib/tests/kcl_samples/makeup-mirror/ops.snap index b9491ee07..142513c1d 100644 --- a/rust/kcl-lib/tests/kcl_samples/makeup-mirror/ops.snap +++ b/rust/kcl-lib/tests/kcl_samples/makeup-mirror/ops.snap @@ -1280,7 +1280,7 @@ description: Operations executed makeup-mirror.kcl "name": "mirrorFn", "functionSourceRange": [ 1389, - 2106, + 2151, 0 ], "unlabeledArg": null, diff --git a/rust/kcl-lib/tests/kcl_samples/mounting-plate/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/mounting-plate/artifact_commands.snap index b034772b3..327e110dc 100644 --- a/rust/kcl-lib/tests/kcl_samples/mounting-plate/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/mounting-plate/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands mounting-plate.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/multi-axis-robot/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/multi-axis-robot/artifact_commands.snap index 5770ab7b0..8ad94c113 100644 --- a/rust/kcl-lib/tests/kcl_samples/multi-axis-robot/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/multi-axis-robot/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands multi-axis-robot.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/multi-axis-robot/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/kcl_samples/multi-axis-robot/artifact_graph_flowchart.snap.md index b86bb5258..ee2173e4c 100644 --- a/rust/kcl-lib/tests/kcl_samples/multi-axis-robot/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/kcl_samples/multi-axis-robot/artifact_graph_flowchart.snap.md @@ -1,162 +1,162 @@ ```mermaid flowchart LR subgraph path2 [Path] - 2["Path
[224, 279, 4]"] - 3["Segment
[285, 347, 4]"] - 4["Segment
[353, 468, 4]"] - 5["Segment
[474, 594, 4]"] - 6["Segment
[600, 685, 4]"] - 7["Segment
[691, 698, 4]"] + 2["Path
[224, 279, 5]"] + 3["Segment
[285, 347, 5]"] + 4["Segment
[353, 468, 5]"] + 5["Segment
[474, 594, 5]"] + 6["Segment
[600, 685, 5]"] + 7["Segment
[691, 698, 5]"] 8[Solid2d] end subgraph path28 [Path] - 28["Path
[1134, 1191, 4]"] - 29["Segment
[1134, 1191, 4]"] + 28["Path
[1134, 1191, 5]"] + 29["Segment
[1134, 1191, 5]"] 30[Solid2d] end subgraph path36 [Path] - 36["Path
[1389, 1426, 4]"] - 37["Segment
[1389, 1426, 4]"] + 36["Path
[1389, 1426, 5]"] + 37["Segment
[1389, 1426, 5]"] 38[Solid2d] end subgraph path44 [Path] - 44["Path
[1558, 1698, 4]"] - 45["Segment
[1558, 1698, 4]"] + 44["Path
[1558, 1698, 5]"] + 45["Segment
[1558, 1698, 5]"] 46[Solid2d] end subgraph path54 [Path] - 54["Path
[1944, 2084, 4]"] - 55["Segment
[1944, 2084, 4]"] + 54["Path
[1944, 2084, 5]"] + 55["Segment
[1944, 2084, 5]"] 56[Solid2d] end subgraph path65 [Path] - 65["Path
[203, 263, 5]"] - 66["Segment
[203, 263, 5]"] + 65["Path
[203, 263, 6]"] + 66["Segment
[203, 263, 6]"] 67[Solid2d] end subgraph path75 [Path] - 75["Path
[493, 529, 5]"] - 76["Segment
[535, 579, 5]"] - 77["Segment
[585, 673, 5]"] - 78["Segment
[679, 728, 5]"] - 79["Segment
[734, 790, 5]"] - 80["Segment
[796, 803, 5]"] + 75["Path
[493, 529, 6]"] + 76["Segment
[535, 579, 6]"] + 77["Segment
[585, 673, 6]"] + 78["Segment
[679, 728, 6]"] + 79["Segment
[734, 790, 6]"] + 80["Segment
[796, 803, 6]"] 81[Solid2d] end subgraph path97 [Path] - 97["Path
[900, 1075, 5]"] - 98["Segment
[900, 1075, 5]"] + 97["Path
[900, 1075, 6]"] + 98["Segment
[900, 1075, 6]"] 99[Solid2d] end subgraph path105 [Path] - 105["Path
[1279, 1426, 5]"] - 106["Segment
[1279, 1426, 5]"] + 105["Path
[1279, 1426, 6]"] + 106["Segment
[1279, 1426, 6]"] 107[Solid2d] end subgraph path116 [Path] - 116["Path
[1743, 1917, 5]"] - 117["Segment
[1743, 1917, 5]"] + 116["Path
[1743, 1917, 6]"] + 117["Segment
[1743, 1917, 6]"] 118[Solid2d] end subgraph path125 [Path] - 125["Path
[2142, 2182, 5]"] - 126["Segment
[2142, 2182, 5]"] + 125["Path
[2142, 2182, 6]"] + 126["Segment
[2142, 2182, 6]"] 127[Solid2d] end subgraph path137 [Path] - 137["Path
[251, 394, 6]"] - 138["Segment
[400, 516, 6]"] - 139["Segment
[522, 600, 6]"] - 140["Segment
[606, 722, 6]"] - 141["Segment
[728, 784, 6]"] - 142["Segment
[790, 797, 6]"] + 137["Path
[251, 394, 7]"] + 138["Segment
[400, 516, 7]"] + 139["Segment
[522, 600, 7]"] + 140["Segment
[606, 722, 7]"] + 141["Segment
[728, 784, 7]"] + 142["Segment
[790, 797, 7]"] 143[Solid2d] end subgraph path159 [Path] - 159["Path
[913, 977, 6]"] - 160["Segment
[913, 977, 6]"] + 159["Path
[913, 977, 7]"] + 160["Segment
[913, 977, 7]"] 161[Solid2d] end subgraph path167 [Path] - 167["Path
[1146, 1354, 6]"] - 168["Segment
[1146, 1354, 6]"] + 167["Path
[1146, 1354, 7]"] + 168["Segment
[1146, 1354, 7]"] 169[Solid2d] end subgraph path175 [Path] - 175["Path
[1557, 1601, 6]"] - 176["Segment
[1557, 1601, 6]"] + 175["Path
[1557, 1601, 7]"] + 176["Segment
[1557, 1601, 7]"] 177[Solid2d] end subgraph path190 [Path] - 190["Path
[1839, 2031, 6]"] - 191["Segment
[1839, 2031, 6]"] + 190["Path
[1839, 2031, 7]"] + 191["Segment
[1839, 2031, 7]"] 192[Solid2d] end subgraph path201 [Path] - 201["Path
[2384, 2559, 6]"] - 202["Segment
[2384, 2559, 6]"] + 201["Path
[2384, 2559, 7]"] + 202["Segment
[2384, 2559, 7]"] 203[Solid2d] end subgraph path210 [Path] - 210["Path
[271, 504, 7]"] - 211["Segment
[510, 629, 7]"] - 212["Segment
[635, 715, 7]"] - 213["Segment
[721, 840, 7]"] - 214["Segment
[846, 916, 7]"] - 215["Segment
[922, 929, 7]"] + 210["Path
[271, 504, 8]"] + 211["Segment
[510, 629, 8]"] + 212["Segment
[635, 715, 8]"] + 213["Segment
[721, 840, 8]"] + 214["Segment
[846, 916, 8]"] + 215["Segment
[922, 929, 8]"] 216[Solid2d] end subgraph path232 [Path] - 232["Path
[1043, 1252, 7]"] - 233["Segment
[1043, 1252, 7]"] + 232["Path
[1043, 1252, 8]"] + 233["Segment
[1043, 1252, 8]"] 234[Solid2d] end subgraph path240 [Path] - 240["Path
[1457, 1646, 7]"] - 241["Segment
[1457, 1646, 7]"] + 240["Path
[1457, 1646, 8]"] + 241["Segment
[1457, 1646, 8]"] 242[Solid2d] end subgraph path255 [Path] - 255["Path
[2067, 2353, 7]"] - 256["Segment
[2067, 2353, 7]"] + 255["Path
[2067, 2353, 8]"] + 256["Segment
[2067, 2353, 8]"] 257[Solid2d] end subgraph path264 [Path] - 264["Path
[2452, 2736, 7]"] - 265["Segment
[2452, 2736, 7]"] + 264["Path
[2452, 2736, 8]"] + 265["Segment
[2452, 2736, 8]"] 266[Solid2d] end subgraph path273 [Path] - 273["Path
[2890, 2928, 7]"] - 274["Segment
[2890, 2928, 7]"] + 273["Path
[2890, 2928, 8]"] + 274["Segment
[2890, 2928, 8]"] 275[Solid2d] end subgraph path282 [Path] - 282["Path
[3058, 3283, 7]"] - 283["Segment
[3289, 3383, 7]"] - 284["Segment
[3389, 3532, 7]"] - 285["Segment
[3538, 3632, 7]"] - 286["Segment
[3638, 3740, 7]"] - 287["Segment
[3746, 3848, 7]"] - 288["Segment
[3854, 3954, 7]"] - 289["Segment
[3960, 4016, 7]"] - 290["Segment
[4022, 4029, 7]"] + 282["Path
[3058, 3283, 8]"] + 283["Segment
[3289, 3383, 8]"] + 284["Segment
[3389, 3532, 8]"] + 285["Segment
[3538, 3632, 8]"] + 286["Segment
[3638, 3740, 8]"] + 287["Segment
[3746, 3848, 8]"] + 288["Segment
[3854, 3954, 8]"] + 289["Segment
[3960, 4016, 8]"] + 290["Segment
[4022, 4029, 8]"] 291[Solid2d] end subgraph path316 [Path] - 316["Path
[4158, 4383, 7]"] - 317["Segment
[4389, 4485, 7]"] - 318["Segment
[4491, 4639, 7]"] - 319["Segment
[4645, 4741, 7]"] - 320["Segment
[4747, 4851, 7]"] - 321["Segment
[4857, 4961, 7]"] - 322["Segment
[4967, 5069, 7]"] - 323["Segment
[5075, 5131, 7]"] - 324["Segment
[5137, 5144, 7]"] + 316["Path
[4158, 4383, 8]"] + 317["Segment
[4389, 4485, 8]"] + 318["Segment
[4491, 4639, 8]"] + 319["Segment
[4645, 4741, 8]"] + 320["Segment
[4747, 4851, 8]"] + 321["Segment
[4857, 4961, 8]"] + 322["Segment
[4967, 5069, 8]"] + 323["Segment
[5075, 5131, 8]"] + 324["Segment
[5137, 5144, 8]"] 325[Solid2d] end - 1["Plane
[201, 218, 4]"] - 9["Sweep Extrusion
[712, 759, 4]"] + 1["Plane
[201, 218, 5]"] + 9["Sweep Extrusion
[712, 759, 5]"] 10[Wall] 11[Wall] 12[Wall] @@ -171,43 +171,43 @@ flowchart LR 21["SweepEdge Adjacent"] 22["SweepEdge Opposite"] 23["SweepEdge Adjacent"] - 24["EdgeCut Chamfer
[765, 1042, 4]"] - 25["EdgeCut Chamfer
[765, 1042, 4]"] - 26["EdgeCut Chamfer
[765, 1042, 4]"] - 27["EdgeCut Chamfer
[765, 1042, 4]"] - 31["Sweep Extrusion
[1205, 1271, 4]"] + 24["EdgeCut Chamfer
[765, 1042, 5]"] + 25["EdgeCut Chamfer
[765, 1042, 5]"] + 26["EdgeCut Chamfer
[765, 1042, 5]"] + 27["EdgeCut Chamfer
[765, 1042, 5]"] + 31["Sweep Extrusion
[1205, 1271, 5]"] 32[Wall] 33["Cap End"] 34["SweepEdge Opposite"] 35["SweepEdge Adjacent"] - 39["Sweep Extrusion
[1440, 1470, 4]"] + 39["Sweep Extrusion
[1440, 1470, 5]"] 40[Wall] 41["Cap End"] 42["SweepEdge Opposite"] 43["SweepEdge Adjacent"] - 47["Sweep Extrusion
[1846, 1893, 4]"] + 47["Sweep Extrusion
[1846, 1893, 5]"] 48[Wall] 49["SweepEdge Opposite"] 50["SweepEdge Adjacent"] - 51["Sweep Extrusion
[1846, 1893, 4]"] - 52["Sweep Extrusion
[1846, 1893, 4]"] - 53["Sweep Extrusion
[1846, 1893, 4]"] - 57["Sweep Extrusion
[2220, 2267, 4]"] + 51["Sweep Extrusion
[1846, 1893, 5]"] + 52["Sweep Extrusion
[1846, 1893, 5]"] + 53["Sweep Extrusion
[1846, 1893, 5]"] + 57["Sweep Extrusion
[2220, 2267, 5]"] 58[Wall] 59["SweepEdge Opposite"] 60["SweepEdge Adjacent"] - 61["Sweep Extrusion
[2220, 2267, 4]"] - 62["Sweep Extrusion
[2220, 2267, 4]"] - 63["Sweep Extrusion
[2220, 2267, 4]"] - 64["Plane
[174, 197, 5]"] - 68["Sweep Extrusion
[277, 315, 5]"] + 61["Sweep Extrusion
[2220, 2267, 5]"] + 62["Sweep Extrusion
[2220, 2267, 5]"] + 63["Sweep Extrusion
[2220, 2267, 5]"] + 64["Plane
[174, 197, 6]"] + 68["Sweep Extrusion
[277, 315, 6]"] 69[Wall] 70["Cap Start"] 71["Cap End"] 72["SweepEdge Opposite"] 73["SweepEdge Adjacent"] - 74["Plane
[464, 487, 5]"] - 82["Sweep Extrusion
[818, 848, 5]"] + 74["Plane
[464, 487, 6]"] + 82["Sweep Extrusion
[818, 848, 6]"] 83[Wall] 84[Wall] 85[Wall] @@ -222,35 +222,35 @@ flowchart LR 94["SweepEdge Adjacent"] 95["SweepEdge Opposite"] 96["SweepEdge Adjacent"] - 100["Sweep Extrusion
[1089, 1121, 5]"] + 100["Sweep Extrusion
[1089, 1121, 6]"] 101[Wall] 102["Cap End"] 103["SweepEdge Opposite"] 104["SweepEdge Adjacent"] - 108["Sweep Extrusion
[1659, 1691, 5]"] + 108["Sweep Extrusion
[1659, 1691, 6]"] 109[Wall] 110["Cap End"] 111["SweepEdge Opposite"] 112["SweepEdge Adjacent"] - 113["Sweep Extrusion
[1659, 1691, 5]"] - 114["Sweep Extrusion
[1659, 1691, 5]"] - 115["Sweep Extrusion
[1659, 1691, 5]"] - 119["Sweep Extrusion
[1931, 1964, 5]"] + 113["Sweep Extrusion
[1659, 1691, 6]"] + 114["Sweep Extrusion
[1659, 1691, 6]"] + 115["Sweep Extrusion
[1659, 1691, 6]"] + 119["Sweep Extrusion
[1931, 1964, 6]"] 120[Wall] 121["Cap End"] 122["SweepEdge Opposite"] 123["SweepEdge Adjacent"] - 124["Plane
[2113, 2136, 5]"] - 128["Sweep Extrusion
[2184, 2215, 5]"] + 124["Plane
[2113, 2136, 6]"] + 128["Sweep Extrusion
[2184, 2215, 6]"] 129[Wall] 130["Cap Start"] 131["Cap End"] 132["SweepEdge Opposite"] 133["SweepEdge Adjacent"] - 134["EdgeCut Fillet
[321, 383, 5]"] - 135["EdgeCut Fillet
[1970, 2032, 5]"] - 136["Plane
[222, 245, 6]"] - 144["Sweep Extrusion
[811, 859, 6]"] + 134["EdgeCut Fillet
[321, 383, 6]"] + 135["EdgeCut Fillet
[1970, 2032, 6]"] + 136["Plane
[222, 245, 7]"] + 144["Sweep Extrusion
[811, 859, 7]"] 145[Wall] 146[Wall] 147[Wall] @@ -265,43 +265,43 @@ flowchart LR 156["SweepEdge Adjacent"] 157["SweepEdge Opposite"] 158["SweepEdge Adjacent"] - 162["Sweep Extrusion
[992, 1025, 6]"] + 162["Sweep Extrusion
[992, 1025, 7]"] 163[Wall] 164["Cap End"] 165["SweepEdge Opposite"] 166["SweepEdge Adjacent"] - 170["Sweep Extrusion
[1369, 1399, 6]"] + 170["Sweep Extrusion
[1369, 1399, 7]"] 171[Wall] 172["Cap End"] 173["SweepEdge Opposite"] 174["SweepEdge Adjacent"] - 178["Sweep Extrusion
[1754, 1787, 6]"] + 178["Sweep Extrusion
[1754, 1787, 7]"] 179[Wall] 180["Cap End"] 181["SweepEdge Opposite"] 182["SweepEdge Adjacent"] - 183["Sweep Extrusion
[1754, 1787, 6]"] - 184["Sweep Extrusion
[1754, 1787, 6]"] - 185["Sweep Extrusion
[1754, 1787, 6]"] - 186["Sweep Extrusion
[1754, 1787, 6]"] - 187["Sweep Extrusion
[1754, 1787, 6]"] - 188["Sweep Extrusion
[1754, 1787, 6]"] - 189["Sweep Extrusion
[1754, 1787, 6]"] - 193["Sweep Extrusion
[2299, 2332, 6]"] + 183["Sweep Extrusion
[1754, 1787, 7]"] + 184["Sweep Extrusion
[1754, 1787, 7]"] + 185["Sweep Extrusion
[1754, 1787, 7]"] + 186["Sweep Extrusion
[1754, 1787, 7]"] + 187["Sweep Extrusion
[1754, 1787, 7]"] + 188["Sweep Extrusion
[1754, 1787, 7]"] + 189["Sweep Extrusion
[1754, 1787, 7]"] + 193["Sweep Extrusion
[2299, 2332, 7]"] 194[Wall] 195["Cap End"] 196["SweepEdge Opposite"] 197["SweepEdge Adjacent"] - 198["Sweep Extrusion
[2299, 2332, 6]"] - 199["Sweep Extrusion
[2299, 2332, 6]"] - 200["Sweep Extrusion
[2299, 2332, 6]"] - 204["Sweep Extrusion
[2561, 2591, 6]"] + 198["Sweep Extrusion
[2299, 2332, 7]"] + 199["Sweep Extrusion
[2299, 2332, 7]"] + 200["Sweep Extrusion
[2299, 2332, 7]"] + 204["Sweep Extrusion
[2561, 2591, 7]"] 205[Wall] 206["Cap End"] 207["SweepEdge Opposite"] 208["SweepEdge Adjacent"] - 209["Plane
[242, 265, 7]"] - 217["Sweep Extrusion
[943, 991, 7]"] + 209["Plane
[242, 265, 8]"] + 217["Sweep Extrusion
[943, 991, 8]"] 218[Wall] 219[Wall] 220[Wall] @@ -316,42 +316,42 @@ flowchart LR 229["SweepEdge Adjacent"] 230["SweepEdge Opposite"] 231["SweepEdge Adjacent"] - 235["Sweep Extrusion
[1267, 1300, 7]"] + 235["Sweep Extrusion
[1267, 1300, 8]"] 236[Wall] 237["Cap End"] 238["SweepEdge Opposite"] 239["SweepEdge Adjacent"] - 243["Sweep Extrusion
[1911, 1944, 7]"] + 243["Sweep Extrusion
[1911, 1944, 8]"] 244[Wall] 245["Cap End"] 246["SweepEdge Opposite"] 247["SweepEdge Adjacent"] - 248["Sweep Extrusion
[1911, 1944, 7]"] - 249["Sweep Extrusion
[1911, 1944, 7]"] - 250["Sweep Extrusion
[1911, 1944, 7]"] - 251["Sweep Extrusion
[1911, 1944, 7]"] - 252["Sweep Extrusion
[1911, 1944, 7]"] - 253["Sweep Extrusion
[1911, 1944, 7]"] - 254["Sweep Extrusion
[1911, 1944, 7]"] - 258["Sweep Extrusion
[2367, 2400, 7]"] + 248["Sweep Extrusion
[1911, 1944, 8]"] + 249["Sweep Extrusion
[1911, 1944, 8]"] + 250["Sweep Extrusion
[1911, 1944, 8]"] + 251["Sweep Extrusion
[1911, 1944, 8]"] + 252["Sweep Extrusion
[1911, 1944, 8]"] + 253["Sweep Extrusion
[1911, 1944, 8]"] + 254["Sweep Extrusion
[1911, 1944, 8]"] + 258["Sweep Extrusion
[2367, 2400, 8]"] 259[Wall] 260["Cap Start"] 261["Cap End"] 262["SweepEdge Opposite"] 263["SweepEdge Adjacent"] - 267["Sweep Extrusion
[2751, 2784, 7]"] + 267["Sweep Extrusion
[2751, 2784, 8]"] 268[Wall] 269["Cap Start"] 270["Cap End"] 271["SweepEdge Opposite"] 272["SweepEdge Adjacent"] - 276["Sweep Extrusion
[2943, 2977, 7]"] + 276["Sweep Extrusion
[2943, 2977, 8]"] 277[Wall] 278["Cap Start"] 279["Cap End"] 280["SweepEdge Opposite"] 281["SweepEdge Adjacent"] - 292["Sweep Extrusion
[4044, 4077, 7]"] + 292["Sweep Extrusion
[4044, 4077, 8]"] 293[Wall] 294[Wall] 295[Wall] @@ -375,7 +375,7 @@ flowchart LR 313["SweepEdge Adjacent"] 314["SweepEdge Opposite"] 315["SweepEdge Adjacent"] - 326["Sweep Extrusion
[5146, 5179, 7]"] + 326["Sweep Extrusion
[5146, 5179, 8]"] 327[Wall] 328[Wall] 329[Wall] @@ -399,25 +399,25 @@ flowchart LR 347["SweepEdge Adjacent"] 348["SweepEdge Opposite"] 349["SweepEdge Adjacent"] - 350["StartSketchOnFace
[1096, 1128, 4]"] - 351["StartSketchOnFace
[1351, 1383, 4]"] - 352["StartSketchOnFace
[1520, 1552, 4]"] - 353["StartSketchOnFace
[1906, 1938, 4]"] - 354["StartSketchOnFace
[862, 894, 5]"] - 355["StartSketchOnFace
[1241, 1273, 5]"] - 356["StartSketchOnFace
[1705, 1737, 5]"] - 357["StartSketchOnFace
[873, 907, 6]"] - 358["StartSketchOnFace
[1106, 1140, 6]"] - 359["StartSketchOnFace
[1519, 1551, 6]"] - 360["StartSketchOnFace
[1801, 1833, 6]"] - 361["StartSketchOnFace
[2346, 2378, 6]"] - 362["StartSketchOnFace
[1005, 1037, 7]"] - 363["StartSketchOnFace
[1419, 1451, 7]"] - 364["StartSketchOnFace
[2027, 2061, 7]"] - 365["StartSketchOnFace
[2414, 2446, 7]"] - 366["StartSketchOnFace
[2850, 2884, 7]"] - 367["StartSketchOnFace
[3018, 3052, 7]"] - 368["StartSketchOnFace
[4118, 4152, 7]"] + 350["StartSketchOnFace
[1096, 1128, 5]"] + 351["StartSketchOnFace
[1351, 1383, 5]"] + 352["StartSketchOnFace
[1520, 1552, 5]"] + 353["StartSketchOnFace
[1906, 1938, 5]"] + 354["StartSketchOnFace
[862, 894, 6]"] + 355["StartSketchOnFace
[1241, 1273, 6]"] + 356["StartSketchOnFace
[1705, 1737, 6]"] + 357["StartSketchOnFace
[873, 907, 7]"] + 358["StartSketchOnFace
[1106, 1140, 7]"] + 359["StartSketchOnFace
[1519, 1551, 7]"] + 360["StartSketchOnFace
[1801, 1833, 7]"] + 361["StartSketchOnFace
[2346, 2378, 7]"] + 362["StartSketchOnFace
[1005, 1037, 8]"] + 363["StartSketchOnFace
[1419, 1451, 8]"] + 364["StartSketchOnFace
[2027, 2061, 8]"] + 365["StartSketchOnFace
[2414, 2446, 8]"] + 366["StartSketchOnFace
[2850, 2884, 8]"] + 367["StartSketchOnFace
[3018, 3052, 8]"] + 368["StartSketchOnFace
[4118, 4152, 8]"] 1 --- 2 2 --- 3 2 --- 4 diff --git a/rust/kcl-lib/tests/kcl_samples/multi-axis-robot/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/multi-axis-robot/program_memory.snap index 541e65408..ebc803a54 100644 --- a/rust/kcl-lib/tests/kcl_samples/multi-axis-robot/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/multi-axis-robot/program_memory.snap @@ -5,18 +5,18 @@ description: Variables in memory after executing multi-axis-robot.kcl { "j2RobotArm": { "type": "Module", - "value": 6 + "value": 7 }, "j3RobotArm": { "type": "Module", - "value": 7 + "value": 8 }, "robotArmBase": { "type": "Module", - "value": 4 + "value": 5 }, "rotatingBase": { "type": "Module", - "value": 5 + "value": 6 } } diff --git a/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/artifact_commands.snap index c344e925e..da1cccefb 100644 --- a/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands pipe-flange-assembly.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/artifact_graph_flowchart.snap.md index eafe2cb92..1d683218f 100644 --- a/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/artifact_graph_flowchart.snap.md @@ -1,206 +1,206 @@ ```mermaid flowchart LR subgraph path2 [Path] - 2["Path
[537, 630, 5]"] - 3["Segment
[537, 630, 5]"] + 2["Path
[537, 630, 6]"] + 3["Segment
[537, 630, 6]"] 4[Solid2d] end subgraph path6 [Path] - 6["Path
[859, 914, 5]"] - 7["Segment
[859, 914, 5]"] + 6["Path
[859, 914, 6]"] + 7["Segment
[859, 914, 6]"] 8[Solid2d] end subgraph path15 [Path] - 15["Path
[1129, 1188, 5]"] - 16["Segment
[1129, 1188, 5]"] + 15["Path
[1129, 1188, 6]"] + 16["Segment
[1129, 1188, 6]"] 17[Solid2d] end subgraph path23 [Path] - 23["Path
[1290, 1350, 5]"] - 24["Segment
[1290, 1350, 5]"] + 23["Path
[1290, 1350, 6]"] + 24["Segment
[1290, 1350, 6]"] 25[Solid2d] end subgraph path31 [Path] - 31["Path
[1507, 1560, 5]"] - 32["Segment
[1507, 1560, 5]"] + 31["Path
[1507, 1560, 6]"] + 32["Segment
[1507, 1560, 6]"] 33[Solid2d] end subgraph path39 [Path] - 39["Path
[537, 630, 5]"] - 40["Segment
[537, 630, 5]"] + 39["Path
[537, 630, 6]"] + 40["Segment
[537, 630, 6]"] 41[Solid2d] end subgraph path43 [Path] - 43["Path
[859, 914, 5]"] - 44["Segment
[859, 914, 5]"] + 43["Path
[859, 914, 6]"] + 44["Segment
[859, 914, 6]"] 45[Solid2d] end subgraph path52 [Path] - 52["Path
[1129, 1188, 5]"] - 53["Segment
[1129, 1188, 5]"] + 52["Path
[1129, 1188, 6]"] + 53["Segment
[1129, 1188, 6]"] 54[Solid2d] end subgraph path60 [Path] - 60["Path
[1290, 1350, 5]"] - 61["Segment
[1290, 1350, 5]"] + 60["Path
[1290, 1350, 6]"] + 61["Segment
[1290, 1350, 6]"] 62[Solid2d] end subgraph path68 [Path] - 68["Path
[1507, 1560, 5]"] - 69["Segment
[1507, 1560, 5]"] + 68["Path
[1507, 1560, 6]"] + 69["Segment
[1507, 1560, 6]"] 70[Solid2d] end subgraph path76 [Path] - 76["Path
[494, 556, 6]"] - 77["Segment
[494, 556, 6]"] + 76["Path
[494, 556, 7]"] + 77["Segment
[494, 556, 7]"] 78[Solid2d] end subgraph path85 [Path] - 85["Path
[706, 766, 6]"] - 86["Segment
[706, 766, 6]"] + 85["Path
[706, 766, 7]"] + 86["Segment
[706, 766, 7]"] 87[Solid2d] end subgraph path93 [Path] - 93["Path
[355, 407, 7]"] - 94["Segment
[355, 407, 7]"] + 93["Path
[354, 406, 8]"] + 94["Segment
[354, 406, 8]"] 95[Solid2d] end subgraph path102 [Path] - 102["Path
[540, 592, 7]"] - 103["Segment
[540, 592, 7]"] + 102["Path
[539, 591, 8]"] + 103["Segment
[539, 591, 8]"] 104[Solid2d] end subgraph path110 [Path] - 110["Path
[446, 516, 8]"] - 111["Segment
[446, 516, 8]"] + 110["Path
[445, 515, 9]"] + 111["Segment
[445, 515, 9]"] 112[Solid2d] end subgraph path121 [Path] - 121["Path
[780, 867, 8]"] - 122["Segment
[875, 958, 8]"] - 123["Segment
[966, 1049, 8]"] - 124["Segment
[1057, 1140, 8]"] - 125["Segment
[1148, 1230, 8]"] - 126["Segment
[1238, 1320, 8]"] - 127["Segment
[1328, 1335, 8]"] + 121["Path
[779, 866, 9]"] + 122["Segment
[874, 957, 9]"] + 123["Segment
[965, 1048, 9]"] + 124["Segment
[1056, 1139, 9]"] + 125["Segment
[1147, 1229, 9]"] + 126["Segment
[1237, 1319, 9]"] + 127["Segment
[1327, 1334, 9]"] 128[Solid2d] end subgraph path149 [Path] - 149["Path
[1469, 1538, 8]"] - 150["Segment
[1469, 1538, 8]"] + 149["Path
[1468, 1537, 9]"] + 150["Segment
[1468, 1537, 9]"] 151[Solid2d] end subgraph path158 [Path] - 158["Path
[378, 468, 9]"] - 159["Segment
[476, 558, 9]"] - 160["Segment
[566, 648, 9]"] - 161["Segment
[656, 738, 9]"] - 162["Segment
[746, 827, 9]"] - 163["Segment
[835, 916, 9]"] - 164["Segment
[924, 931, 9]"] + 158["Path
[378, 468, 10]"] + 159["Segment
[476, 558, 10]"] + 160["Segment
[566, 648, 10]"] + 161["Segment
[656, 738, 10]"] + 162["Segment
[746, 827, 10]"] + 163["Segment
[835, 916, 10]"] + 164["Segment
[924, 931, 10]"] 165[Solid2d] end subgraph path187 [Path] - 187["Path
[1075, 1127, 9]"] - 188["Segment
[1075, 1127, 9]"] + 187["Path
[1075, 1127, 10]"] + 188["Segment
[1075, 1127, 10]"] 189[Solid2d] end subgraph path195 [Path] - 195["Path
[313, 371, 10]"] - 196["Segment
[313, 371, 10]"] + 195["Path
[313, 371, 11]"] + 196["Segment
[313, 371, 11]"] 197[Solid2d] end subgraph path204 [Path] - 204["Path
[510, 565, 10]"] - 205["Segment
[510, 565, 10]"] + 204["Path
[510, 565, 11]"] + 205["Segment
[510, 565, 11]"] 206[Solid2d] end subgraph path212 [Path] - 212["Path
[313, 371, 10]"] - 213["Segment
[313, 371, 10]"] + 212["Path
[313, 371, 11]"] + 213["Segment
[313, 371, 11]"] 214[Solid2d] end subgraph path221 [Path] - 221["Path
[510, 565, 10]"] - 222["Segment
[510, 565, 10]"] + 221["Path
[510, 565, 11]"] + 222["Segment
[510, 565, 11]"] 223[Solid2d] end - 1["Plane
[512, 529, 5]"] - 5["Plane
[834, 851, 5]"] - 9["Sweep Extrusion
[952, 992, 5]"] + 1["Plane
[512, 529, 6]"] + 5["Plane
[834, 851, 6]"] + 9["Sweep Extrusion
[952, 992, 6]"] 10[Wall] 11["Cap Start"] 12["Cap End"] 13["SweepEdge Opposite"] 14["SweepEdge Adjacent"] - 18["Sweep Extrusion
[1196, 1233, 5]"] + 18["Sweep Extrusion
[1196, 1233, 6]"] 19[Wall] 20["Cap End"] 21["SweepEdge Opposite"] 22["SweepEdge Adjacent"] - 26["Sweep Extrusion
[1358, 1396, 5]"] + 26["Sweep Extrusion
[1358, 1396, 6]"] 27[Wall] 28["Cap End"] 29["SweepEdge Opposite"] 30["SweepEdge Adjacent"] - 34["Sweep Extrusion
[1568, 1610, 5]"] + 34["Sweep Extrusion
[1568, 1610, 6]"] 35[Wall] 36["SweepEdge Opposite"] 37["SweepEdge Adjacent"] - 38["Plane
[512, 529, 5]"] - 42["Plane
[834, 851, 5]"] - 46["Sweep Extrusion
[952, 992, 5]"] + 38["Plane
[512, 529, 6]"] + 42["Plane
[834, 851, 6]"] + 46["Sweep Extrusion
[952, 992, 6]"] 47[Wall] 48["Cap Start"] 49["Cap End"] 50["SweepEdge Opposite"] 51["SweepEdge Adjacent"] - 55["Sweep Extrusion
[1196, 1233, 5]"] + 55["Sweep Extrusion
[1196, 1233, 6]"] 56[Wall] 57["Cap End"] 58["SweepEdge Opposite"] 59["SweepEdge Adjacent"] - 63["Sweep Extrusion
[1358, 1396, 5]"] + 63["Sweep Extrusion
[1358, 1396, 6]"] 64[Wall] 65["Cap End"] 66["SweepEdge Opposite"] 67["SweepEdge Adjacent"] - 71["Sweep Extrusion
[1568, 1610, 5]"] + 71["Sweep Extrusion
[1568, 1610, 6]"] 72[Wall] 73["SweepEdge Opposite"] 74["SweepEdge Adjacent"] - 75["Plane
[469, 486, 6]"] - 79["Sweep Extrusion
[564, 600, 6]"] + 75["Plane
[469, 486, 7]"] + 79["Sweep Extrusion
[564, 600, 7]"] 80[Wall] 81["Cap Start"] 82["Cap End"] 83["SweepEdge Opposite"] 84["SweepEdge Adjacent"] - 88["Sweep Extrusion
[774, 811, 6]"] + 88["Sweep Extrusion
[774, 811, 7]"] 89[Wall] 90["SweepEdge Opposite"] 91["SweepEdge Adjacent"] - 92["Plane
[330, 347, 7]"] - 96["Sweep Extrusion
[415, 448, 7]"] + 92["Plane
[329, 346, 8]"] + 96["Sweep Extrusion
[414, 447, 8]"] 97[Wall] 98["Cap Start"] 99["Cap End"] 100["SweepEdge Opposite"] 101["SweepEdge Adjacent"] - 105["Sweep Extrusion
[600, 637, 7]"] + 105["Sweep Extrusion
[599, 636, 8]"] 106[Wall] 107["SweepEdge Opposite"] 108["SweepEdge Adjacent"] - 109["Plane
[421, 438, 8]"] - 113["Sweep Extrusion
[524, 557, 8]"] + 109["Plane
[420, 437, 9]"] + 113["Sweep Extrusion
[523, 556, 9]"] 114[Wall] 115["Cap Start"] 116["Cap End"] 117["SweepEdge Opposite"] 118["SweepEdge Adjacent"] - 119["EdgeCut Fillet
[565, 631, 8]"] - 120["EdgeCut Fillet
[565, 631, 8]"] - 129["Sweep Extrusion
[1343, 1383, 8]"] + 119["EdgeCut Fillet
[564, 630, 9]"] + 120["EdgeCut Fillet
[564, 630, 9]"] + 129["Sweep Extrusion
[1342, 1382, 9]"] 130[Wall] 131[Wall] 132[Wall] @@ -220,13 +220,13 @@ flowchart LR 146["SweepEdge Adjacent"] 147["SweepEdge Opposite"] 148["SweepEdge Adjacent"] - 152["Sweep Extrusion
[1546, 1574, 8]"] + 152["Sweep Extrusion
[1545, 1573, 9]"] 153[Wall] 154["Cap End"] 155["SweepEdge Opposite"] 156["SweepEdge Adjacent"] - 157["Plane
[353, 370, 9]"] - 166["Sweep Extrusion
[939, 972, 9]"] + 157["Plane
[353, 370, 10]"] + 166["Sweep Extrusion
[939, 972, 10]"] 167[Wall] 168[Wall] 169[Wall] @@ -247,45 +247,45 @@ flowchart LR 184["SweepEdge Adjacent"] 185["SweepEdge Opposite"] 186["SweepEdge Adjacent"] - 190["Sweep Extrusion
[1135, 1172, 9]"] + 190["Sweep Extrusion
[1135, 1172, 10]"] 191[Wall] 192["SweepEdge Opposite"] 193["SweepEdge Adjacent"] - 194["Plane
[288, 305, 10]"] - 198["Sweep Extrusion
[379, 410, 10]"] + 194["Plane
[288, 305, 11]"] + 198["Sweep Extrusion
[379, 410, 11]"] 199[Wall] 200["Cap Start"] 201["Cap End"] 202["SweepEdge Opposite"] 203["SweepEdge Adjacent"] - 207["Sweep Extrusion
[573, 605, 10]"] + 207["Sweep Extrusion
[573, 605, 11]"] 208[Wall] 209["SweepEdge Opposite"] 210["SweepEdge Adjacent"] - 211["Plane
[288, 305, 10]"] - 215["Sweep Extrusion
[379, 410, 10]"] + 211["Plane
[288, 305, 11]"] + 215["Sweep Extrusion
[379, 410, 11]"] 216[Wall] 217["Cap Start"] 218["Cap End"] 219["SweepEdge Opposite"] 220["SweepEdge Adjacent"] - 224["Sweep Extrusion
[573, 605, 10]"] + 224["Sweep Extrusion
[573, 605, 11]"] 225[Wall] 226["SweepEdge Opposite"] 227["SweepEdge Adjacent"] - 228["StartSketchOnFace
[1087, 1121, 5]"] - 229["StartSketchOnFace
[1250, 1282, 5]"] - 230["StartSketchOnFace
[1466, 1499, 5]"] - 231["StartSketchOnFace
[1087, 1121, 5]"] - 232["StartSketchOnFace
[1250, 1282, 5]"] - 233["StartSketchOnFace
[1466, 1499, 5]"] - 234["StartSketchOnFace
[666, 698, 6]"] - 235["StartSketchOnFace
[500, 532, 7]"] - 236["StartSketchOnFace
[740, 772, 8]"] - 237["StartSketchOnFace
[1431, 1461, 8]"] - 238["StartSketchOnFace
[1035, 1067, 9]"] - 239["StartSketchOnFace
[472, 502, 10]"] - 240["StartSketchOnFace
[472, 502, 10]"] + 228["StartSketchOnFace
[1087, 1121, 6]"] + 229["StartSketchOnFace
[1250, 1282, 6]"] + 230["StartSketchOnFace
[1466, 1499, 6]"] + 231["StartSketchOnFace
[1087, 1121, 6]"] + 232["StartSketchOnFace
[1250, 1282, 6]"] + 233["StartSketchOnFace
[1466, 1499, 6]"] + 234["StartSketchOnFace
[666, 698, 7]"] + 235["StartSketchOnFace
[499, 531, 8]"] + 236["StartSketchOnFace
[739, 771, 9]"] + 237["StartSketchOnFace
[1430, 1460, 9]"] + 238["StartSketchOnFace
[1035, 1067, 10]"] + 239["StartSketchOnFace
[472, 502, 11]"] + 240["StartSketchOnFace
[472, 502, 11]"] 1 --- 2 2 --- 3 2 --- 4 diff --git a/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/ast.snap b/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/ast.snap index 33999ead1..7c314b1cc 100644 --- a/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/ast.snap +++ b/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/ast.snap @@ -382,102 +382,113 @@ description: Result of parsing pipe-flange-assembly.kcl "label": { "commentStart": 781, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 793, - "elements": [ - { - "commentStart": 802, + "commentStart": 785, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 788, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 792, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 795, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 799, + "end": 0, + "left": { + "commentStart": 799, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 799, "end": 0, - "raw": "0", + "name": { + "commentStart": 799, + "end": 0, + "name": "flangeBackHeight", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "*", + "right": { + "commentStart": 818, + "end": 0, + "raw": "2", "start": 0, "type": "Literal", "type": "Literal", "value": { - "value": 0.0, + "value": 2.0, "suffix": "None" } }, - { - "commentStart": 812, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - }, - { + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "operator": "+", + "right": { + "abs_path": false, + "commentStart": 822, + "end": 0, + "name": { "commentStart": 822, "end": 0, - "left": { - "commentStart": 822, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 822, - "end": 0, - "name": { - "commentStart": 822, - "end": 0, - "name": "flangeBackHeight", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "*", - "right": { - "commentStart": 841, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "operator": "+", - "right": { - "abs_path": false, - "commentStart": 845, - "end": 0, - "name": { - "commentStart": 845, - "end": 0, - "name": "gasketThickness", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, + "name": "gasketThickness", "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - } - ], - "end": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "BinaryExpression", + "type": "BinaryExpression" } } ], @@ -510,7 +521,7 @@ description: Result of parsing pipe-flange-assembly.kcl "nonCodeNodes": { "2": [ { - "commentStart": 868, + "commentStart": 838, "end": 0, "start": 0, "type": "NonCodeNode", @@ -533,7 +544,7 @@ description: Result of parsing pipe-flange-assembly.kcl "type": "ExpressionStatement" }, { - "commentStart": 906, + "commentStart": 876, "end": 0, "expression": { "body": [ @@ -541,10 +552,10 @@ description: Result of parsing pipe-flange-assembly.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 906, + "commentStart": 876, "end": 0, "name": { - "commentStart": 906, + "commentStart": 876, "end": 0, "name": "gasket", "start": 0, @@ -554,7 +565,7 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 906, + "commentStart": 876, "end": 0, "start": 0, "type": "CallExpression", @@ -565,101 +576,112 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 930, + "commentStart": 900, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 942, - "elements": [ - { - "commentStart": 951, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - }, - { - "commentStart": 961, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - }, - { - "commentStart": 971, - "end": 0, - "left": { - "argument": { - "abs_path": false, - "commentStart": 972, - "end": 0, - "name": { - "commentStart": 972, - "end": 0, - "name": "flangeBackHeight", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "commentStart": 971, - "end": 0, - "operator": "-", - "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" - }, - "operator": "-", - "right": { - "abs_path": false, - "commentStart": 991, - "end": 0, - "name": { - "commentStart": 991, - "end": 0, - "name": "gasketThickness", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - } - ], + "commentStart": 904, "end": 0, + "raw": "0", "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 907, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 911, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 914, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 918, + "end": 0, + "left": { + "argument": { + "abs_path": false, + "commentStart": 919, + "end": 0, + "name": { + "commentStart": 919, + "end": 0, + "name": "flangeBackHeight", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "commentStart": 918, + "end": 0, + "operator": "-", + "start": 0, + "type": "UnaryExpression", + "type": "UnaryExpression" + }, + "operator": "-", + "right": { + "abs_path": false, + "commentStart": 938, + "end": 0, + "name": { + "commentStart": 938, + "end": 0, + "name": "gasketThickness", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" } } ], "callee": { "abs_path": false, - "commentStart": 920, + "commentStart": 890, "end": 0, "name": { - "commentStart": 920, + "commentStart": 890, "end": 0, "name": "translate", "start": 0, @@ -669,7 +691,7 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 920, + "commentStart": 890, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -677,13 +699,13 @@ description: Result of parsing pipe-flange-assembly.kcl "unlabeled": null } ], - "commentStart": 906, + "commentStart": 876, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "1": [ { - "commentStart": 1014, + "commentStart": 954, "end": 0, "start": 0, "type": "NonCodeNode", @@ -706,7 +728,7 @@ description: Result of parsing pipe-flange-assembly.kcl "type": "ExpressionStatement" }, { - "commentStart": 1063, + "commentStart": 1003, "end": 0, "expression": { "body": [ @@ -714,10 +736,10 @@ description: Result of parsing pipe-flange-assembly.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 1063, + "commentStart": 1003, "end": 0, "name": { - "commentStart": 1063, + "commentStart": 1003, "end": 0, "name": "washer", "start": 0, @@ -727,7 +749,7 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 1063, + "commentStart": 1003, "end": 0, "start": 0, "type": "CallExpression", @@ -738,93 +760,104 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1087, + "commentStart": 1027, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1099, - "elements": [ - { - "commentStart": 1108, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 1108, - "end": 0, - "name": { - "commentStart": 1108, - "end": 0, - "name": "mountingHolePlacementDiameter", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "/", - "right": { - "commentStart": 1140, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - { - "commentStart": 1150, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - }, - { - "abs_path": false, - "commentStart": 1160, - "end": 0, - "name": { - "commentStart": 1160, - "end": 0, - "name": "flangeBaseThickness", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - } - ], + "commentStart": 1031, "end": 0, + "left": { + "abs_path": false, + "commentStart": 1031, + "end": 0, + "name": { + "commentStart": 1031, + "end": 0, + "name": "mountingHolePlacementDiameter", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "/", + "right": { + "commentStart": 1063, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "BinaryExpression", + "type": "BinaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1066, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1070, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1073, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "abs_path": false, + "commentStart": 1077, + "end": 0, + "name": { + "commentStart": 1077, + "end": 0, + "name": "flangeBaseThickness", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" } } ], "callee": { "abs_path": false, - "commentStart": 1077, + "commentStart": 1017, "end": 0, "name": { - "commentStart": 1077, + "commentStart": 1017, "end": 0, "name": "translate", "start": 0, @@ -834,7 +867,7 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 1077, + "commentStart": 1017, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -846,14 +879,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1229, + "commentStart": 1139, "end": 0, "name": "instances", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1241, + "commentStart": 1151, "end": 0, "raw": "4", "start": 0, @@ -868,17 +901,17 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1251, + "commentStart": 1161, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1258, + "commentStart": 1168, "elements": [ { - "commentStart": 1259, + "commentStart": 1169, "end": 0, "raw": "0", "start": 0, @@ -890,7 +923,7 @@ description: Result of parsing pipe-flange-assembly.kcl } }, { - "commentStart": 1262, + "commentStart": 1172, "end": 0, "raw": "0", "start": 0, @@ -902,7 +935,7 @@ description: Result of parsing pipe-flange-assembly.kcl } }, { - "commentStart": 1265, + "commentStart": 1175, "end": 0, "raw": "1", "start": 0, @@ -923,17 +956,17 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1276, + "commentStart": 1186, "end": 0, "name": "center", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1285, + "commentStart": 1195, "elements": [ { - "commentStart": 1286, + "commentStart": 1196, "end": 0, "raw": "0", "start": 0, @@ -945,7 +978,7 @@ description: Result of parsing pipe-flange-assembly.kcl } }, { - "commentStart": 1289, + "commentStart": 1199, "end": 0, "raw": "0", "start": 0, @@ -957,7 +990,7 @@ description: Result of parsing pipe-flange-assembly.kcl } }, { - "commentStart": 1292, + "commentStart": 1202, "end": 0, "raw": "0", "start": 0, @@ -978,14 +1011,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1303, + "commentStart": 1213, "end": 0, "name": "arcDegrees", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1316, + "commentStart": 1226, "end": 0, "raw": "360", "start": 0, @@ -1000,14 +1033,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1328, + "commentStart": 1238, "end": 0, "name": "rotateDuplicates", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1347, + "commentStart": 1257, "end": 0, "raw": "false", "start": 0, @@ -1019,10 +1052,10 @@ description: Result of parsing pipe-flange-assembly.kcl ], "callee": { "abs_path": false, - "commentStart": 1193, + "commentStart": 1103, "end": 0, "name": { - "commentStart": 1193, + "commentStart": 1103, "end": 0, "name": "patternCircular3d", "start": 0, @@ -1032,13 +1065,13 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 1193, + "commentStart": 1103, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { - "commentStart": 1219, + "commentStart": 1129, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -1050,14 +1083,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1400, + "commentStart": 1310, "end": 0, "name": "instances", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1412, + "commentStart": 1322, "end": 0, "raw": "2", "start": 0, @@ -1072,7 +1105,7 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1422, + "commentStart": 1332, "end": 0, "name": "distance", "start": 0, @@ -1080,23 +1113,23 @@ description: Result of parsing pipe-flange-assembly.kcl }, "arg": { "argument": { - "commentStart": 1435, + "commentStart": 1345, "end": 0, "left": { - "commentStart": 1435, + "commentStart": 1345, "end": 0, "left": { - "commentStart": 1435, + "commentStart": 1345, "end": 0, "left": { - "commentStart": 1435, + "commentStart": 1345, "end": 0, "left": { "abs_path": false, - "commentStart": 1435, + "commentStart": 1345, "end": 0, "name": { - "commentStart": 1435, + "commentStart": 1345, "end": 0, "name": "flangeBaseThickness", "start": 0, @@ -1109,7 +1142,7 @@ description: Result of parsing pipe-flange-assembly.kcl }, "operator": "*", "right": { - "commentStart": 1457, + "commentStart": 1367, "end": 0, "raw": "2", "start": 0, @@ -1126,14 +1159,14 @@ description: Result of parsing pipe-flange-assembly.kcl }, "operator": "+", "right": { - "commentStart": 1461, + "commentStart": 1371, "end": 0, "left": { "abs_path": false, - "commentStart": 1461, + "commentStart": 1371, "end": 0, "name": { - "commentStart": 1461, + "commentStart": 1371, "end": 0, "name": "flangeBackHeight", "start": 0, @@ -1146,7 +1179,7 @@ description: Result of parsing pipe-flange-assembly.kcl }, "operator": "*", "right": { - "commentStart": 1480, + "commentStart": 1390, "end": 0, "raw": "2", "start": 0, @@ -1168,10 +1201,10 @@ description: Result of parsing pipe-flange-assembly.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 1484, + "commentStart": 1394, "end": 0, "name": { - "commentStart": 1484, + "commentStart": 1394, "end": 0, "name": "gasketThickness", "start": 0, @@ -1189,10 +1222,10 @@ description: Result of parsing pipe-flange-assembly.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 1502, + "commentStart": 1412, "end": 0, "name": { - "commentStart": 1502, + "commentStart": 1412, "end": 0, "name": "washerThickness", "start": 0, @@ -1207,7 +1240,7 @@ description: Result of parsing pipe-flange-assembly.kcl "type": "BinaryExpression", "type": "BinaryExpression" }, - "commentStart": 1433, + "commentStart": 1343, "end": 0, "operator": "-", "start": 0, @@ -1218,17 +1251,17 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1527, + "commentStart": 1437, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1534, + "commentStart": 1444, "elements": [ { - "commentStart": 1535, + "commentStart": 1445, "end": 0, "raw": "0", "start": 0, @@ -1240,7 +1273,7 @@ description: Result of parsing pipe-flange-assembly.kcl } }, { - "commentStart": 1538, + "commentStart": 1448, "end": 0, "raw": "0", "start": 0, @@ -1252,7 +1285,7 @@ description: Result of parsing pipe-flange-assembly.kcl } }, { - "commentStart": 1541, + "commentStart": 1451, "end": 0, "raw": "1", "start": 0, @@ -1273,10 +1306,10 @@ description: Result of parsing pipe-flange-assembly.kcl ], "callee": { "abs_path": false, - "commentStart": 1366, + "commentStart": 1276, "end": 0, "name": { - "commentStart": 1366, + "commentStart": 1276, "end": 0, "name": "patternLinear3d", "start": 0, @@ -1286,13 +1319,13 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 1366, + "commentStart": 1276, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { - "commentStart": 1390, + "commentStart": 1300, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -1300,13 +1333,13 @@ description: Result of parsing pipe-flange-assembly.kcl } } ], - "commentStart": 1063, + "commentStart": 1003, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "3": [ { - "commentStart": 1551, + "commentStart": 1461, "end": 0, "start": 0, "type": "NonCodeNode", @@ -1329,7 +1362,7 @@ description: Result of parsing pipe-flange-assembly.kcl "type": "ExpressionStatement" }, { - "commentStart": 1573, + "commentStart": 1483, "end": 0, "expression": { "body": [ @@ -1337,10 +1370,10 @@ description: Result of parsing pipe-flange-assembly.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 1573, + "commentStart": 1483, "end": 0, "name": { - "commentStart": 1573, + "commentStart": 1483, "end": 0, "name": "bolt", "start": 0, @@ -1350,7 +1383,7 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 1573, + "commentStart": 1483, "end": 0, "start": 0, "type": "CallExpression", @@ -1361,117 +1394,128 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1595, + "commentStart": 1505, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1607, - "elements": [ - { - "commentStart": 1616, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 1616, - "end": 0, - "name": { - "commentStart": 1616, - "end": 0, - "name": "mountingHolePlacementDiameter", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "/", - "right": { - "commentStart": 1648, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - { - "commentStart": 1658, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - }, - { - "commentStart": 1668, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 1668, - "end": 0, - "name": { - "commentStart": 1668, - "end": 0, - "name": "flangeBaseThickness", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "+", - "right": { - "abs_path": false, - "commentStart": 1690, - "end": 0, - "name": { - "commentStart": 1690, - "end": 0, - "name": "washerThickness", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - } - ], + "commentStart": 1509, "end": 0, + "left": { + "abs_path": false, + "commentStart": 1509, + "end": 0, + "name": { + "commentStart": 1509, + "end": 0, + "name": "mountingHolePlacementDiameter", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "/", + "right": { + "commentStart": 1541, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "BinaryExpression", + "type": "BinaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1544, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1548, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1551, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1555, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 1555, + "end": 0, + "name": { + "commentStart": 1555, + "end": 0, + "name": "flangeBaseThickness", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "+", + "right": { + "abs_path": false, + "commentStart": 1577, + "end": 0, + "name": { + "commentStart": 1577, + "end": 0, + "name": "washerThickness", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" } } ], "callee": { "abs_path": false, - "commentStart": 1585, + "commentStart": 1495, "end": 0, "name": { - "commentStart": 1585, + "commentStart": 1495, "end": 0, "name": "translate", "start": 0, @@ -1481,7 +1525,7 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 1585, + "commentStart": 1495, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1493,14 +1537,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1726, + "commentStart": 1606, "end": 0, "name": "roll", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1733, + "commentStart": 1613, "end": 0, "raw": "90", "start": 0, @@ -1515,14 +1559,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1737, + "commentStart": 1617, "end": 0, "name": "pitch", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1745, + "commentStart": 1625, "end": 0, "raw": "0", "start": 0, @@ -1537,14 +1581,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1748, + "commentStart": 1628, "end": 0, "name": "yaw", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1754, + "commentStart": 1634, "end": 0, "raw": "0", "start": 0, @@ -1559,10 +1603,10 @@ description: Result of parsing pipe-flange-assembly.kcl ], "callee": { "abs_path": false, - "commentStart": 1719, + "commentStart": 1599, "end": 0, "name": { - "commentStart": 1719, + "commentStart": 1599, "end": 0, "name": "rotate", "start": 0, @@ -1572,7 +1616,7 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 1719, + "commentStart": 1599, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1584,14 +1628,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1798, + "commentStart": 1678, "end": 0, "name": "instances", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1810, + "commentStart": 1690, "end": 0, "raw": "4", "start": 0, @@ -1606,17 +1650,17 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1820, + "commentStart": 1700, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1827, + "commentStart": 1707, "elements": [ { - "commentStart": 1828, + "commentStart": 1708, "end": 0, "raw": "0", "start": 0, @@ -1628,7 +1672,7 @@ description: Result of parsing pipe-flange-assembly.kcl } }, { - "commentStart": 1831, + "commentStart": 1711, "end": 0, "raw": "0", "start": 0, @@ -1640,7 +1684,7 @@ description: Result of parsing pipe-flange-assembly.kcl } }, { - "commentStart": 1834, + "commentStart": 1714, "end": 0, "raw": "1", "start": 0, @@ -1661,17 +1705,17 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1845, + "commentStart": 1725, "end": 0, "name": "center", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1854, + "commentStart": 1734, "elements": [ { - "commentStart": 1855, + "commentStart": 1735, "end": 0, "raw": "0", "start": 0, @@ -1683,7 +1727,7 @@ description: Result of parsing pipe-flange-assembly.kcl } }, { - "commentStart": 1858, + "commentStart": 1738, "end": 0, "raw": "0", "start": 0, @@ -1695,7 +1739,7 @@ description: Result of parsing pipe-flange-assembly.kcl } }, { - "commentStart": 1861, + "commentStart": 1741, "end": 0, "raw": "0", "start": 0, @@ -1716,14 +1760,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1872, + "commentStart": 1752, "end": 0, "name": "arcDegrees", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1885, + "commentStart": 1765, "end": 0, "raw": "360", "start": 0, @@ -1738,14 +1782,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1897, + "commentStart": 1777, "end": 0, "name": "rotateDuplicates", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1916, + "commentStart": 1796, "end": 0, "raw": "false", "start": 0, @@ -1757,10 +1801,10 @@ description: Result of parsing pipe-flange-assembly.kcl ], "callee": { "abs_path": false, - "commentStart": 1762, + "commentStart": 1642, "end": 0, "name": { - "commentStart": 1762, + "commentStart": 1642, "end": 0, "name": "patternCircular3d", "start": 0, @@ -1770,13 +1814,13 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 1762, + "commentStart": 1642, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { - "commentStart": 1788, + "commentStart": 1668, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -1784,13 +1828,13 @@ description: Result of parsing pipe-flange-assembly.kcl } } ], - "commentStart": 1573, + "commentStart": 1483, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "3": [ { - "commentStart": 1929, + "commentStart": 1809, "end": 0, "start": 0, "type": "NonCodeNode", @@ -1813,7 +1857,7 @@ description: Result of parsing pipe-flange-assembly.kcl "type": "ExpressionStatement" }, { - "commentStart": 1954, + "commentStart": 1834, "end": 0, "expression": { "body": [ @@ -1821,10 +1865,10 @@ description: Result of parsing pipe-flange-assembly.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 1954, + "commentStart": 1834, "end": 0, "name": { - "commentStart": 1954, + "commentStart": 1834, "end": 0, "name": "hexNut", "start": 0, @@ -1834,7 +1878,7 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 1954, + "commentStart": 1834, "end": 0, "start": 0, "type": "CallExpression", @@ -1845,142 +1889,104 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 1978, + "commentStart": 1858, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1990, - "elements": [ - { - "commentStart": 1999, + "commentStart": 1862, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 1862, + "end": 0, + "name": { + "commentStart": 1862, + "end": 0, + "name": "mountingHolePlacementDiameter", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "/", + "right": { + "commentStart": 1894, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1897, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1901, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1904, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "argument": { + "commentStart": 1910, + "end": 0, + "left": { + "commentStart": 1910, "end": 0, "left": { - "abs_path": false, - "commentStart": 1999, - "end": 0, - "name": { - "commentStart": 1999, - "end": 0, - "name": "mountingHolePlacementDiameter", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "/", - "right": { - "commentStart": 2031, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - { - "commentStart": 2041, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - }, - { - "argument": { - "commentStart": 2053, + "commentStart": 1910, "end": 0, "left": { - "commentStart": 2053, + "commentStart": 1910, "end": 0, "left": { - "commentStart": 2053, + "commentStart": 1910, "end": 0, "left": { - "commentStart": 2053, - "end": 0, - "left": { - "commentStart": 2053, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 2053, - "end": 0, - "name": { - "commentStart": 2053, - "end": 0, - "name": "flangeBackHeight", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "*", - "right": { - "commentStart": 2072, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "operator": "+", - "right": { - "abs_path": false, - "commentStart": 2076, - "end": 0, - "name": { - "commentStart": 2076, - "end": 0, - "name": "gasketThickness", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "operator": "+", - "right": { "abs_path": false, - "commentStart": 2094, + "commentStart": 1910, "end": 0, "name": { - "commentStart": 2094, + "commentStart": 1910, "end": 0, - "name": "flangeBaseThickness", + "name": "flangeBackHeight", "start": 0, "type": "Identifier" }, @@ -1989,6 +1995,19 @@ description: Result of parsing pipe-flange-assembly.kcl "type": "Name", "type": "Name" }, + "operator": "*", + "right": { + "commentStart": 1929, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, "start": 0, "type": "BinaryExpression", "type": "BinaryExpression" @@ -1996,12 +2015,12 @@ description: Result of parsing pipe-flange-assembly.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 2116, + "commentStart": 1933, "end": 0, "name": { - "commentStart": 2116, + "commentStart": 1933, "end": 0, - "name": "washerThickness", + "name": "gasketThickness", "start": 0, "type": "Identifier" }, @@ -2017,12 +2036,12 @@ description: Result of parsing pipe-flange-assembly.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 2134, + "commentStart": 1951, "end": 0, "name": { - "commentStart": 2134, + "commentStart": 1951, "end": 0, - "name": "hexNutThickness", + "name": "flangeBaseThickness", "start": 0, "type": "Identifier" }, @@ -2035,27 +2054,63 @@ description: Result of parsing pipe-flange-assembly.kcl "type": "BinaryExpression", "type": "BinaryExpression" }, - "commentStart": 2051, - "end": 0, - "operator": "-", + "operator": "+", + "right": { + "abs_path": false, + "commentStart": 1973, + "end": 0, + "name": { + "commentStart": 1973, + "end": 0, + "name": "washerThickness", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" - } - ], + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "operator": "+", + "right": { + "abs_path": false, + "commentStart": 1991, + "end": 0, + "name": { + "commentStart": 1991, + "end": 0, + "name": "hexNutThickness", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "commentStart": 1908, "end": 0, + "operator": "-", "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "UnaryExpression", + "type": "UnaryExpression" } } ], "callee": { "abs_path": false, - "commentStart": 1968, + "commentStart": 1848, "end": 0, "name": { - "commentStart": 1968, + "commentStart": 1848, "end": 0, "name": "translate", "start": 0, @@ -2065,7 +2120,7 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 1968, + "commentStart": 1848, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2077,14 +2132,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 2200, + "commentStart": 2050, "end": 0, "name": "instances", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2212, + "commentStart": 2062, "end": 0, "raw": "4", "start": 0, @@ -2099,17 +2154,17 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 2222, + "commentStart": 2072, "end": 0, "name": "axis", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2229, + "commentStart": 2079, "elements": [ { - "commentStart": 2230, + "commentStart": 2080, "end": 0, "raw": "0", "start": 0, @@ -2121,7 +2176,7 @@ description: Result of parsing pipe-flange-assembly.kcl } }, { - "commentStart": 2233, + "commentStart": 2083, "end": 0, "raw": "0", "start": 0, @@ -2133,7 +2188,7 @@ description: Result of parsing pipe-flange-assembly.kcl } }, { - "commentStart": 2236, + "commentStart": 2086, "end": 0, "raw": "1", "start": 0, @@ -2154,17 +2209,17 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 2247, + "commentStart": 2097, "end": 0, "name": "center", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2256, + "commentStart": 2106, "elements": [ { - "commentStart": 2257, + "commentStart": 2107, "end": 0, "raw": "0", "start": 0, @@ -2176,7 +2231,7 @@ description: Result of parsing pipe-flange-assembly.kcl } }, { - "commentStart": 2260, + "commentStart": 2110, "end": 0, "raw": "0", "start": 0, @@ -2188,7 +2243,7 @@ description: Result of parsing pipe-flange-assembly.kcl } }, { - "commentStart": 2263, + "commentStart": 2113, "end": 0, "raw": "0", "start": 0, @@ -2209,14 +2264,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 2274, + "commentStart": 2124, "end": 0, "name": "arcDegrees", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2287, + "commentStart": 2137, "end": 0, "raw": "360", "start": 0, @@ -2231,14 +2286,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 2299, + "commentStart": 2149, "end": 0, "name": "rotateDuplicates", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2318, + "commentStart": 2168, "end": 0, "raw": "false", "start": 0, @@ -2250,10 +2305,10 @@ description: Result of parsing pipe-flange-assembly.kcl ], "callee": { "abs_path": false, - "commentStart": 2164, + "commentStart": 2014, "end": 0, "name": { - "commentStart": 2164, + "commentStart": 2014, "end": 0, "name": "patternCircular3d", "start": 0, @@ -2263,13 +2318,13 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 2164, + "commentStart": 2014, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { - "commentStart": 2190, + "commentStart": 2040, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2277,13 +2332,13 @@ description: Result of parsing pipe-flange-assembly.kcl } } ], - "commentStart": 1954, + "commentStart": 1834, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "2": [ { - "commentStart": 2331, + "commentStart": 2181, "end": 0, "start": 0, "type": "NonCodeNode", @@ -2306,7 +2361,7 @@ description: Result of parsing pipe-flange-assembly.kcl "type": "ExpressionStatement" }, { - "commentStart": 2362, + "commentStart": 2212, "end": 0, "expression": { "body": [ @@ -2314,10 +2369,10 @@ description: Result of parsing pipe-flange-assembly.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 2362, + "commentStart": 2212, "end": 0, "name": { - "commentStart": 2362, + "commentStart": 2212, "end": 0, "name": "pipe", "start": 0, @@ -2327,7 +2382,7 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 2362, + "commentStart": 2212, "end": 0, "start": 0, "type": "CallExpression", @@ -2338,7 +2393,7 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 2399, + "commentStart": 2249, "end": 0, "name": "roll", "start": 0, @@ -2346,7 +2401,7 @@ description: Result of parsing pipe-flange-assembly.kcl }, "arg": { "argument": { - "commentStart": 2407, + "commentStart": 2257, "end": 0, "raw": "90", "start": 0, @@ -2357,7 +2412,7 @@ description: Result of parsing pipe-flange-assembly.kcl "suffix": "None" } }, - "commentStart": 2406, + "commentStart": 2256, "end": 0, "operator": "-", "start": 0, @@ -2368,14 +2423,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 2418, + "commentStart": 2268, "end": 0, "name": "pitch", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2426, + "commentStart": 2276, "end": 0, "raw": "0", "start": 0, @@ -2390,14 +2445,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 2436, + "commentStart": 2286, "end": 0, "name": "yaw", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2442, + "commentStart": 2292, "end": 0, "raw": "0", "start": 0, @@ -2412,10 +2467,10 @@ description: Result of parsing pipe-flange-assembly.kcl ], "callee": { "abs_path": false, - "commentStart": 2374, + "commentStart": 2224, "end": 0, "name": { - "commentStart": 2374, + "commentStart": 2224, "end": 0, "name": "rotate", "start": 0, @@ -2425,13 +2480,13 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 2374, + "commentStart": 2224, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { - "commentStart": 2389, + "commentStart": 2239, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2443,117 +2498,128 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 2485, + "commentStart": 2335, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2497, - "elements": [ - { - "commentStart": 2508, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - }, - { - "commentStart": 2520, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - }, - { - "commentStart": 2532, - "end": 0, - "left": { - "commentStart": 2532, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 2532, - "end": 0, - "name": { - "commentStart": 2532, - "end": 0, - "name": "flangeBaseThickness", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "+", - "right": { - "abs_path": false, - "commentStart": 2554, - "end": 0, - "name": { - "commentStart": 2554, - "end": 0, - "name": "flangeFrontHeight", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "operator": "-", - "right": { - "commentStart": 2574, - "end": 0, - "raw": "0.5", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.5, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - } - ], + "commentStart": 2339, "end": 0, + "raw": "0", "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } } }, { "type": "LabeledArg", "label": { - "commentStart": 2595, + "commentStart": 2349, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 2353, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 2363, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 2367, + "end": 0, + "left": { + "commentStart": 2367, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 2367, + "end": 0, + "name": { + "commentStart": 2367, + "end": 0, + "name": "flangeBaseThickness", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "+", + "right": { + "abs_path": false, + "commentStart": 2389, + "end": 0, + "name": { + "commentStart": 2389, + "end": 0, + "name": "flangeFrontHeight", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "operator": "-", + "right": { + "commentStart": 2409, + "end": 0, + "raw": "0.5", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.5, + "suffix": "None" + } + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 2421, "end": 0, "name": "global", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2604, + "commentStart": 2430, "end": 0, "raw": "true", "start": 0, @@ -2565,10 +2631,10 @@ description: Result of parsing pipe-flange-assembly.kcl ], "callee": { "abs_path": false, - "commentStart": 2457, + "commentStart": 2307, "end": 0, "name": { - "commentStart": 2457, + "commentStart": 2307, "end": 0, "name": "translate", "start": 0, @@ -2578,13 +2644,13 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 2457, + "commentStart": 2307, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { - "commentStart": 2475, + "commentStart": 2325, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2592,7 +2658,7 @@ description: Result of parsing pipe-flange-assembly.kcl } } ], - "commentStart": 2362, + "commentStart": 2212, "end": 0, "start": 0, "type": "PipeExpression", @@ -2603,7 +2669,7 @@ description: Result of parsing pipe-flange-assembly.kcl "type": "ExpressionStatement" }, { - "commentStart": 2616, + "commentStart": 2442, "end": 0, "expression": { "body": [ @@ -2611,10 +2677,10 @@ description: Result of parsing pipe-flange-assembly.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 2618, + "commentStart": 2444, "end": 0, "name": { - "commentStart": 2618, + "commentStart": 2444, "end": 0, "name": "pipe", "start": 0, @@ -2624,7 +2690,7 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 2618, + "commentStart": 2444, "end": 0, "start": 0, "type": "CallExpression", @@ -2635,14 +2701,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 2655, + "commentStart": 2481, "end": 0, "name": "roll", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2662, + "commentStart": 2488, "end": 0, "raw": "90", "start": 0, @@ -2657,14 +2723,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 2673, + "commentStart": 2499, "end": 0, "name": "pitch", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2681, + "commentStart": 2507, "end": 0, "raw": "0", "start": 0, @@ -2679,14 +2745,14 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 2691, + "commentStart": 2517, "end": 0, "name": "yaw", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2697, + "commentStart": 2523, "end": 0, "raw": "0", "start": 0, @@ -2701,10 +2767,10 @@ description: Result of parsing pipe-flange-assembly.kcl ], "callee": { "abs_path": false, - "commentStart": 2630, + "commentStart": 2456, "end": 0, "name": { - "commentStart": 2630, + "commentStart": 2456, "end": 0, "name": "rotate", "start": 0, @@ -2714,13 +2780,13 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 2630, + "commentStart": 2456, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { - "commentStart": 2645, + "commentStart": 2471, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2732,118 +2798,80 @@ description: Result of parsing pipe-flange-assembly.kcl { "type": "LabeledArg", "label": { - "commentStart": 2740, + "commentStart": 2566, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2752, - "elements": [ - { - "commentStart": 2763, + "commentStart": 2570, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 2580, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 2584, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 2594, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "argument": { + "commentStart": 2600, + "end": 0, + "left": { + "commentStart": 2600, "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - }, - { - "commentStart": 2775, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - }, - { - "argument": { - "commentStart": 2789, + "left": { + "commentStart": 2600, "end": 0, "left": { - "commentStart": 2789, + "commentStart": 2600, "end": 0, "left": { - "commentStart": 2789, + "commentStart": 2600, "end": 0, "left": { - "commentStart": 2789, - "end": 0, - "left": { - "commentStart": 2789, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 2789, - "end": 0, - "name": { - "commentStart": 2789, - "end": 0, - "name": "flangeBackHeight", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "*", - "right": { - "commentStart": 2808, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "operator": "+", - "right": { - "abs_path": false, - "commentStart": 2812, - "end": 0, - "name": { - "commentStart": 2812, - "end": 0, - "name": "gasketThickness", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "operator": "+", - "right": { "abs_path": false, - "commentStart": 2830, + "commentStart": 2600, "end": 0, "name": { - "commentStart": 2830, + "commentStart": 2600, "end": 0, - "name": "flangeBaseThickness", + "name": "flangeBackHeight", "start": 0, "type": "Identifier" }, @@ -2852,6 +2880,19 @@ description: Result of parsing pipe-flange-assembly.kcl "type": "Name", "type": "Name" }, + "operator": "*", + "right": { + "commentStart": 2619, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, "start": 0, "type": "BinaryExpression", "type": "BinaryExpression" @@ -2859,12 +2900,12 @@ description: Result of parsing pipe-flange-assembly.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 2852, + "commentStart": 2623, "end": 0, "name": { - "commentStart": 2852, + "commentStart": 2623, "end": 0, - "name": "flangeFrontHeight", + "name": "gasketThickness", "start": 0, "type": "Identifier" }, @@ -2877,48 +2918,84 @@ description: Result of parsing pipe-flange-assembly.kcl "type": "BinaryExpression", "type": "BinaryExpression" }, - "operator": "-", + "operator": "+", "right": { - "commentStart": 2872, + "abs_path": false, + "commentStart": 2641, "end": 0, - "raw": "0.5", + "name": { + "commentStart": 2641, + "end": 0, + "name": "flangeBaseThickness", + "start": 0, + "type": "Identifier" + }, + "path": [], "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.5, - "suffix": "None" - } + "type": "Name", + "type": "Name" }, "start": 0, "type": "BinaryExpression", "type": "BinaryExpression" }, - "commentStart": 2787, - "end": 0, - "operator": "-", + "operator": "+", + "right": { + "abs_path": false, + "commentStart": 2663, + "end": 0, + "name": { + "commentStart": 2663, + "end": 0, + "name": "flangeFrontHeight", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" - } - ], + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "operator": "-", + "right": { + "commentStart": 2683, + "end": 0, + "raw": "0.5", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.5, + "suffix": "None" + } + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "commentStart": 2598, "end": 0, + "operator": "-", "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "UnaryExpression", + "type": "UnaryExpression" } }, { "type": "LabeledArg", "label": { - "commentStart": 2894, + "commentStart": 2696, "end": 0, "name": "global", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2903, + "commentStart": 2705, "end": 0, "raw": "true", "start": 0, @@ -2930,10 +3007,10 @@ description: Result of parsing pipe-flange-assembly.kcl ], "callee": { "abs_path": false, - "commentStart": 2712, + "commentStart": 2538, "end": 0, "name": { - "commentStart": 2712, + "commentStart": 2538, "end": 0, "name": "translate", "start": 0, @@ -2943,13 +3020,13 @@ description: Result of parsing pipe-flange-assembly.kcl "start": 0, "type": "Name" }, - "commentStart": 2712, + "commentStart": 2538, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { - "commentStart": 2730, + "commentStart": 2556, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2957,7 +3034,7 @@ description: Result of parsing pipe-flange-assembly.kcl } } ], - "commentStart": 2618, + "commentStart": 2444, "end": 0, "start": 0, "type": "PipeExpression", @@ -3027,7 +3104,7 @@ description: Result of parsing pipe-flange-assembly.kcl "nonCodeNodes": { "13": [ { - "commentStart": 2616, + "commentStart": 2442, "end": 0, "start": 0, "type": "NonCodeNode", diff --git a/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/ops.snap b/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/ops.snap index cb6de8327..e17bbd3b9 100644 --- a/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/ops.snap +++ b/rust/kcl-lib/tests/kcl_samples/pipe-flange-assembly/ops.snap @@ -39,7 +39,7 @@ description: Operations executed pipe-flange-assembly.kcl "functionSourceRange": [ 451, 1670, - 5 + 6 ], "unlabeledArg": null, "labeledArgs": {}, @@ -657,7 +657,7 @@ description: Operations executed pipe-flange-assembly.kcl "functionSourceRange": [ 451, 1670, - 5 + 6 ], "unlabeledArg": null, "labeledArgs": {}, @@ -1275,7 +1275,7 @@ description: Operations executed pipe-flange-assembly.kcl "functionSourceRange": [ 414, 870, - 6 + 7 ], "unlabeledArg": null, "labeledArgs": {}, @@ -1523,9 +1523,9 @@ description: Operations executed pipe-flange-assembly.kcl "type": "UserDefinedFunctionCall", "name": "washer", "functionSourceRange": [ - 275, - 696, - 7 + 274, + 695, + 8 ], "unlabeledArg": null, "labeledArgs": {}, @@ -2022,9 +2022,9 @@ description: Operations executed pipe-flange-assembly.kcl "type": "UserDefinedFunctionCall", "name": "bolt", "functionSourceRange": [ - 365, - 1664, - 8 + 364, + 1663, + 9 ], "unlabeledArg": null, "labeledArgs": {}, @@ -2524,7 +2524,7 @@ description: Operations executed pipe-flange-assembly.kcl "functionSourceRange": [ 297, 1231, - 9 + 10 ], "unlabeledArg": null, "labeledArgs": {}, @@ -2839,7 +2839,7 @@ description: Operations executed pipe-flange-assembly.kcl "functionSourceRange": [ 244, 658, - 10 + 11 ], "unlabeledArg": null, "labeledArgs": {}, @@ -3083,7 +3083,7 @@ description: Operations executed pipe-flange-assembly.kcl "functionSourceRange": [ 244, 658, - 10 + 11 ], "unlabeledArg": null, "labeledArgs": {}, diff --git a/rust/kcl-lib/tests/kcl_samples/pipe-with-bend/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/pipe-with-bend/artifact_commands.snap index 669414905..adfbcf459 100644 --- a/rust/kcl-lib/tests/kcl_samples/pipe-with-bend/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/pipe-with-bend/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands pipe-with-bend.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/pipe/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/pipe/artifact_commands.snap index a738d8abb..2a00a6cbd 100644 --- a/rust/kcl-lib/tests/kcl_samples/pipe/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/pipe/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands pipe.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/poopy-shoe/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/poopy-shoe/artifact_commands.snap index 638fb7c64..a6175f25c 100644 --- a/rust/kcl-lib/tests/kcl_samples/poopy-shoe/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/poopy-shoe/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands poopy-shoe.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/artifact_commands.snap index 560ed4bf2..480854b6f 100644 --- a/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands router-template-cross-bar.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/artifact_graph_flowchart.snap.md index b064f7b19..174a00100 100644 --- a/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/artifact_graph_flowchart.snap.md @@ -1,59 +1,59 @@ ```mermaid flowchart LR subgraph path2 [Path] - 2["Path
[460, 506, 0]"] - 3["Segment
[512, 565, 0]"] - 4["Segment
[571, 673, 0]"] - 5["Segment
[679, 732, 0]"] - 6["Segment
[738, 785, 0]"] - 7["Segment
[791, 886, 0]"] - 8["Segment
[892, 963, 0]"] - 9["Segment
[969, 1020, 0]"] - 10["Segment
[1026, 1079, 0]"] - 11["Segment
[1085, 1154, 0]"] - 12["Segment
[1160, 1199, 0]"] - 13["Segment
[1205, 1235, 0]"] - 14["Segment
[1241, 1271, 0]"] - 15["Segment
[1277, 1307, 0]"] - 16["Segment
[1313, 1343, 0]"] - 17["Segment
[1349, 1378, 0]"] - 18["Segment
[1384, 1414, 0]"] - 19["Segment
[1420, 1449, 0]"] - 20["Segment
[1455, 1484, 0]"] - 21["Segment
[1490, 1586, 0]"] - 22["Segment
[1592, 1648, 0]"] - 23["Segment
[1654, 1661, 0]"] + 2["Path
[460, 503, 0]"] + 3["Segment
[509, 562, 0]"] + 4["Segment
[568, 670, 0]"] + 5["Segment
[676, 729, 0]"] + 6["Segment
[735, 782, 0]"] + 7["Segment
[788, 883, 0]"] + 8["Segment
[889, 960, 0]"] + 9["Segment
[966, 1017, 0]"] + 10["Segment
[1023, 1076, 0]"] + 11["Segment
[1082, 1151, 0]"] + 12["Segment
[1157, 1193, 0]"] + 13["Segment
[1199, 1229, 0]"] + 14["Segment
[1235, 1265, 0]"] + 15["Segment
[1271, 1301, 0]"] + 16["Segment
[1307, 1337, 0]"] + 17["Segment
[1343, 1372, 0]"] + 18["Segment
[1378, 1408, 0]"] + 19["Segment
[1414, 1443, 0]"] + 20["Segment
[1449, 1478, 0]"] + 21["Segment
[1484, 1580, 0]"] + 22["Segment
[1586, 1642, 0]"] + 23["Segment
[1648, 1655, 0]"] 24[Solid2d] end subgraph path85 [Path] - 85["Path
[1759, 1803, 0]"] - 86["Segment
[1809, 1871, 0]"] - 87["Segment
[1877, 1990, 0]"] - 88["Segment
[1996, 2116, 0]"] - 89["Segment
[2122, 2178, 0]"] - 90["Segment
[2184, 2191, 0]"] + 85["Path
[1753, 1797, 0]"] + 86["Segment
[1803, 1865, 0]"] + 87["Segment
[1871, 1984, 0]"] + 88["Segment
[1990, 2110, 0]"] + 89["Segment
[2116, 2172, 0]"] + 90["Segment
[2178, 2185, 0]"] 91[Solid2d] end subgraph path107 [Path] - 107["Path
[2290, 2335, 0]"] - 108["Segment
[2341, 2401, 0]"] - 109["Segment
[2407, 2520, 0]"] - 110["Segment
[2526, 2646, 0]"] - 111["Segment
[2652, 2708, 0]"] - 112["Segment
[2714, 2721, 0]"] + 107["Path
[2284, 2329, 0]"] + 108["Segment
[2335, 2395, 0]"] + 109["Segment
[2401, 2514, 0]"] + 110["Segment
[2520, 2640, 0]"] + 111["Segment
[2646, 2702, 0]"] + 112["Segment
[2708, 2715, 0]"] 113[Solid2d] end subgraph path129 [Path] - 129["Path
[2819, 2864, 0]"] - 130["Segment
[2870, 2937, 0]"] - 131["Segment
[2943, 3056, 0]"] - 132["Segment
[3062, 3182, 0]"] - 133["Segment
[3188, 3244, 0]"] - 134["Segment
[3250, 3257, 0]"] + 129["Path
[2813, 2858, 0]"] + 130["Segment
[2864, 2931, 0]"] + 131["Segment
[2937, 3050, 0]"] + 132["Segment
[3056, 3176, 0]"] + 133["Segment
[3182, 3238, 0]"] + 134["Segment
[3244, 3251, 0]"] 135[Solid2d] end 1["Plane
[437, 454, 0]"] - 25["Sweep Extrusion
[1675, 1705, 0]"] + 25["Sweep Extrusion
[1669, 1699, 0]"] 26[Wall] 27[Wall] 28[Wall] @@ -113,7 +113,7 @@ flowchart LR 82["SweepEdge Adjacent"] 83["SweepEdge Opposite"] 84["SweepEdge Adjacent"] - 92["Sweep Extrusion
[2205, 2236, 0]"] + 92["Sweep Extrusion
[2199, 2230, 0]"] 93[Wall] 94[Wall] 95[Wall] @@ -128,7 +128,7 @@ flowchart LR 104["SweepEdge Adjacent"] 105["SweepEdge Opposite"] 106["SweepEdge Adjacent"] - 114["Sweep Extrusion
[2736, 2767, 0]"] + 114["Sweep Extrusion
[2730, 2761, 0]"] 115[Wall] 116[Wall] 117[Wall] @@ -143,7 +143,7 @@ flowchart LR 126["SweepEdge Adjacent"] 127["SweepEdge Opposite"] 128["SweepEdge Adjacent"] - 136["Sweep Extrusion
[3271, 3301, 0]"] + 136["Sweep Extrusion
[3265, 3295, 0]"] 137[Wall] 138[Wall] 139[Wall] @@ -158,9 +158,9 @@ flowchart LR 148["SweepEdge Adjacent"] 149["SweepEdge Opposite"] 150["SweepEdge Adjacent"] - 151["StartSketchOnFace
[1719, 1753, 0]"] - 152["StartSketchOnFace
[2250, 2284, 0]"] - 153["StartSketchOnFace
[2781, 2813, 0]"] + 151["StartSketchOnFace
[1713, 1747, 0]"] + 152["StartSketchOnFace
[2244, 2278, 0]"] + 153["StartSketchOnFace
[2775, 2807, 0]"] 1 --- 2 2 --- 3 2 --- 4 diff --git a/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/ast.snap b/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/ast.snap index ec2ed7550..1c2d22a71 100644 --- a/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/ast.snap +++ b/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/ast.snap @@ -573,30 +573,26 @@ description: Result of parsing router-template-cross-bar.kcl "commentStart": 475, "elements": [ { - "abs_path": false, "commentStart": 476, "end": 0, - "name": { - "commentStart": 476, - "end": 0, - "name": "ZERO", - "start": 0, - "type": "Identifier" - }, - "path": [], + "raw": "0", "start": 0, - "type": "Name", - "type": "Name" + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } }, { - "commentStart": 482, + "commentStart": 479, "end": 0, "left": { "abs_path": false, - "commentStart": 482, + "commentStart": 479, "end": 0, "name": { - "commentStart": 482, + "commentStart": 479, "end": 0, "name": "depth", "start": 0, @@ -610,10 +606,10 @@ description: Result of parsing router-template-cross-bar.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 490, + "commentStart": 487, "end": 0, "name": { - "commentStart": 490, + "commentStart": 487, "end": 0, "name": "templateGap", "start": 0, @@ -635,7 +631,7 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ArrayExpression" }, { - "commentStart": 504, + "commentStart": 501, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -668,21 +664,21 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 518, + "commentStart": 515, "end": 0, "name": "length", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 527, + "commentStart": 524, "end": 0, "left": { "abs_path": false, - "commentStart": 527, + "commentStart": 524, "end": 0, "name": { - "commentStart": 527, + "commentStart": 524, "end": 0, "name": "slateWidthHalf", "start": 0, @@ -696,10 +692,10 @@ description: Result of parsing router-template-cross-bar.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 544, + "commentStart": 541, "end": 0, "name": { - "commentStart": 544, + "commentStart": 541, "end": 0, "name": "radius", "start": 0, @@ -718,14 +714,14 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 552, + "commentStart": 549, "end": 0, "name": "tag", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 558, + "commentStart": 555, "end": 0, "start": 0, "type": "TagDeclarator", @@ -736,10 +732,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 512, + "commentStart": 509, "end": 0, "name": { - "commentStart": 512, + "commentStart": 509, "end": 0, "name": "xLine", "start": 0, @@ -749,7 +745,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 512, + "commentStart": 509, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -759,14 +755,14 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 575, + "commentStart": 572, "end": 0, "properties": [ { - "commentStart": 584, + "commentStart": 581, "end": 0, "key": { - "commentStart": 584, + "commentStart": 581, "end": 0, "name": "angleEnd", "start": 0, @@ -775,7 +771,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 595, + "commentStart": 592, "end": 0, "raw": "0", "start": 0, @@ -788,10 +784,10 @@ description: Result of parsing router-template-cross-bar.kcl } }, { - "commentStart": 605, + "commentStart": 602, "end": 0, "key": { - "commentStart": 605, + "commentStart": 602, "end": 0, "name": "angleStart", "start": 0, @@ -800,7 +796,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 618, + "commentStart": 615, "end": 0, "raw": "90", "start": 0, @@ -813,10 +809,10 @@ description: Result of parsing router-template-cross-bar.kcl } }, { - "commentStart": 629, + "commentStart": 626, "end": 0, "key": { - "commentStart": 629, + "commentStart": 626, "end": 0, "name": "radius", "start": 0, @@ -825,10 +821,10 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 638, + "commentStart": 635, "end": 0, "left": { - "commentStart": 638, + "commentStart": 635, "end": 0, "raw": "10", "start": 0, @@ -842,10 +838,10 @@ description: Result of parsing router-template-cross-bar.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 643, + "commentStart": 640, "end": 0, "name": { - "commentStart": 643, + "commentStart": 640, "end": 0, "name": "templateGap", "start": 0, @@ -867,14 +863,14 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ObjectExpression" }, { - "commentStart": 663, + "commentStart": 660, "end": 0, "start": 0, "type": "PipeSubstitution", "type": "PipeSubstitution" }, { - "commentStart": 666, + "commentStart": 663, "end": 0, "start": 0, "type": "TagDeclarator", @@ -884,10 +880,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 571, + "commentStart": 568, "end": 0, "name": { - "commentStart": 571, + "commentStart": 568, "end": 0, "name": "arc", "start": 0, @@ -897,7 +893,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 571, + "commentStart": 568, "end": 0, "start": 0, "type": "CallExpression", @@ -908,7 +904,7 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 685, + "commentStart": 682, "end": 0, "name": "endAbsolute", "start": 0, @@ -917,10 +913,10 @@ description: Result of parsing router-template-cross-bar.kcl "arg": { "argument": { "abs_path": false, - "commentStart": 700, + "commentStart": 697, "end": 0, "name": { - "commentStart": 700, + "commentStart": 697, "end": 0, "name": "templateThickness", "start": 0, @@ -931,7 +927,7 @@ description: Result of parsing router-template-cross-bar.kcl "type": "Name", "type": "Name" }, - "commentStart": 699, + "commentStart": 696, "end": 0, "operator": "-", "start": 0, @@ -942,14 +938,14 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 719, + "commentStart": 716, "end": 0, "name": "tag", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 725, + "commentStart": 722, "end": 0, "start": 0, "type": "TagDeclarator", @@ -960,10 +956,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 679, + "commentStart": 676, "end": 0, "name": { - "commentStart": 679, + "commentStart": 676, "end": 0, "name": "yLine", "start": 0, @@ -973,7 +969,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 679, + "commentStart": 676, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -985,7 +981,7 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 744, + "commentStart": 741, "end": 0, "name": "length", "start": 0, @@ -993,10 +989,10 @@ description: Result of parsing router-template-cross-bar.kcl }, "arg": { "abs_path": false, - "commentStart": 753, + "commentStart": 750, "end": 0, "name": { - "commentStart": 753, + "commentStart": 750, "end": 0, "name": "templateThickness", "start": 0, @@ -1011,14 +1007,14 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 772, + "commentStart": 769, "end": 0, "name": "tag", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 778, + "commentStart": 775, "end": 0, "start": 0, "type": "TagDeclarator", @@ -1029,10 +1025,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 738, + "commentStart": 735, "end": 0, "name": { - "commentStart": 738, + "commentStart": 735, "end": 0, "name": "xLine", "start": 0, @@ -1042,7 +1038,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 738, + "commentStart": 735, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1054,29 +1050,29 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 797, + "commentStart": 794, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 812, + "commentStart": 809, "end": 0, "left": { - "commentStart": 812, + "commentStart": 809, "end": 0, "left": { - "commentStart": 812, + "commentStart": 809, "end": 0, "left": { "arguments": [ { "abs_path": false, - "commentStart": 820, + "commentStart": 817, "end": 0, "name": { - "commentStart": 820, + "commentStart": 817, "end": 0, "name": "seg01", "start": 0, @@ -1090,10 +1086,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 812, + "commentStart": 809, "end": 0, "name": { - "commentStart": 812, + "commentStart": 809, "end": 0, "name": "segEndY", "start": 0, @@ -1103,7 +1099,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 812, + "commentStart": 809, "end": 0, "start": 0, "type": "CallExpression", @@ -1112,10 +1108,10 @@ description: Result of parsing router-template-cross-bar.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 829, + "commentStart": 826, "end": 0, "name": { - "commentStart": 829, + "commentStart": 826, "end": 0, "name": "templateThickness", "start": 0, @@ -1132,7 +1128,7 @@ description: Result of parsing router-template-cross-bar.kcl }, "operator": "/", "right": { - "commentStart": 850, + "commentStart": 847, "end": 0, "raw": "2", "start": 0, @@ -1150,10 +1146,10 @@ description: Result of parsing router-template-cross-bar.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 854, + "commentStart": 851, "end": 0, "name": { - "commentStart": 854, + "commentStart": 851, "end": 0, "name": "templateThickness", "start": 0, @@ -1172,14 +1168,14 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 873, + "commentStart": 870, "end": 0, "name": "tag", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 879, + "commentStart": 876, "end": 0, "start": 0, "type": "TagDeclarator", @@ -1190,10 +1186,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 791, + "commentStart": 788, "end": 0, "name": { - "commentStart": 791, + "commentStart": 788, "end": 0, "name": "yLine", "start": 0, @@ -1203,7 +1199,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 791, + "commentStart": 788, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1215,23 +1211,23 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 898, + "commentStart": 895, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 912, + "commentStart": 909, "end": 0, "left": { "arguments": [ { "abs_path": false, - "commentStart": 920, + "commentStart": 917, "end": 0, "name": { - "commentStart": 920, + "commentStart": 917, "end": 0, "name": "seg03", "start": 0, @@ -1245,10 +1241,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 912, + "commentStart": 909, "end": 0, "name": { - "commentStart": 912, + "commentStart": 909, "end": 0, "name": "segEndX", "start": 0, @@ -1258,7 +1254,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 912, + "commentStart": 909, "end": 0, "start": 0, "type": "CallExpression", @@ -1267,10 +1263,10 @@ description: Result of parsing router-template-cross-bar.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 929, + "commentStart": 926, "end": 0, "name": { - "commentStart": 929, + "commentStart": 926, "end": 0, "name": "minClampingDistance", "start": 0, @@ -1289,14 +1285,14 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 950, + "commentStart": 947, "end": 0, "name": "tag", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 956, + "commentStart": 953, "end": 0, "start": 0, "type": "TagDeclarator", @@ -1307,10 +1303,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 892, + "commentStart": 889, "end": 0, "name": { - "commentStart": 892, + "commentStart": 889, "end": 0, "name": "xLine", "start": 0, @@ -1320,7 +1316,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 892, + "commentStart": 889, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1332,21 +1328,21 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 975, + "commentStart": 972, "end": 0, "name": "length", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 984, + "commentStart": 981, "end": 0, "left": { "abs_path": false, - "commentStart": 984, + "commentStart": 981, "end": 0, "name": { - "commentStart": 984, + "commentStart": 981, "end": 0, "name": "templateThickness", "start": 0, @@ -1359,7 +1355,7 @@ description: Result of parsing router-template-cross-bar.kcl }, "operator": "*", "right": { - "commentStart": 1004, + "commentStart": 1001, "end": 0, "raw": "2", "start": 0, @@ -1378,14 +1374,14 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1007, + "commentStart": 1004, "end": 0, "name": "tag", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1013, + "commentStart": 1010, "end": 0, "start": 0, "type": "TagDeclarator", @@ -1396,10 +1392,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 969, + "commentStart": 966, "end": 0, "name": { - "commentStart": 969, + "commentStart": 966, "end": 0, "name": "yLine", "start": 0, @@ -1409,7 +1405,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 969, + "commentStart": 966, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1421,23 +1417,23 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1032, + "commentStart": 1029, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1046, + "commentStart": 1043, "end": 0, "left": { "arguments": [ { "abs_path": false, - "commentStart": 1054, + "commentStart": 1051, "end": 0, "name": { - "commentStart": 1054, + "commentStart": 1051, "end": 0, "name": "seg02", "start": 0, @@ -1451,10 +1447,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1046, + "commentStart": 1043, "end": 0, "name": { - "commentStart": 1046, + "commentStart": 1043, "end": 0, "name": "segEndX", "start": 0, @@ -1464,7 +1460,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1046, + "commentStart": 1043, "end": 0, "start": 0, "type": "CallExpression", @@ -1472,7 +1468,7 @@ description: Result of parsing router-template-cross-bar.kcl }, "operator": "+", "right": { - "commentStart": 1063, + "commentStart": 1060, "end": 0, "raw": "0", "start": 0, @@ -1491,14 +1487,14 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1066, + "commentStart": 1063, "end": 0, "name": "tag", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1072, + "commentStart": 1069, "end": 0, "start": 0, "type": "TagDeclarator", @@ -1509,10 +1505,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1026, + "commentStart": 1023, "end": 0, "name": { - "commentStart": 1026, + "commentStart": 1023, "end": 0, "name": "xLine", "start": 0, @@ -1522,7 +1518,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1026, + "commentStart": 1023, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1534,23 +1530,23 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1091, + "commentStart": 1088, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1105, + "commentStart": 1102, "end": 0, "left": { "arguments": [ { "abs_path": false, - "commentStart": 1113, + "commentStart": 1110, "end": 0, "name": { - "commentStart": 1113, + "commentStart": 1110, "end": 0, "name": "seg01", "start": 0, @@ -1564,10 +1560,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1105, + "commentStart": 1102, "end": 0, "name": { - "commentStart": 1105, + "commentStart": 1102, "end": 0, "name": "segEndY", "start": 0, @@ -1577,7 +1573,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1105, + "commentStart": 1102, "end": 0, "start": 0, "type": "CallExpression", @@ -1586,10 +1582,10 @@ description: Result of parsing router-template-cross-bar.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 1122, + "commentStart": 1119, "end": 0, "name": { - "commentStart": 1122, + "commentStart": 1119, "end": 0, "name": "templateThickness", "start": 0, @@ -1608,14 +1604,14 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1141, + "commentStart": 1138, "end": 0, "name": "tag", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1147, + "commentStart": 1144, "end": 0, "start": 0, "type": "TagDeclarator", @@ -1626,10 +1622,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1085, + "commentStart": 1082, "end": 0, "name": { - "commentStart": 1085, + "commentStart": 1082, "end": 0, "name": "yLine", "start": 0, @@ -1639,7 +1635,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1085, + "commentStart": 1082, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1651,40 +1647,36 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1166, + "commentStart": 1163, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "abs_path": false, - "commentStart": 1180, + "commentStart": 1177, "end": 0, - "name": { - "commentStart": 1180, - "end": 0, - "name": "ZERO", - "start": 0, - "type": "Identifier" - }, - "path": [], + "raw": "0", "start": 0, - "type": "Name", - "type": "Name" + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } } }, { "type": "LabeledArg", "label": { - "commentStart": 1186, + "commentStart": 1180, "end": 0, "name": "tag", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1192, + "commentStart": 1186, "end": 0, "start": 0, "type": "TagDeclarator", @@ -1695,10 +1687,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1160, + "commentStart": 1157, "end": 0, "name": { - "commentStart": 1160, + "commentStart": 1157, "end": 0, "name": "xLine", "start": 0, @@ -1708,7 +1700,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1160, + "commentStart": 1157, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1720,7 +1712,7 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1211, + "commentStart": 1205, "end": 0, "name": "length", "start": 0, @@ -1731,10 +1723,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [ { "abs_path": false, - "commentStart": 1228, + "commentStart": 1222, "end": 0, "name": { - "commentStart": 1228, + "commentStart": 1222, "end": 0, "name": "seg04", "start": 0, @@ -1748,10 +1740,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1221, + "commentStart": 1215, "end": 0, "name": { - "commentStart": 1221, + "commentStart": 1215, "end": 0, "name": "segLen", "start": 0, @@ -1761,13 +1753,13 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1221, + "commentStart": 1215, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" }, - "commentStart": 1220, + "commentStart": 1214, "end": 0, "operator": "-", "start": 0, @@ -1778,10 +1770,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1205, + "commentStart": 1199, "end": 0, "name": { - "commentStart": 1205, + "commentStart": 1199, "end": 0, "name": "xLine", "start": 0, @@ -1791,7 +1783,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1205, + "commentStart": 1199, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1803,7 +1795,7 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1247, + "commentStart": 1241, "end": 0, "name": "length", "start": 0, @@ -1814,10 +1806,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [ { "abs_path": false, - "commentStart": 1264, + "commentStart": 1258, "end": 0, "name": { - "commentStart": 1264, + "commentStart": 1258, "end": 0, "name": "seg10", "start": 0, @@ -1831,10 +1823,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1257, + "commentStart": 1251, "end": 0, "name": { - "commentStart": 1257, + "commentStart": 1251, "end": 0, "name": "segLen", "start": 0, @@ -1844,13 +1836,13 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1257, + "commentStart": 1251, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" }, - "commentStart": 1256, + "commentStart": 1250, "end": 0, "operator": "-", "start": 0, @@ -1861,10 +1853,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1241, + "commentStart": 1235, "end": 0, "name": { - "commentStart": 1241, + "commentStart": 1235, "end": 0, "name": "yLine", "start": 0, @@ -1874,7 +1866,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1241, + "commentStart": 1235, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1886,7 +1878,7 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1283, + "commentStart": 1277, "end": 0, "name": "length", "start": 0, @@ -1897,10 +1889,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [ { "abs_path": false, - "commentStart": 1300, + "commentStart": 1294, "end": 0, "name": { - "commentStart": 1300, + "commentStart": 1294, "end": 0, "name": "seg05", "start": 0, @@ -1914,10 +1906,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1293, + "commentStart": 1287, "end": 0, "name": { - "commentStart": 1293, + "commentStart": 1287, "end": 0, "name": "segLen", "start": 0, @@ -1927,13 +1919,13 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1293, + "commentStart": 1287, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" }, - "commentStart": 1292, + "commentStart": 1286, "end": 0, "operator": "-", "start": 0, @@ -1944,10 +1936,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1277, + "commentStart": 1271, "end": 0, "name": { - "commentStart": 1277, + "commentStart": 1271, "end": 0, "name": "xLine", "start": 0, @@ -1957,7 +1949,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1277, + "commentStart": 1271, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1969,7 +1961,7 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1319, + "commentStart": 1313, "end": 0, "name": "length", "start": 0, @@ -1980,10 +1972,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [ { "abs_path": false, - "commentStart": 1336, + "commentStart": 1330, "end": 0, "name": { - "commentStart": 1336, + "commentStart": 1330, "end": 0, "name": "seg08", "start": 0, @@ -1997,10 +1989,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1329, + "commentStart": 1323, "end": 0, "name": { - "commentStart": 1329, + "commentStart": 1323, "end": 0, "name": "segLen", "start": 0, @@ -2010,13 +2002,13 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1329, + "commentStart": 1323, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" }, - "commentStart": 1328, + "commentStart": 1322, "end": 0, "operator": "-", "start": 0, @@ -2027,10 +2019,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1313, + "commentStart": 1307, "end": 0, "name": { - "commentStart": 1313, + "commentStart": 1307, "end": 0, "name": "yLine", "start": 0, @@ -2040,7 +2032,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1313, + "commentStart": 1307, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2052,7 +2044,7 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1355, + "commentStart": 1349, "end": 0, "name": "length", "start": 0, @@ -2062,10 +2054,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [ { "abs_path": false, - "commentStart": 1371, + "commentStart": 1365, "end": 0, "name": { - "commentStart": 1371, + "commentStart": 1365, "end": 0, "name": "seg06", "start": 0, @@ -2079,10 +2071,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1364, + "commentStart": 1358, "end": 0, "name": { - "commentStart": 1364, + "commentStart": 1358, "end": 0, "name": "segLen", "start": 0, @@ -2092,7 +2084,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1364, + "commentStart": 1358, "end": 0, "start": 0, "type": "CallExpression", @@ -2102,10 +2094,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1349, + "commentStart": 1343, "end": 0, "name": { - "commentStart": 1349, + "commentStart": 1343, "end": 0, "name": "xLine", "start": 0, @@ -2115,7 +2107,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1349, + "commentStart": 1343, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2127,7 +2119,7 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1390, + "commentStart": 1384, "end": 0, "name": "length", "start": 0, @@ -2138,10 +2130,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [ { "abs_path": false, - "commentStart": 1407, + "commentStart": 1401, "end": 0, "name": { - "commentStart": 1407, + "commentStart": 1401, "end": 0, "name": "seg02", "start": 0, @@ -2155,10 +2147,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1400, + "commentStart": 1394, "end": 0, "name": { - "commentStart": 1400, + "commentStart": 1394, "end": 0, "name": "segLen", "start": 0, @@ -2168,13 +2160,13 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1400, + "commentStart": 1394, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" }, - "commentStart": 1399, + "commentStart": 1393, "end": 0, "operator": "-", "start": 0, @@ -2185,10 +2177,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1384, + "commentStart": 1378, "end": 0, "name": { - "commentStart": 1384, + "commentStart": 1378, "end": 0, "name": "yLine", "start": 0, @@ -2198,7 +2190,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1384, + "commentStart": 1378, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2210,7 +2202,7 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1426, + "commentStart": 1420, "end": 0, "name": "length", "start": 0, @@ -2220,10 +2212,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [ { "abs_path": false, - "commentStart": 1442, + "commentStart": 1436, "end": 0, "name": { - "commentStart": 1442, + "commentStart": 1436, "end": 0, "name": "seg07", "start": 0, @@ -2237,10 +2229,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1435, + "commentStart": 1429, "end": 0, "name": { - "commentStart": 1435, + "commentStart": 1429, "end": 0, "name": "segLen", "start": 0, @@ -2250,7 +2242,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1435, + "commentStart": 1429, "end": 0, "start": 0, "type": "CallExpression", @@ -2260,10 +2252,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1420, + "commentStart": 1414, "end": 0, "name": { - "commentStart": 1420, + "commentStart": 1414, "end": 0, "name": "xLine", "start": 0, @@ -2273,7 +2265,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1420, + "commentStart": 1414, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2285,7 +2277,7 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1461, + "commentStart": 1455, "end": 0, "name": "length", "start": 0, @@ -2295,10 +2287,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [ { "abs_path": false, - "commentStart": 1477, + "commentStart": 1471, "end": 0, "name": { - "commentStart": 1477, + "commentStart": 1471, "end": 0, "name": "seg03", "start": 0, @@ -2312,10 +2304,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1470, + "commentStart": 1464, "end": 0, "name": { - "commentStart": 1470, + "commentStart": 1464, "end": 0, "name": "segLen", "start": 0, @@ -2325,7 +2317,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1470, + "commentStart": 1464, "end": 0, "start": 0, "type": "CallExpression", @@ -2335,10 +2327,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1455, + "commentStart": 1449, "end": 0, "name": { - "commentStart": 1455, + "commentStart": 1449, "end": 0, "name": "yLine", "start": 0, @@ -2348,7 +2340,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1455, + "commentStart": 1449, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2358,14 +2350,14 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 1494, + "commentStart": 1488, "end": 0, "properties": [ { - "commentStart": 1503, + "commentStart": 1497, "end": 0, "key": { - "commentStart": 1503, + "commentStart": 1497, "end": 0, "name": "angleEnd", "start": 0, @@ -2374,7 +2366,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 1514, + "commentStart": 1508, "end": 0, "raw": "90", "start": 0, @@ -2387,10 +2379,10 @@ description: Result of parsing router-template-cross-bar.kcl } }, { - "commentStart": 1525, + "commentStart": 1519, "end": 0, "key": { - "commentStart": 1525, + "commentStart": 1519, "end": 0, "name": "angleStart", "start": 0, @@ -2399,7 +2391,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 1538, + "commentStart": 1532, "end": 0, "raw": "180", "start": 0, @@ -2412,10 +2404,10 @@ description: Result of parsing router-template-cross-bar.kcl } }, { - "commentStart": 1550, + "commentStart": 1544, "end": 0, "key": { - "commentStart": 1550, + "commentStart": 1544, "end": 0, "name": "radius", "start": 0, @@ -2424,10 +2416,10 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 1559, + "commentStart": 1553, "end": 0, "left": { - "commentStart": 1559, + "commentStart": 1553, "end": 0, "raw": "10", "start": 0, @@ -2441,10 +2433,10 @@ description: Result of parsing router-template-cross-bar.kcl "operator": "+", "right": { "abs_path": false, - "commentStart": 1564, + "commentStart": 1558, "end": 0, "name": { - "commentStart": 1564, + "commentStart": 1558, "end": 0, "name": "templateGap", "start": 0, @@ -2466,7 +2458,7 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ObjectExpression" }, { - "commentStart": 1584, + "commentStart": 1578, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2475,10 +2467,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1490, + "commentStart": 1484, "end": 0, "name": { - "commentStart": 1490, + "commentStart": 1484, "end": 0, "name": "arc", "start": 0, @@ -2488,7 +2480,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1490, + "commentStart": 1484, "end": 0, "start": 0, "type": "CallExpression", @@ -2499,19 +2491,19 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1597, + "commentStart": 1591, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1611, + "commentStart": 1605, "elements": [ { "arguments": [ { - "commentStart": 1626, + "commentStart": 1620, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2520,10 +2512,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1612, + "commentStart": 1606, "end": 0, "name": { - "commentStart": 1612, + "commentStart": 1606, "end": 0, "name": "profileStartX", "start": 0, @@ -2533,7 +2525,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1612, + "commentStart": 1606, "end": 0, "start": 0, "type": "CallExpression", @@ -2542,7 +2534,7 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 1644, + "commentStart": 1638, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2551,10 +2543,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1630, + "commentStart": 1624, "end": 0, "name": { - "commentStart": 1630, + "commentStart": 1624, "end": 0, "name": "profileStartY", "start": 0, @@ -2564,7 +2556,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1630, + "commentStart": 1624, "end": 0, "start": 0, "type": "CallExpression", @@ -2580,10 +2572,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1592, + "commentStart": 1586, "end": 0, "name": { - "commentStart": 1592, + "commentStart": 1586, "end": 0, "name": "line", "start": 0, @@ -2593,7 +2585,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1592, + "commentStart": 1586, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2604,10 +2596,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 1654, + "commentStart": 1648, "end": 0, "name": { - "commentStart": 1654, + "commentStart": 1648, "end": 0, "name": "close", "start": 0, @@ -2617,7 +2609,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1654, + "commentStart": 1648, "end": 0, "start": 0, "type": "CallExpression", @@ -2640,12 +2632,12 @@ description: Result of parsing router-template-cross-bar.kcl "type": "VariableDeclaration" }, { - "commentStart": 1662, + "commentStart": 1656, "declaration": { - "commentStart": 1662, + "commentStart": 1656, "end": 0, "id": { - "commentStart": 1662, + "commentStart": 1656, "end": 0, "name": "extrude001", "start": 0, @@ -2656,14 +2648,14 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 1694, + "commentStart": 1688, "end": 0, "name": "length", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1703, + "commentStart": 1697, "end": 0, "raw": "5", "start": 0, @@ -2678,10 +2670,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1675, + "commentStart": 1669, "end": 0, "name": { - "commentStart": 1675, + "commentStart": 1669, "end": 0, "name": "extrude", "start": 0, @@ -2691,17 +2683,17 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1675, + "commentStart": 1669, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 1683, + "commentStart": 1677, "end": 0, "name": { - "commentStart": 1683, + "commentStart": 1677, "end": 0, "name": "sketch001", "start": 0, @@ -2723,12 +2715,12 @@ description: Result of parsing router-template-cross-bar.kcl "type": "VariableDeclaration" }, { - "commentStart": 1705, + "commentStart": 1699, "declaration": { - "commentStart": 1707, + "commentStart": 1701, "end": 0, "id": { - "commentStart": 1707, + "commentStart": 1701, "end": 0, "name": "sketch003", "start": 0, @@ -2740,10 +2732,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [ { "abs_path": false, - "commentStart": 1733, + "commentStart": 1727, "end": 0, "name": { - "commentStart": 1733, + "commentStart": 1727, "end": 0, "name": "extrude001", "start": 0, @@ -2755,7 +2747,7 @@ description: Result of parsing router-template-cross-bar.kcl "type": "Name" }, { - "commentStart": 1745, + "commentStart": 1739, "end": 0, "raw": "'START'", "start": 0, @@ -2766,10 +2758,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1719, + "commentStart": 1713, "end": 0, "name": { - "commentStart": 1719, + "commentStart": 1713, "end": 0, "name": "startSketchOn", "start": 0, @@ -2779,7 +2771,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1719, + "commentStart": 1713, "end": 0, "start": 0, "type": "CallExpression", @@ -2788,14 +2780,14 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 1774, + "commentStart": 1768, "elements": [ { "abs_path": false, - "commentStart": 1775, + "commentStart": 1769, "end": 0, "name": { - "commentStart": 1775, + "commentStart": 1769, "end": 0, "name": "distanceToInsideEdge", "start": 0, @@ -2807,7 +2799,7 @@ description: Result of parsing router-template-cross-bar.kcl "type": "Name" }, { - "commentStart": 1797, + "commentStart": 1791, "end": 0, "raw": "0", "start": 0, @@ -2825,7 +2817,7 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ArrayExpression" }, { - "commentStart": 1801, + "commentStart": 1795, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2834,10 +2826,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1759, + "commentStart": 1753, "end": 0, "name": { - "commentStart": 1759, + "commentStart": 1753, "end": 0, "name": "startProfileAt", "start": 0, @@ -2847,7 +2839,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1759, + "commentStart": 1753, "end": 0, "start": 0, "type": "CallExpression", @@ -2856,10 +2848,10 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 1820, + "commentStart": 1814, "elements": [ { - "commentStart": 1821, + "commentStart": 1815, "end": 0, "raw": "180", "start": 0, @@ -2872,10 +2864,10 @@ description: Result of parsing router-template-cross-bar.kcl }, { "abs_path": false, - "commentStart": 1826, + "commentStart": 1820, "end": 0, "name": { - "commentStart": 1826, + "commentStart": 1820, "end": 0, "name": "templateThickness", "start": 0, @@ -2893,14 +2885,14 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ArrayExpression" }, { - "commentStart": 1846, + "commentStart": 1840, "end": 0, "start": 0, "type": "PipeSubstitution", "type": "PipeSubstitution" }, { - "commentStart": 1849, + "commentStart": 1843, "end": 0, "start": 0, "type": "TagDeclarator", @@ -2910,10 +2902,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1809, + "commentStart": 1803, "end": 0, "name": { - "commentStart": 1809, + "commentStart": 1803, "end": 0, "name": "angledLine", "start": 0, @@ -2923,7 +2915,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1809, + "commentStart": 1803, "end": 0, "start": 0, "type": "CallExpression", @@ -2932,19 +2924,19 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 1888, + "commentStart": 1882, "elements": [ { - "commentStart": 1897, + "commentStart": 1891, "end": 0, "left": { "arguments": [ { "abs_path": false, - "commentStart": 1904, + "commentStart": 1898, "end": 0, "name": { - "commentStart": 1904, + "commentStart": 1898, "end": 0, "name": "rectangleSegmentA002", "start": 0, @@ -2958,10 +2950,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1897, + "commentStart": 1891, "end": 0, "name": { - "commentStart": 1897, + "commentStart": 1891, "end": 0, "name": "segAng", "start": 0, @@ -2971,7 +2963,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1897, + "commentStart": 1891, "end": 0, "start": 0, "type": "CallExpression", @@ -2979,7 +2971,7 @@ description: Result of parsing router-template-cross-bar.kcl }, "operator": "+", "right": { - "commentStart": 1928, + "commentStart": 1922, "end": 0, "raw": "90", "start": 0, @@ -2996,10 +2988,10 @@ description: Result of parsing router-template-cross-bar.kcl }, { "abs_path": false, - "commentStart": 1939, + "commentStart": 1933, "end": 0, "name": { - "commentStart": 1939, + "commentStart": 1933, "end": 0, "name": "templateThickness", "start": 0, @@ -3017,14 +3009,14 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ArrayExpression" }, { - "commentStart": 1965, + "commentStart": 1959, "end": 0, "start": 0, "type": "PipeSubstitution", "type": "PipeSubstitution" }, { - "commentStart": 1968, + "commentStart": 1962, "end": 0, "start": 0, "type": "TagDeclarator", @@ -3034,10 +3026,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1877, + "commentStart": 1871, "end": 0, "name": { - "commentStart": 1877, + "commentStart": 1871, "end": 0, "name": "angledLine", "start": 0, @@ -3047,7 +3039,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1877, + "commentStart": 1871, "end": 0, "start": 0, "type": "CallExpression", @@ -3056,16 +3048,16 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 2007, + "commentStart": 2001, "elements": [ { "arguments": [ { "abs_path": false, - "commentStart": 2023, + "commentStart": 2017, "end": 0, "name": { - "commentStart": 2023, + "commentStart": 2017, "end": 0, "name": "rectangleSegmentA002", "start": 0, @@ -3079,10 +3071,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2016, + "commentStart": 2010, "end": 0, "name": { - "commentStart": 2016, + "commentStart": 2010, "end": 0, "name": "segAng", "start": 0, @@ -3092,7 +3084,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2016, + "commentStart": 2010, "end": 0, "start": 0, "type": "CallExpression", @@ -3103,10 +3095,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [ { "abs_path": false, - "commentStart": 2061, + "commentStart": 2055, "end": 0, "name": { - "commentStart": 2061, + "commentStart": 2055, "end": 0, "name": "rectangleSegmentA002", "start": 0, @@ -3120,10 +3112,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2054, + "commentStart": 2048, "end": 0, "name": { - "commentStart": 2054, + "commentStart": 2048, "end": 0, "name": "segLen", "start": 0, @@ -3133,13 +3125,13 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2054, + "commentStart": 2048, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" }, - "commentStart": 2053, + "commentStart": 2047, "end": 0, "operator": "-", "start": 0, @@ -3153,14 +3145,14 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ArrayExpression" }, { - "commentStart": 2091, + "commentStart": 2085, "end": 0, "start": 0, "type": "PipeSubstitution", "type": "PipeSubstitution" }, { - "commentStart": 2094, + "commentStart": 2088, "end": 0, "start": 0, "type": "TagDeclarator", @@ -3170,10 +3162,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 1996, + "commentStart": 1990, "end": 0, "name": { - "commentStart": 1996, + "commentStart": 1990, "end": 0, "name": "angledLine", "start": 0, @@ -3183,7 +3175,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 1996, + "commentStart": 1990, "end": 0, "start": 0, "type": "CallExpression", @@ -3194,19 +3186,19 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 2127, + "commentStart": 2121, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2141, + "commentStart": 2135, "elements": [ { "arguments": [ { - "commentStart": 2156, + "commentStart": 2150, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3215,10 +3207,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2142, + "commentStart": 2136, "end": 0, "name": { - "commentStart": 2142, + "commentStart": 2136, "end": 0, "name": "profileStartX", "start": 0, @@ -3228,7 +3220,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2142, + "commentStart": 2136, "end": 0, "start": 0, "type": "CallExpression", @@ -3237,7 +3229,7 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 2174, + "commentStart": 2168, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3246,10 +3238,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2160, + "commentStart": 2154, "end": 0, "name": { - "commentStart": 2160, + "commentStart": 2154, "end": 0, "name": "profileStartY", "start": 0, @@ -3259,7 +3251,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2160, + "commentStart": 2154, "end": 0, "start": 0, "type": "CallExpression", @@ -3275,10 +3267,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2122, + "commentStart": 2116, "end": 0, "name": { - "commentStart": 2122, + "commentStart": 2116, "end": 0, "name": "line", "start": 0, @@ -3288,7 +3280,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2122, + "commentStart": 2116, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -3299,10 +3291,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 2184, + "commentStart": 2178, "end": 0, "name": { - "commentStart": 2184, + "commentStart": 2178, "end": 0, "name": "close", "start": 0, @@ -3312,14 +3304,14 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2184, + "commentStart": 2178, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" } ], - "commentStart": 1719, + "commentStart": 1713, "end": 0, "start": 0, "type": "PipeExpression", @@ -3335,12 +3327,12 @@ description: Result of parsing router-template-cross-bar.kcl "type": "VariableDeclaration" }, { - "commentStart": 2192, + "commentStart": 2186, "declaration": { - "commentStart": 2192, + "commentStart": 2186, "end": 0, "id": { - "commentStart": 2192, + "commentStart": 2186, "end": 0, "name": "extrude003", "start": 0, @@ -3351,14 +3343,14 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 2224, + "commentStart": 2218, "end": 0, "name": "length", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2233, + "commentStart": 2227, "end": 0, "raw": "13", "start": 0, @@ -3373,10 +3365,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2205, + "commentStart": 2199, "end": 0, "name": { - "commentStart": 2205, + "commentStart": 2199, "end": 0, "name": "extrude", "start": 0, @@ -3386,17 +3378,17 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2205, + "commentStart": 2199, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 2213, + "commentStart": 2207, "end": 0, "name": { - "commentStart": 2213, + "commentStart": 2207, "end": 0, "name": "sketch003", "start": 0, @@ -3418,12 +3410,12 @@ description: Result of parsing router-template-cross-bar.kcl "type": "VariableDeclaration" }, { - "commentStart": 2236, + "commentStart": 2230, "declaration": { - "commentStart": 2238, + "commentStart": 2232, "end": 0, "id": { - "commentStart": 2238, + "commentStart": 2232, "end": 0, "name": "sketch002", "start": 0, @@ -3435,10 +3427,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [ { "abs_path": false, - "commentStart": 2264, + "commentStart": 2258, "end": 0, "name": { - "commentStart": 2264, + "commentStart": 2258, "end": 0, "name": "extrude001", "start": 0, @@ -3450,7 +3442,7 @@ description: Result of parsing router-template-cross-bar.kcl "type": "Name" }, { - "commentStart": 2276, + "commentStart": 2270, "end": 0, "raw": "'START'", "start": 0, @@ -3461,10 +3453,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2250, + "commentStart": 2244, "end": 0, "name": { - "commentStart": 2250, + "commentStart": 2244, "end": 0, "name": "startSketchOn", "start": 0, @@ -3474,7 +3466,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2250, + "commentStart": 2244, "end": 0, "start": 0, "type": "CallExpression", @@ -3483,15 +3475,15 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 2305, + "commentStart": 2299, "elements": [ { "argument": { "abs_path": false, - "commentStart": 2307, + "commentStart": 2301, "end": 0, "name": { - "commentStart": 2307, + "commentStart": 2301, "end": 0, "name": "distanceToInsideEdge", "start": 0, @@ -3502,7 +3494,7 @@ description: Result of parsing router-template-cross-bar.kcl "type": "Name", "type": "Name" }, - "commentStart": 2306, + "commentStart": 2300, "end": 0, "operator": "-", "start": 0, @@ -3510,7 +3502,7 @@ description: Result of parsing router-template-cross-bar.kcl "type": "UnaryExpression" }, { - "commentStart": 2329, + "commentStart": 2323, "end": 0, "raw": "0", "start": 0, @@ -3528,7 +3520,7 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ArrayExpression" }, { - "commentStart": 2333, + "commentStart": 2327, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3537,10 +3529,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2290, + "commentStart": 2284, "end": 0, "name": { - "commentStart": 2290, + "commentStart": 2284, "end": 0, "name": "startProfileAt", "start": 0, @@ -3550,7 +3542,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2290, + "commentStart": 2284, "end": 0, "start": 0, "type": "CallExpression", @@ -3559,10 +3551,10 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 2352, + "commentStart": 2346, "elements": [ { - "commentStart": 2353, + "commentStart": 2347, "end": 0, "raw": "0", "start": 0, @@ -3575,10 +3567,10 @@ description: Result of parsing router-template-cross-bar.kcl }, { "abs_path": false, - "commentStart": 2356, + "commentStart": 2350, "end": 0, "name": { - "commentStart": 2356, + "commentStart": 2350, "end": 0, "name": "templateThickness", "start": 0, @@ -3596,14 +3588,14 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ArrayExpression" }, { - "commentStart": 2376, + "commentStart": 2370, "end": 0, "start": 0, "type": "PipeSubstitution", "type": "PipeSubstitution" }, { - "commentStart": 2379, + "commentStart": 2373, "end": 0, "start": 0, "type": "TagDeclarator", @@ -3613,10 +3605,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2341, + "commentStart": 2335, "end": 0, "name": { - "commentStart": 2341, + "commentStart": 2335, "end": 0, "name": "angledLine", "start": 0, @@ -3626,7 +3618,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2341, + "commentStart": 2335, "end": 0, "start": 0, "type": "CallExpression", @@ -3635,19 +3627,19 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 2418, + "commentStart": 2412, "elements": [ { - "commentStart": 2427, + "commentStart": 2421, "end": 0, "left": { "arguments": [ { "abs_path": false, - "commentStart": 2434, + "commentStart": 2428, "end": 0, "name": { - "commentStart": 2434, + "commentStart": 2428, "end": 0, "name": "rectangleSegmentA001", "start": 0, @@ -3661,10 +3653,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2427, + "commentStart": 2421, "end": 0, "name": { - "commentStart": 2427, + "commentStart": 2421, "end": 0, "name": "segAng", "start": 0, @@ -3674,7 +3666,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2427, + "commentStart": 2421, "end": 0, "start": 0, "type": "CallExpression", @@ -3682,7 +3674,7 @@ description: Result of parsing router-template-cross-bar.kcl }, "operator": "-", "right": { - "commentStart": 2458, + "commentStart": 2452, "end": 0, "raw": "90", "start": 0, @@ -3699,10 +3691,10 @@ description: Result of parsing router-template-cross-bar.kcl }, { "abs_path": false, - "commentStart": 2469, + "commentStart": 2463, "end": 0, "name": { - "commentStart": 2469, + "commentStart": 2463, "end": 0, "name": "templateThickness", "start": 0, @@ -3720,14 +3712,14 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ArrayExpression" }, { - "commentStart": 2495, + "commentStart": 2489, "end": 0, "start": 0, "type": "PipeSubstitution", "type": "PipeSubstitution" }, { - "commentStart": 2498, + "commentStart": 2492, "end": 0, "start": 0, "type": "TagDeclarator", @@ -3737,10 +3729,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2407, + "commentStart": 2401, "end": 0, "name": { - "commentStart": 2407, + "commentStart": 2401, "end": 0, "name": "angledLine", "start": 0, @@ -3750,7 +3742,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2407, + "commentStart": 2401, "end": 0, "start": 0, "type": "CallExpression", @@ -3759,16 +3751,16 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 2537, + "commentStart": 2531, "elements": [ { "arguments": [ { "abs_path": false, - "commentStart": 2553, + "commentStart": 2547, "end": 0, "name": { - "commentStart": 2553, + "commentStart": 2547, "end": 0, "name": "rectangleSegmentA001", "start": 0, @@ -3782,10 +3774,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2546, + "commentStart": 2540, "end": 0, "name": { - "commentStart": 2546, + "commentStart": 2540, "end": 0, "name": "segAng", "start": 0, @@ -3795,7 +3787,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2546, + "commentStart": 2540, "end": 0, "start": 0, "type": "CallExpression", @@ -3806,10 +3798,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [ { "abs_path": false, - "commentStart": 2591, + "commentStart": 2585, "end": 0, "name": { - "commentStart": 2591, + "commentStart": 2585, "end": 0, "name": "rectangleSegmentA001", "start": 0, @@ -3823,10 +3815,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2584, + "commentStart": 2578, "end": 0, "name": { - "commentStart": 2584, + "commentStart": 2578, "end": 0, "name": "segLen", "start": 0, @@ -3836,13 +3828,13 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2584, + "commentStart": 2578, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" }, - "commentStart": 2583, + "commentStart": 2577, "end": 0, "operator": "-", "start": 0, @@ -3856,14 +3848,14 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ArrayExpression" }, { - "commentStart": 2621, + "commentStart": 2615, "end": 0, "start": 0, "type": "PipeSubstitution", "type": "PipeSubstitution" }, { - "commentStart": 2624, + "commentStart": 2618, "end": 0, "start": 0, "type": "TagDeclarator", @@ -3873,10 +3865,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2526, + "commentStart": 2520, "end": 0, "name": { - "commentStart": 2526, + "commentStart": 2520, "end": 0, "name": "angledLine", "start": 0, @@ -3886,7 +3878,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2526, + "commentStart": 2520, "end": 0, "start": 0, "type": "CallExpression", @@ -3897,19 +3889,19 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 2657, + "commentStart": 2651, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2671, + "commentStart": 2665, "elements": [ { "arguments": [ { - "commentStart": 2686, + "commentStart": 2680, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3918,10 +3910,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2672, + "commentStart": 2666, "end": 0, "name": { - "commentStart": 2672, + "commentStart": 2666, "end": 0, "name": "profileStartX", "start": 0, @@ -3931,7 +3923,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2672, + "commentStart": 2666, "end": 0, "start": 0, "type": "CallExpression", @@ -3940,7 +3932,7 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 2704, + "commentStart": 2698, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3949,10 +3941,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2690, + "commentStart": 2684, "end": 0, "name": { - "commentStart": 2690, + "commentStart": 2684, "end": 0, "name": "profileStartY", "start": 0, @@ -3962,7 +3954,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2690, + "commentStart": 2684, "end": 0, "start": 0, "type": "CallExpression", @@ -3978,10 +3970,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2652, + "commentStart": 2646, "end": 0, "name": { - "commentStart": 2652, + "commentStart": 2646, "end": 0, "name": "line", "start": 0, @@ -3991,7 +3983,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2652, + "commentStart": 2646, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -4002,10 +3994,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 2714, + "commentStart": 2708, "end": 0, "name": { - "commentStart": 2714, + "commentStart": 2708, "end": 0, "name": "close", "start": 0, @@ -4015,14 +4007,14 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2714, + "commentStart": 2708, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" } ], - "commentStart": 2250, + "commentStart": 2244, "end": 0, "start": 0, "type": "PipeExpression", @@ -4038,12 +4030,12 @@ description: Result of parsing router-template-cross-bar.kcl "type": "VariableDeclaration" }, { - "commentStart": 2721, + "commentStart": 2715, "declaration": { - "commentStart": 2723, + "commentStart": 2717, "end": 0, "id": { - "commentStart": 2723, + "commentStart": 2717, "end": 0, "name": "extrude002", "start": 0, @@ -4054,14 +4046,14 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 2755, + "commentStart": 2749, "end": 0, "name": "length", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2764, + "commentStart": 2758, "end": 0, "raw": "13", "start": 0, @@ -4076,10 +4068,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2736, + "commentStart": 2730, "end": 0, "name": { - "commentStart": 2736, + "commentStart": 2730, "end": 0, "name": "extrude", "start": 0, @@ -4089,17 +4081,17 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2736, + "commentStart": 2730, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 2744, + "commentStart": 2738, "end": 0, "name": { - "commentStart": 2744, + "commentStart": 2738, "end": 0, "name": "sketch002", "start": 0, @@ -4121,12 +4113,12 @@ description: Result of parsing router-template-cross-bar.kcl "type": "VariableDeclaration" }, { - "commentStart": 2767, + "commentStart": 2761, "declaration": { - "commentStart": 2769, + "commentStart": 2763, "end": 0, "id": { - "commentStart": 2769, + "commentStart": 2763, "end": 0, "name": "sketch004", "start": 0, @@ -4138,10 +4130,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [ { "abs_path": false, - "commentStart": 2795, + "commentStart": 2789, "end": 0, "name": { - "commentStart": 2795, + "commentStart": 2789, "end": 0, "name": "extrude002", "start": 0, @@ -4153,7 +4145,7 @@ description: Result of parsing router-template-cross-bar.kcl "type": "Name" }, { - "commentStart": 2807, + "commentStart": 2801, "end": 0, "raw": "'END'", "start": 0, @@ -4164,10 +4156,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2781, + "commentStart": 2775, "end": 0, "name": { - "commentStart": 2781, + "commentStart": 2775, "end": 0, "name": "startSketchOn", "start": 0, @@ -4177,7 +4169,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2781, + "commentStart": 2775, "end": 0, "start": 0, "type": "CallExpression", @@ -4186,15 +4178,15 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 2834, + "commentStart": 2828, "elements": [ { "argument": { "abs_path": false, - "commentStart": 2836, + "commentStart": 2830, "end": 0, "name": { - "commentStart": 2836, + "commentStart": 2830, "end": 0, "name": "distanceToInsideEdge", "start": 0, @@ -4205,7 +4197,7 @@ description: Result of parsing router-template-cross-bar.kcl "type": "Name", "type": "Name" }, - "commentStart": 2835, + "commentStart": 2829, "end": 0, "operator": "-", "start": 0, @@ -4213,7 +4205,7 @@ description: Result of parsing router-template-cross-bar.kcl "type": "UnaryExpression" }, { - "commentStart": 2858, + "commentStart": 2852, "end": 0, "raw": "0", "start": 0, @@ -4231,7 +4223,7 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ArrayExpression" }, { - "commentStart": 2862, + "commentStart": 2856, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -4240,10 +4232,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2819, + "commentStart": 2813, "end": 0, "name": { - "commentStart": 2819, + "commentStart": 2813, "end": 0, "name": "startProfileAt", "start": 0, @@ -4253,7 +4245,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2819, + "commentStart": 2813, "end": 0, "start": 0, "type": "CallExpression", @@ -4262,10 +4254,10 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 2881, + "commentStart": 2875, "elements": [ { - "commentStart": 2882, + "commentStart": 2876, "end": 0, "raw": "0", "start": 0, @@ -4277,14 +4269,14 @@ description: Result of parsing router-template-cross-bar.kcl } }, { - "commentStart": 2885, + "commentStart": 2879, "end": 0, "left": { "abs_path": false, - "commentStart": 2885, + "commentStart": 2879, "end": 0, "name": { - "commentStart": 2885, + "commentStart": 2879, "end": 0, "name": "distanceToInsideEdge", "start": 0, @@ -4297,7 +4289,7 @@ description: Result of parsing router-template-cross-bar.kcl }, "operator": "*", "right": { - "commentStart": 2908, + "commentStart": 2902, "end": 0, "raw": "2", "start": 0, @@ -4319,14 +4311,14 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ArrayExpression" }, { - "commentStart": 2912, + "commentStart": 2906, "end": 0, "start": 0, "type": "PipeSubstitution", "type": "PipeSubstitution" }, { - "commentStart": 2915, + "commentStart": 2909, "end": 0, "start": 0, "type": "TagDeclarator", @@ -4336,10 +4328,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2870, + "commentStart": 2864, "end": 0, "name": { - "commentStart": 2870, + "commentStart": 2864, "end": 0, "name": "angledLine", "start": 0, @@ -4349,7 +4341,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2870, + "commentStart": 2864, "end": 0, "start": 0, "type": "CallExpression", @@ -4358,19 +4350,19 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 2954, + "commentStart": 2948, "elements": [ { - "commentStart": 2963, + "commentStart": 2957, "end": 0, "left": { "arguments": [ { "abs_path": false, - "commentStart": 2970, + "commentStart": 2964, "end": 0, "name": { - "commentStart": 2970, + "commentStart": 2964, "end": 0, "name": "rectangleSegmentA003", "start": 0, @@ -4384,10 +4376,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2963, + "commentStart": 2957, "end": 0, "name": { - "commentStart": 2963, + "commentStart": 2957, "end": 0, "name": "segAng", "start": 0, @@ -4397,7 +4389,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2963, + "commentStart": 2957, "end": 0, "start": 0, "type": "CallExpression", @@ -4405,7 +4397,7 @@ description: Result of parsing router-template-cross-bar.kcl }, "operator": "-", "right": { - "commentStart": 2994, + "commentStart": 2988, "end": 0, "raw": "90", "start": 0, @@ -4422,10 +4414,10 @@ description: Result of parsing router-template-cross-bar.kcl }, { "abs_path": false, - "commentStart": 3005, + "commentStart": 2999, "end": 0, "name": { - "commentStart": 3005, + "commentStart": 2999, "end": 0, "name": "templateThickness", "start": 0, @@ -4443,14 +4435,14 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ArrayExpression" }, { - "commentStart": 3031, + "commentStart": 3025, "end": 0, "start": 0, "type": "PipeSubstitution", "type": "PipeSubstitution" }, { - "commentStart": 3034, + "commentStart": 3028, "end": 0, "start": 0, "type": "TagDeclarator", @@ -4460,10 +4452,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 2943, + "commentStart": 2937, "end": 0, "name": { - "commentStart": 2943, + "commentStart": 2937, "end": 0, "name": "angledLine", "start": 0, @@ -4473,7 +4465,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 2943, + "commentStart": 2937, "end": 0, "start": 0, "type": "CallExpression", @@ -4482,16 +4474,16 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 3073, + "commentStart": 3067, "elements": [ { "arguments": [ { "abs_path": false, - "commentStart": 3089, + "commentStart": 3083, "end": 0, "name": { - "commentStart": 3089, + "commentStart": 3083, "end": 0, "name": "rectangleSegmentA003", "start": 0, @@ -4505,10 +4497,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 3082, + "commentStart": 3076, "end": 0, "name": { - "commentStart": 3082, + "commentStart": 3076, "end": 0, "name": "segAng", "start": 0, @@ -4518,7 +4510,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 3082, + "commentStart": 3076, "end": 0, "start": 0, "type": "CallExpression", @@ -4529,10 +4521,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [ { "abs_path": false, - "commentStart": 3127, + "commentStart": 3121, "end": 0, "name": { - "commentStart": 3127, + "commentStart": 3121, "end": 0, "name": "rectangleSegmentA003", "start": 0, @@ -4546,10 +4538,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 3120, + "commentStart": 3114, "end": 0, "name": { - "commentStart": 3120, + "commentStart": 3114, "end": 0, "name": "segLen", "start": 0, @@ -4559,13 +4551,13 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 3120, + "commentStart": 3114, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" }, - "commentStart": 3119, + "commentStart": 3113, "end": 0, "operator": "-", "start": 0, @@ -4579,14 +4571,14 @@ description: Result of parsing router-template-cross-bar.kcl "type": "ArrayExpression" }, { - "commentStart": 3157, + "commentStart": 3151, "end": 0, "start": 0, "type": "PipeSubstitution", "type": "PipeSubstitution" }, { - "commentStart": 3160, + "commentStart": 3154, "end": 0, "start": 0, "type": "TagDeclarator", @@ -4596,10 +4588,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 3062, + "commentStart": 3056, "end": 0, "name": { - "commentStart": 3062, + "commentStart": 3056, "end": 0, "name": "angledLine", "start": 0, @@ -4609,7 +4601,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 3062, + "commentStart": 3056, "end": 0, "start": 0, "type": "CallExpression", @@ -4620,19 +4612,19 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 3193, + "commentStart": 3187, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 3207, + "commentStart": 3201, "elements": [ { "arguments": [ { - "commentStart": 3222, + "commentStart": 3216, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -4641,10 +4633,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 3208, + "commentStart": 3202, "end": 0, "name": { - "commentStart": 3208, + "commentStart": 3202, "end": 0, "name": "profileStartX", "start": 0, @@ -4654,7 +4646,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 3208, + "commentStart": 3202, "end": 0, "start": 0, "type": "CallExpression", @@ -4663,7 +4655,7 @@ description: Result of parsing router-template-cross-bar.kcl { "arguments": [ { - "commentStart": 3240, + "commentStart": 3234, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -4672,10 +4664,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 3226, + "commentStart": 3220, "end": 0, "name": { - "commentStart": 3226, + "commentStart": 3220, "end": 0, "name": "profileStartY", "start": 0, @@ -4685,7 +4677,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 3226, + "commentStart": 3220, "end": 0, "start": 0, "type": "CallExpression", @@ -4701,10 +4693,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 3188, + "commentStart": 3182, "end": 0, "name": { - "commentStart": 3188, + "commentStart": 3182, "end": 0, "name": "line", "start": 0, @@ -4714,7 +4706,7 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 3188, + "commentStart": 3182, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -4725,10 +4717,10 @@ description: Result of parsing router-template-cross-bar.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 3250, + "commentStart": 3244, "end": 0, "name": { - "commentStart": 3250, + "commentStart": 3244, "end": 0, "name": "close", "start": 0, @@ -4738,14 +4730,14 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 3250, + "commentStart": 3244, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" } ], - "commentStart": 2781, + "commentStart": 2775, "end": 0, "start": 0, "type": "PipeExpression", @@ -4761,12 +4753,12 @@ description: Result of parsing router-template-cross-bar.kcl "type": "VariableDeclaration" }, { - "commentStart": 3258, + "commentStart": 3252, "declaration": { - "commentStart": 3258, + "commentStart": 3252, "end": 0, "id": { - "commentStart": 3258, + "commentStart": 3252, "end": 0, "name": "extrude004", "start": 0, @@ -4777,14 +4769,14 @@ description: Result of parsing router-template-cross-bar.kcl { "type": "LabeledArg", "label": { - "commentStart": 3290, + "commentStart": 3284, "end": 0, "name": "length", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 3299, + "commentStart": 3293, "end": 0, "raw": "4", "start": 0, @@ -4799,10 +4791,10 @@ description: Result of parsing router-template-cross-bar.kcl ], "callee": { "abs_path": false, - "commentStart": 3271, + "commentStart": 3265, "end": 0, "name": { - "commentStart": 3271, + "commentStart": 3265, "end": 0, "name": "extrude", "start": 0, @@ -4812,17 +4804,17 @@ description: Result of parsing router-template-cross-bar.kcl "start": 0, "type": "Name" }, - "commentStart": 3271, + "commentStart": 3265, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 3279, + "commentStart": 3273, "end": 0, "name": { - "commentStart": 3279, + "commentStart": 3273, "end": 0, "name": "sketch004", "start": 0, @@ -4903,7 +4895,7 @@ description: Result of parsing router-template-cross-bar.kcl "nonCodeNodes": { "10": [ { - "commentStart": 1705, + "commentStart": 1699, "end": 0, "start": 0, "type": "NonCodeNode", @@ -4914,7 +4906,7 @@ description: Result of parsing router-template-cross-bar.kcl ], "12": [ { - "commentStart": 2236, + "commentStart": 2230, "end": 0, "start": 0, "type": "NonCodeNode", @@ -4925,7 +4917,7 @@ description: Result of parsing router-template-cross-bar.kcl ], "13": [ { - "commentStart": 2721, + "commentStart": 2715, "end": 0, "start": 0, "type": "NonCodeNode", @@ -4936,7 +4928,7 @@ description: Result of parsing router-template-cross-bar.kcl ], "14": [ { - "commentStart": 2767, + "commentStart": 2761, "end": 0, "start": 0, "type": "NonCodeNode", diff --git a/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/program_memory.snap index bcb135c7e..969d993ad 100644 --- a/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/router-template-cross-bar/program_memory.snap @@ -35,9 +35,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -48,9 +48,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -61,9 +61,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -74,9 +74,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -87,9 +87,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -100,9 +100,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -113,9 +113,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -126,9 +126,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -139,9 +139,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -152,9 +152,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, @@ -238,9 +238,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 31.8813 ], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -269,9 +269,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl ], "radius": 11.88125, "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -294,9 +294,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 20.0 ], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -319,9 +319,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -344,9 +344,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -369,9 +369,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -394,9 +394,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -419,9 +419,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -444,9 +444,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -469,9 +469,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 41.8813 ], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, @@ -815,9 +815,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 2379, - "end": 2400, - "start": 2379, + "commentStart": 2373, + "end": 2394, + "start": 2373, "type": "TagDeclarator", "value": "rectangleSegmentA001" }, @@ -828,9 +828,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 2498, - "end": 2519, - "start": 2498, + "commentStart": 2492, + "end": 2513, + "start": 2492, "type": "TagDeclarator", "value": "rectangleSegmentB001" }, @@ -841,9 +841,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 2624, - "end": 2645, - "start": 2624, + "commentStart": 2618, + "end": 2639, + "start": 2618, "type": "TagDeclarator", "value": "rectangleSegmentC001" }, @@ -871,9 +871,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 2379, - "end": 2400, - "start": 2379, + "commentStart": 2373, + "end": 2394, + "start": 2373, "type": "TagDeclarator", "value": "rectangleSegmentA001" }, @@ -896,9 +896,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 2498, - "end": 2519, - "start": 2498, + "commentStart": 2492, + "end": 2513, + "start": 2492, "type": "TagDeclarator", "value": "rectangleSegmentB001" }, @@ -921,9 +921,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 2624, - "end": 2645, - "start": 2624, + "commentStart": 2618, + "end": 2639, + "start": 2618, "type": "TagDeclarator", "value": "rectangleSegmentC001" }, @@ -1005,9 +1005,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -1018,9 +1018,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -1031,9 +1031,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -1044,9 +1044,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -1057,9 +1057,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -1070,9 +1070,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -1083,9 +1083,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -1096,9 +1096,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -1109,9 +1109,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -1122,9 +1122,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, @@ -1208,9 +1208,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 31.8813 ], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -1239,9 +1239,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl ], "radius": 11.88125, "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -1264,9 +1264,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 20.0 ], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -1289,9 +1289,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -1314,9 +1314,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -1339,9 +1339,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -1364,9 +1364,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -1389,9 +1389,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -1414,9 +1414,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -1439,9 +1439,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 41.8813 ], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, @@ -1834,9 +1834,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1849, - "end": 1870, - "start": 1849, + "commentStart": 1843, + "end": 1864, + "start": 1843, "type": "TagDeclarator", "value": "rectangleSegmentA002" }, @@ -1847,9 +1847,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1968, - "end": 1989, - "start": 1968, + "commentStart": 1962, + "end": 1983, + "start": 1962, "type": "TagDeclarator", "value": "rectangleSegmentB002" }, @@ -1860,9 +1860,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 2094, - "end": 2115, - "start": 2094, + "commentStart": 2088, + "end": 2109, + "start": 2088, "type": "TagDeclarator", "value": "rectangleSegmentC002" }, @@ -1890,9 +1890,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 1849, - "end": 1870, - "start": 1849, + "commentStart": 1843, + "end": 1864, + "start": 1843, "type": "TagDeclarator", "value": "rectangleSegmentA002" }, @@ -1915,9 +1915,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 1968, - "end": 1989, - "start": 1968, + "commentStart": 1962, + "end": 1983, + "start": 1962, "type": "TagDeclarator", "value": "rectangleSegmentB002" }, @@ -1940,9 +1940,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 2094, - "end": 2115, - "start": 2094, + "commentStart": 2088, + "end": 2109, + "start": 2088, "type": "TagDeclarator", "value": "rectangleSegmentC002" }, @@ -2024,9 +2024,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -2037,9 +2037,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -2050,9 +2050,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -2063,9 +2063,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -2076,9 +2076,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -2089,9 +2089,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -2102,9 +2102,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -2115,9 +2115,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -2128,9 +2128,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -2141,9 +2141,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, @@ -2227,9 +2227,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 31.8813 ], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -2258,9 +2258,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl ], "radius": 11.88125, "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -2283,9 +2283,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 20.0 ], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -2308,9 +2308,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -2333,9 +2333,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -2358,9 +2358,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -2383,9 +2383,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -2408,9 +2408,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -2433,9 +2433,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -2458,9 +2458,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 41.8813 ], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, @@ -2853,9 +2853,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 2915, - "end": 2936, - "start": 2915, + "commentStart": 2909, + "end": 2930, + "start": 2909, "type": "TagDeclarator", "value": "rectangleSegmentA003" }, @@ -2866,9 +2866,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 3034, - "end": 3055, - "start": 3034, + "commentStart": 3028, + "end": 3049, + "start": 3028, "type": "TagDeclarator", "value": "rectangleSegmentB003" }, @@ -2879,9 +2879,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 3160, - "end": 3181, - "start": 3160, + "commentStart": 3154, + "end": 3175, + "start": 3154, "type": "TagDeclarator", "value": "rectangleSegmentC003" }, @@ -2909,9 +2909,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 2915, - "end": 2936, - "start": 2915, + "commentStart": 2909, + "end": 2930, + "start": 2909, "type": "TagDeclarator", "value": "rectangleSegmentA003" }, @@ -2934,9 +2934,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 3034, - "end": 3055, - "start": 3034, + "commentStart": 3028, + "end": 3049, + "start": 3028, "type": "TagDeclarator", "value": "rectangleSegmentB003" }, @@ -2959,9 +2959,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 3160, - "end": 3181, - "start": 3160, + "commentStart": 3154, + "end": 3175, + "start": 3154, "type": "TagDeclarator", "value": "rectangleSegmentC003" }, @@ -3043,9 +3043,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 2379, - "end": 2400, - "start": 2379, + "commentStart": 2373, + "end": 2394, + "start": 2373, "type": "TagDeclarator", "value": "rectangleSegmentA001" }, @@ -3056,9 +3056,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 2498, - "end": 2519, - "start": 2498, + "commentStart": 2492, + "end": 2513, + "start": 2492, "type": "TagDeclarator", "value": "rectangleSegmentB001" }, @@ -3069,9 +3069,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 2624, - "end": 2645, - "start": 2624, + "commentStart": 2618, + "end": 2639, + "start": 2618, "type": "TagDeclarator", "value": "rectangleSegmentC001" }, @@ -3099,9 +3099,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 2379, - "end": 2400, - "start": 2379, + "commentStart": 2373, + "end": 2394, + "start": 2373, "type": "TagDeclarator", "value": "rectangleSegmentA001" }, @@ -3124,9 +3124,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 2498, - "end": 2519, - "start": 2498, + "commentStart": 2492, + "end": 2513, + "start": 2492, "type": "TagDeclarator", "value": "rectangleSegmentB001" }, @@ -3149,9 +3149,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 2624, - "end": 2645, - "start": 2624, + "commentStart": 2618, + "end": 2639, + "start": 2618, "type": "TagDeclarator", "value": "rectangleSegmentC001" }, @@ -3233,9 +3233,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -3246,9 +3246,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -3259,9 +3259,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -3272,9 +3272,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -3285,9 +3285,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -3298,9 +3298,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -3311,9 +3311,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -3324,9 +3324,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -3337,9 +3337,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -3350,9 +3350,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, @@ -3436,9 +3436,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 31.8813 ], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -3467,9 +3467,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl ], "radius": 11.88125, "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -3492,9 +3492,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 20.0 ], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -3517,9 +3517,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -3542,9 +3542,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -3567,9 +3567,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -3592,9 +3592,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -3617,9 +3617,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -3642,9 +3642,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -3667,9 +3667,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 41.8813 ], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, @@ -4249,9 +4249,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 31.8813 ], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -4280,9 +4280,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl ], "radius": 11.88125, "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -4305,9 +4305,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 20.0 ], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -4330,9 +4330,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -4355,9 +4355,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -4380,9 +4380,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -4405,9 +4405,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -4430,9 +4430,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -4455,9 +4455,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -4480,9 +4480,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 41.8813 ], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, @@ -4823,9 +4823,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 2379, - "end": 2400, - "start": 2379, + "commentStart": 2373, + "end": 2394, + "start": 2373, "type": "TagDeclarator", "value": "rectangleSegmentA001" }, @@ -4848,9 +4848,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 2498, - "end": 2519, - "start": 2498, + "commentStart": 2492, + "end": 2513, + "start": 2492, "type": "TagDeclarator", "value": "rectangleSegmentB001" }, @@ -4873,9 +4873,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 2624, - "end": 2645, - "start": 2624, + "commentStart": 2618, + "end": 2639, + "start": 2618, "type": "TagDeclarator", "value": "rectangleSegmentC001" }, @@ -4957,9 +4957,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -4970,9 +4970,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -4983,9 +4983,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -4996,9 +4996,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -5009,9 +5009,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -5022,9 +5022,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -5035,9 +5035,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -5048,9 +5048,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -5061,9 +5061,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -5074,9 +5074,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, @@ -5160,9 +5160,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 31.8813 ], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -5191,9 +5191,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl ], "radius": 11.88125, "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -5216,9 +5216,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 20.0 ], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -5241,9 +5241,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -5266,9 +5266,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -5291,9 +5291,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -5316,9 +5316,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -5341,9 +5341,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -5366,9 +5366,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -5391,9 +5391,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 41.8813 ], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, @@ -5783,9 +5783,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 1849, - "end": 1870, - "start": 1849, + "commentStart": 1843, + "end": 1864, + "start": 1843, "type": "TagDeclarator", "value": "rectangleSegmentA002" }, @@ -5808,9 +5808,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 1968, - "end": 1989, - "start": 1968, + "commentStart": 1962, + "end": 1983, + "start": 1962, "type": "TagDeclarator", "value": "rectangleSegmentB002" }, @@ -5833,9 +5833,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 2094, - "end": 2115, - "start": 2094, + "commentStart": 2088, + "end": 2109, + "start": 2088, "type": "TagDeclarator", "value": "rectangleSegmentC002" }, @@ -5917,9 +5917,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -5930,9 +5930,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -5943,9 +5943,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -5956,9 +5956,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -5969,9 +5969,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -5982,9 +5982,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -5995,9 +5995,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -6008,9 +6008,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -6021,9 +6021,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -6034,9 +6034,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, @@ -6120,9 +6120,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 31.8813 ], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -6151,9 +6151,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl ], "radius": 11.88125, "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -6176,9 +6176,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 20.0 ], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -6201,9 +6201,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -6226,9 +6226,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -6251,9 +6251,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -6276,9 +6276,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -6301,9 +6301,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -6326,9 +6326,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -6351,9 +6351,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 41.8813 ], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, @@ -6743,9 +6743,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 2915, - "end": 2936, - "start": 2915, + "commentStart": 2909, + "end": 2930, + "start": 2909, "type": "TagDeclarator", "value": "rectangleSegmentA003" }, @@ -6768,9 +6768,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 3034, - "end": 3055, - "start": 3034, + "commentStart": 3028, + "end": 3049, + "start": 3028, "type": "TagDeclarator", "value": "rectangleSegmentB003" }, @@ -6793,9 +6793,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 3160, - "end": 3181, - "start": 3160, + "commentStart": 3154, + "end": 3175, + "start": 3154, "type": "TagDeclarator", "value": "rectangleSegmentC003" }, @@ -6877,9 +6877,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 2379, - "end": 2400, - "start": 2379, + "commentStart": 2373, + "end": 2394, + "start": 2373, "type": "TagDeclarator", "value": "rectangleSegmentA001" }, @@ -6890,9 +6890,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 2498, - "end": 2519, - "start": 2498, + "commentStart": 2492, + "end": 2513, + "start": 2492, "type": "TagDeclarator", "value": "rectangleSegmentB001" }, @@ -6903,9 +6903,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 2624, - "end": 2645, - "start": 2624, + "commentStart": 2618, + "end": 2639, + "start": 2618, "type": "TagDeclarator", "value": "rectangleSegmentC001" }, @@ -6933,9 +6933,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 2379, - "end": 2400, - "start": 2379, + "commentStart": 2373, + "end": 2394, + "start": 2373, "type": "TagDeclarator", "value": "rectangleSegmentA001" }, @@ -6958,9 +6958,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 0.0 ], "tag": { - "commentStart": 2498, - "end": 2519, - "start": 2498, + "commentStart": 2492, + "end": 2513, + "start": 2492, "type": "TagDeclarator", "value": "rectangleSegmentB001" }, @@ -6983,9 +6983,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 2624, - "end": 2645, - "start": 2624, + "commentStart": 2618, + "end": 2639, + "start": 2618, "type": "TagDeclarator", "value": "rectangleSegmentC001" }, @@ -7067,9 +7067,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -7080,9 +7080,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -7093,9 +7093,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -7106,9 +7106,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -7119,9 +7119,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -7132,9 +7132,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -7145,9 +7145,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -7158,9 +7158,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -7171,9 +7171,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -7184,9 +7184,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, @@ -7270,9 +7270,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 31.8813 ], "tag": { - "commentStart": 558, - "end": 564, - "start": 558, + "commentStart": 555, + "end": 561, + "start": 555, "type": "TagDeclarator", "value": "seg01" }, @@ -7301,9 +7301,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl ], "radius": 11.88125, "tag": { - "commentStart": 666, - "end": 672, - "start": 666, + "commentStart": 663, + "end": 669, + "start": 663, "type": "TagDeclarator", "value": "seg09" }, @@ -7326,9 +7326,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 20.0 ], "tag": { - "commentStart": 725, - "end": 731, - "start": 725, + "commentStart": 722, + "end": 728, + "start": 722, "type": "TagDeclarator", "value": "seg03" }, @@ -7351,9 +7351,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 778, - "end": 784, - "start": 778, + "commentStart": 775, + "end": 781, + "start": 775, "type": "TagDeclarator", "value": "seg07" }, @@ -7376,9 +7376,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl -10.0 ], "tag": { - "commentStart": 879, - "end": 885, - "start": 879, + "commentStart": 876, + "end": 882, + "start": 876, "type": "TagDeclarator", "value": "seg02" }, @@ -7401,9 +7401,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 956, - "end": 962, - "start": 956, + "commentStart": 953, + "end": 959, + "start": 953, "type": "TagDeclarator", "value": "seg06" }, @@ -7426,9 +7426,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 10.9406 ], "tag": { - "commentStart": 1013, - "end": 1019, - "start": 1013, + "commentStart": 1010, + "end": 1016, + "start": 1010, "type": "TagDeclarator", "value": "seg08" }, @@ -7451,9 +7451,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1072, - "end": 1078, - "start": 1072, + "commentStart": 1069, + "end": 1075, + "start": 1069, "type": "TagDeclarator", "value": "seg05" }, @@ -7476,9 +7476,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 30.9406 ], "tag": { - "commentStart": 1147, - "end": 1153, - "start": 1147, + "commentStart": 1144, + "end": 1150, + "start": 1144, "type": "TagDeclarator", "value": "seg10" }, @@ -7501,9 +7501,9 @@ description: Variables in memory after executing router-template-cross-bar.kcl 41.8813 ], "tag": { - "commentStart": 1192, - "end": 1198, - "start": 1192, + "commentStart": 1186, + "end": 1192, + "start": 1186, "type": "TagDeclarator", "value": "seg04" }, diff --git a/rust/kcl-lib/tests/kcl_samples/router-template-slate/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/router-template-slate/artifact_commands.snap index 2fedc3b87..a1bc94bf9 100644 --- a/rust/kcl-lib/tests/kcl_samples/router-template-slate/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/router-template-slate/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands router-template-slate.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/router-template-slate/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/kcl_samples/router-template-slate/artifact_graph_flowchart.snap.md index 4c27a6527..2cbc5e206 100644 --- a/rust/kcl-lib/tests/kcl_samples/router-template-slate/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/kcl_samples/router-template-slate/artifact_graph_flowchart.snap.md @@ -7,36 +7,36 @@ flowchart LR 5["Segment
[705, 781, 0]"] 6["Segment
[787, 856, 0]"] 7["Segment
[862, 902, 0]"] - 8["Segment
[908, 947, 0]"] - 9["Segment
[987, 1017, 0]"] - 10["Segment
[1023, 1052, 0]"] - 11["Segment
[1058, 1087, 0]"] - 12["Segment
[1093, 1122, 0]"] - 13["Segment
[1128, 1228, 0]"] - 14["Segment
[1234, 1290, 0]"] - 15["Segment
[1296, 1303, 0]"] + 8["Segment
[908, 944, 0]"] + 9["Segment
[984, 1014, 0]"] + 10["Segment
[1020, 1049, 0]"] + 11["Segment
[1055, 1084, 0]"] + 12["Segment
[1090, 1119, 0]"] + 13["Segment
[1125, 1225, 0]"] + 14["Segment
[1231, 1287, 0]"] + 15["Segment
[1293, 1300, 0]"] 16[Solid2d] end subgraph path52 [Path] - 52["Path
[1458, 1558, 0]"] - 53["Segment
[1564, 1611, 0]"] - 54["Segment
[1617, 1732, 0]"] - 55["Segment
[1738, 1858, 0]"] - 56["Segment
[1864, 1920, 0]"] - 57["Segment
[1926, 1933, 0]"] + 52["Path
[1455, 1555, 0]"] + 53["Segment
[1561, 1608, 0]"] + 54["Segment
[1614, 1729, 0]"] + 55["Segment
[1735, 1855, 0]"] + 56["Segment
[1861, 1917, 0]"] + 57["Segment
[1923, 1930, 0]"] 58[Solid2d] end subgraph path74 [Path] - 74["Path
[2090, 2189, 0]"] - 75["Segment
[2195, 2241, 0]"] - 76["Segment
[2247, 2339, 0]"] - 77["Segment
[2345, 2442, 0]"] - 78["Segment
[2448, 2504, 0]"] - 79["Segment
[2510, 2517, 0]"] + 74["Path
[2087, 2186, 0]"] + 75["Segment
[2192, 2238, 0]"] + 76["Segment
[2244, 2336, 0]"] + 77["Segment
[2342, 2439, 0]"] + 78["Segment
[2445, 2501, 0]"] + 79["Segment
[2507, 2514, 0]"] 80[Solid2d] end 1["Plane
[484, 501, 0]"] - 17["Sweep Extrusion
[1346, 1376, 0]"] + 17["Sweep Extrusion
[1343, 1373, 0]"] 18[Wall] 19[Wall] 20[Wall] @@ -71,7 +71,7 @@ flowchart LR 49["SweepEdge Opposite"] 50["SweepEdge Adjacent"] 51["SweepEdge Opposite"] - 59["Sweep Extrusion
[1977, 2009, 0]"] + 59["Sweep Extrusion
[1974, 2006, 0]"] 60[Wall] 61[Wall] 62[Wall] @@ -86,7 +86,7 @@ flowchart LR 71["SweepEdge Adjacent"] 72["SweepEdge Opposite"] 73["SweepEdge Adjacent"] - 81["Sweep Extrusion
[2560, 2592, 0]"] + 81["Sweep Extrusion
[2557, 2589, 0]"] 82[Wall] 83[Wall] 84[Wall] @@ -101,8 +101,8 @@ flowchart LR 93["SweepEdge Adjacent"] 94["SweepEdge Opposite"] 95["SweepEdge Adjacent"] - 96["StartSketchOnFace
[1418, 1452, 0]"] - 97["StartSketchOnFace
[2050, 2084, 0]"] + 96["StartSketchOnFace
[1415, 1449, 0]"] + 97["StartSketchOnFace
[2047, 2081, 0]"] 1 --- 2 2 --- 3 2 --- 4 diff --git a/rust/kcl-lib/tests/kcl_samples/router-template-slate/ast.snap b/rust/kcl-lib/tests/kcl_samples/router-template-slate/ast.snap index b0a744e13..9add12d6e 100644 --- a/rust/kcl-lib/tests/kcl_samples/router-template-slate/ast.snap +++ b/rust/kcl-lib/tests/kcl_samples/router-template-slate/ast.snap @@ -1234,33 +1234,29 @@ description: Result of parsing router-template-slate.kcl "type": "Identifier" }, "arg": { - "abs_path": false, "commentStart": 928, "end": 0, - "name": { - "commentStart": 928, - "end": 0, - "name": "ZERO", - "start": 0, - "type": "Identifier" - }, - "path": [], + "raw": "0", "start": 0, - "type": "Name", - "type": "Name" + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } } }, { "type": "LabeledArg", "label": { - "commentStart": 934, + "commentStart": 931, "end": 0, "name": "tag", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 940, + "commentStart": 937, "end": 0, "start": 0, "type": "TagDeclarator", @@ -1296,7 +1292,7 @@ description: Result of parsing router-template-slate.kcl { "type": "LabeledArg", "label": { - "commentStart": 993, + "commentStart": 990, "end": 0, "name": "length", "start": 0, @@ -1307,10 +1303,10 @@ description: Result of parsing router-template-slate.kcl "arguments": [ { "abs_path": false, - "commentStart": 1010, + "commentStart": 1007, "end": 0, "name": { - "commentStart": 1010, + "commentStart": 1007, "end": 0, "name": "seg02", "start": 0, @@ -1324,10 +1320,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1003, + "commentStart": 1000, "end": 0, "name": { - "commentStart": 1003, + "commentStart": 1000, "end": 0, "name": "segLen", "start": 0, @@ -1337,13 +1333,13 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1003, + "commentStart": 1000, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" }, - "commentStart": 1002, + "commentStart": 999, "end": 0, "operator": "-", "start": 0, @@ -1354,10 +1350,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 987, + "commentStart": 984, "end": 0, "name": { - "commentStart": 987, + "commentStart": 984, "end": 0, "name": "xLine", "start": 0, @@ -1367,7 +1363,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 987, + "commentStart": 984, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1379,7 +1375,7 @@ description: Result of parsing router-template-slate.kcl { "type": "LabeledArg", "label": { - "commentStart": 1029, + "commentStart": 1026, "end": 0, "name": "length", "start": 0, @@ -1389,10 +1385,10 @@ description: Result of parsing router-template-slate.kcl "arguments": [ { "abs_path": false, - "commentStart": 1045, + "commentStart": 1042, "end": 0, "name": { - "commentStart": 1045, + "commentStart": 1042, "end": 0, "name": "seg03", "start": 0, @@ -1406,10 +1402,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1038, + "commentStart": 1035, "end": 0, "name": { - "commentStart": 1038, + "commentStart": 1035, "end": 0, "name": "segLen", "start": 0, @@ -1419,7 +1415,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1038, + "commentStart": 1035, "end": 0, "start": 0, "type": "CallExpression", @@ -1429,10 +1425,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1023, + "commentStart": 1020, "end": 0, "name": { - "commentStart": 1023, + "commentStart": 1020, "end": 0, "name": "yLine", "start": 0, @@ -1442,7 +1438,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1023, + "commentStart": 1020, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1454,7 +1450,7 @@ description: Result of parsing router-template-slate.kcl { "type": "LabeledArg", "label": { - "commentStart": 1064, + "commentStart": 1061, "end": 0, "name": "length", "start": 0, @@ -1464,10 +1460,10 @@ description: Result of parsing router-template-slate.kcl "arguments": [ { "abs_path": false, - "commentStart": 1080, + "commentStart": 1077, "end": 0, "name": { - "commentStart": 1080, + "commentStart": 1077, "end": 0, "name": "seg04", "start": 0, @@ -1481,10 +1477,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1073, + "commentStart": 1070, "end": 0, "name": { - "commentStart": 1073, + "commentStart": 1070, "end": 0, "name": "segLen", "start": 0, @@ -1494,7 +1490,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1073, + "commentStart": 1070, "end": 0, "start": 0, "type": "CallExpression", @@ -1504,10 +1500,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1058, + "commentStart": 1055, "end": 0, "name": { - "commentStart": 1058, + "commentStart": 1055, "end": 0, "name": "xLine", "start": 0, @@ -1517,7 +1513,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1058, + "commentStart": 1055, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1529,7 +1525,7 @@ description: Result of parsing router-template-slate.kcl { "type": "LabeledArg", "label": { - "commentStart": 1099, + "commentStart": 1096, "end": 0, "name": "length", "start": 0, @@ -1539,10 +1535,10 @@ description: Result of parsing router-template-slate.kcl "arguments": [ { "abs_path": false, - "commentStart": 1115, + "commentStart": 1112, "end": 0, "name": { - "commentStart": 1115, + "commentStart": 1112, "end": 0, "name": "seg05", "start": 0, @@ -1556,10 +1552,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1108, + "commentStart": 1105, "end": 0, "name": { - "commentStart": 1108, + "commentStart": 1105, "end": 0, "name": "segLen", "start": 0, @@ -1569,7 +1565,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1108, + "commentStart": 1105, "end": 0, "start": 0, "type": "CallExpression", @@ -1579,10 +1575,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1093, + "commentStart": 1090, "end": 0, "name": { - "commentStart": 1093, + "commentStart": 1090, "end": 0, "name": "yLine", "start": 0, @@ -1592,7 +1588,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1093, + "commentStart": 1090, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1602,14 +1598,14 @@ description: Result of parsing router-template-slate.kcl { "arguments": [ { - "commentStart": 1132, + "commentStart": 1129, "end": 0, "properties": [ { - "commentStart": 1141, + "commentStart": 1138, "end": 0, "key": { - "commentStart": 1141, + "commentStart": 1138, "end": 0, "name": "angleEnd", "start": 0, @@ -1618,7 +1614,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 1152, + "commentStart": 1149, "end": 0, "raw": "90", "start": 0, @@ -1631,10 +1627,10 @@ description: Result of parsing router-template-slate.kcl } }, { - "commentStart": 1163, + "commentStart": 1160, "end": 0, "key": { - "commentStart": 1163, + "commentStart": 1160, "end": 0, "name": "angleStart", "start": 0, @@ -1643,7 +1639,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 1176, + "commentStart": 1173, "end": 0, "raw": "180", "start": 0, @@ -1656,10 +1652,10 @@ description: Result of parsing router-template-slate.kcl } }, { - "commentStart": 1188, + "commentStart": 1185, "end": 0, "key": { - "commentStart": 1188, + "commentStart": 1185, "end": 0, "name": "radius", "start": 0, @@ -1668,14 +1664,14 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "ObjectProperty", "value": { - "commentStart": 1197, + "commentStart": 1194, "end": 0, "left": { "abs_path": false, - "commentStart": 1197, + "commentStart": 1194, "end": 0, "name": { - "commentStart": 1197, + "commentStart": 1194, "end": 0, "name": "radius", "start": 0, @@ -1689,10 +1685,10 @@ description: Result of parsing router-template-slate.kcl "operator": "-", "right": { "abs_path": false, - "commentStart": 1206, + "commentStart": 1203, "end": 0, "name": { - "commentStart": 1206, + "commentStart": 1203, "end": 0, "name": "templateGap", "start": 0, @@ -1714,7 +1710,7 @@ description: Result of parsing router-template-slate.kcl "type": "ObjectExpression" }, { - "commentStart": 1226, + "commentStart": 1223, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -1723,10 +1719,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1128, + "commentStart": 1125, "end": 0, "name": { - "commentStart": 1128, + "commentStart": 1125, "end": 0, "name": "arc", "start": 0, @@ -1736,7 +1732,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1128, + "commentStart": 1125, "end": 0, "start": 0, "type": "CallExpression", @@ -1747,19 +1743,19 @@ description: Result of parsing router-template-slate.kcl { "type": "LabeledArg", "label": { - "commentStart": 1239, + "commentStart": 1236, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1253, + "commentStart": 1250, "elements": [ { "arguments": [ { - "commentStart": 1268, + "commentStart": 1265, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -1768,10 +1764,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1254, + "commentStart": 1251, "end": 0, "name": { - "commentStart": 1254, + "commentStart": 1251, "end": 0, "name": "profileStartX", "start": 0, @@ -1781,7 +1777,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1254, + "commentStart": 1251, "end": 0, "start": 0, "type": "CallExpression", @@ -1790,7 +1786,7 @@ description: Result of parsing router-template-slate.kcl { "arguments": [ { - "commentStart": 1286, + "commentStart": 1283, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -1799,10 +1795,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1272, + "commentStart": 1269, "end": 0, "name": { - "commentStart": 1272, + "commentStart": 1269, "end": 0, "name": "profileStartY", "start": 0, @@ -1812,7 +1808,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1272, + "commentStart": 1269, "end": 0, "start": 0, "type": "CallExpression", @@ -1828,10 +1824,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1234, + "commentStart": 1231, "end": 0, "name": { - "commentStart": 1234, + "commentStart": 1231, "end": 0, "name": "line", "start": 0, @@ -1841,7 +1837,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1234, + "commentStart": 1231, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1852,10 +1848,10 @@ description: Result of parsing router-template-slate.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 1296, + "commentStart": 1293, "end": 0, "name": { - "commentStart": 1296, + "commentStart": 1293, "end": 0, "name": "close", "start": 0, @@ -1865,7 +1861,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1296, + "commentStart": 1293, "end": 0, "start": 0, "type": "CallExpression", @@ -1878,7 +1874,7 @@ description: Result of parsing router-template-slate.kcl "nonCodeNodes": { "7": [ { - "commentStart": 949, + "commentStart": 946, "end": 0, "start": 0, "type": "NonCodeNode", @@ -1891,7 +1887,7 @@ description: Result of parsing router-template-slate.kcl ], "14": [ { - "commentStart": 1303, + "commentStart": 1300, "end": 0, "start": 0, "type": "NonCodeNode", @@ -1924,12 +1920,12 @@ description: Result of parsing router-template-slate.kcl "type": "VariableDeclaration" }, { - "commentStart": 1333, + "commentStart": 1330, "declaration": { - "commentStart": 1333, + "commentStart": 1330, "end": 0, "id": { - "commentStart": 1333, + "commentStart": 1330, "end": 0, "name": "extrude001", "start": 0, @@ -1940,14 +1936,14 @@ description: Result of parsing router-template-slate.kcl { "type": "LabeledArg", "label": { - "commentStart": 1365, + "commentStart": 1362, "end": 0, "name": "length", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1374, + "commentStart": 1371, "end": 0, "raw": "5", "start": 0, @@ -1962,10 +1958,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1346, + "commentStart": 1343, "end": 0, "name": { - "commentStart": 1346, + "commentStart": 1343, "end": 0, "name": "extrude", "start": 0, @@ -1975,17 +1971,17 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1346, + "commentStart": 1343, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 1354, + "commentStart": 1351, "end": 0, "name": { - "commentStart": 1354, + "commentStart": 1351, "end": 0, "name": "sketch001", "start": 0, @@ -2007,12 +2003,12 @@ description: Result of parsing router-template-slate.kcl "type": "VariableDeclaration" }, { - "commentStart": 1376, + "commentStart": 1373, "declaration": { - "commentStart": 1406, + "commentStart": 1403, "end": 0, "id": { - "commentStart": 1406, + "commentStart": 1403, "end": 0, "name": "sketch002", "start": 0, @@ -2024,10 +2020,10 @@ description: Result of parsing router-template-slate.kcl "arguments": [ { "abs_path": false, - "commentStart": 1432, + "commentStart": 1429, "end": 0, "name": { - "commentStart": 1432, + "commentStart": 1429, "end": 0, "name": "extrude001", "start": 0, @@ -2039,7 +2035,7 @@ description: Result of parsing router-template-slate.kcl "type": "Name" }, { - "commentStart": 1444, + "commentStart": 1441, "end": 0, "raw": "'START'", "start": 0, @@ -2050,10 +2046,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1418, + "commentStart": 1415, "end": 0, "name": { - "commentStart": 1418, + "commentStart": 1415, "end": 0, "name": "startSketchOn", "start": 0, @@ -2063,7 +2059,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1418, + "commentStart": 1415, "end": 0, "start": 0, "type": "CallExpression", @@ -2072,15 +2068,15 @@ description: Result of parsing router-template-slate.kcl { "arguments": [ { - "commentStart": 1473, + "commentStart": 1470, "elements": [ { "argument": { "abs_path": false, - "commentStart": 1483, + "commentStart": 1480, "end": 0, "name": { - "commentStart": 1483, + "commentStart": 1480, "end": 0, "name": "slateWidthHalf", "start": 0, @@ -2091,7 +2087,7 @@ description: Result of parsing router-template-slate.kcl "type": "Name", "type": "Name" }, - "commentStart": 1482, + "commentStart": 1479, "end": 0, "operator": "-", "start": 0, @@ -2099,18 +2095,18 @@ description: Result of parsing router-template-slate.kcl "type": "UnaryExpression" }, { - "commentStart": 1506, + "commentStart": 1503, "end": 0, "left": { - "commentStart": 1506, + "commentStart": 1503, "end": 0, "left": { "argument": { "abs_path": false, - "commentStart": 1507, + "commentStart": 1504, "end": 0, "name": { - "commentStart": 1507, + "commentStart": 1504, "end": 0, "name": "templateGap", "start": 0, @@ -2121,7 +2117,7 @@ description: Result of parsing router-template-slate.kcl "type": "Name", "type": "Name" }, - "commentStart": 1506, + "commentStart": 1503, "end": 0, "operator": "-", "start": 0, @@ -2130,7 +2126,7 @@ description: Result of parsing router-template-slate.kcl }, "operator": "*", "right": { - "commentStart": 1521, + "commentStart": 1518, "end": 0, "raw": "2", "start": 0, @@ -2147,14 +2143,14 @@ description: Result of parsing router-template-slate.kcl }, "operator": "-", "right": { - "commentStart": 1526, + "commentStart": 1523, "end": 0, "left": { "abs_path": false, - "commentStart": 1526, + "commentStart": 1523, "end": 0, "name": { - "commentStart": 1526, + "commentStart": 1523, "end": 0, "name": "templateDiameter", "start": 0, @@ -2167,7 +2163,7 @@ description: Result of parsing router-template-slate.kcl }, "operator": "/", "right": { - "commentStart": 1545, + "commentStart": 1542, "end": 0, "raw": "2", "start": 0, @@ -2193,7 +2189,7 @@ description: Result of parsing router-template-slate.kcl "type": "ArrayExpression" }, { - "commentStart": 1556, + "commentStart": 1553, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2202,10 +2198,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1458, + "commentStart": 1455, "end": 0, "name": { - "commentStart": 1458, + "commentStart": 1455, "end": 0, "name": "startProfileAt", "start": 0, @@ -2215,7 +2211,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1458, + "commentStart": 1455, "end": 0, "start": 0, "type": "CallExpression", @@ -2226,7 +2222,7 @@ description: Result of parsing router-template-slate.kcl { "type": "LabeledArg", "label": { - "commentStart": 1570, + "commentStart": 1567, "end": 0, "name": "length", "start": 0, @@ -2234,7 +2230,7 @@ description: Result of parsing router-template-slate.kcl }, "arg": { "argument": { - "commentStart": 1580, + "commentStart": 1577, "end": 0, "raw": "7", "start": 0, @@ -2245,7 +2241,7 @@ description: Result of parsing router-template-slate.kcl "suffix": "None" } }, - "commentStart": 1579, + "commentStart": 1576, "end": 0, "operator": "-", "start": 0, @@ -2256,14 +2252,14 @@ description: Result of parsing router-template-slate.kcl { "type": "LabeledArg", "label": { - "commentStart": 1583, + "commentStart": 1580, "end": 0, "name": "tag", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1589, + "commentStart": 1586, "end": 0, "start": 0, "type": "TagDeclarator", @@ -2274,10 +2270,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1564, + "commentStart": 1561, "end": 0, "name": { - "commentStart": 1564, + "commentStart": 1561, "end": 0, "name": "xLine", "start": 0, @@ -2287,7 +2283,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1564, + "commentStart": 1561, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2297,19 +2293,19 @@ description: Result of parsing router-template-slate.kcl { "arguments": [ { - "commentStart": 1628, + "commentStart": 1625, "elements": [ { - "commentStart": 1637, + "commentStart": 1634, "end": 0, "left": { "arguments": [ { "abs_path": false, - "commentStart": 1644, + "commentStart": 1641, "end": 0, "name": { - "commentStart": 1644, + "commentStart": 1641, "end": 0, "name": "rectangleSegmentA001", "start": 0, @@ -2323,10 +2319,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1637, + "commentStart": 1634, "end": 0, "name": { - "commentStart": 1637, + "commentStart": 1634, "end": 0, "name": "segAng", "start": 0, @@ -2336,7 +2332,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1637, + "commentStart": 1634, "end": 0, "start": 0, "type": "CallExpression", @@ -2344,7 +2340,7 @@ description: Result of parsing router-template-slate.kcl }, "operator": "+", "right": { - "commentStart": 1668, + "commentStart": 1665, "end": 0, "raw": "90", "start": 0, @@ -2361,10 +2357,10 @@ description: Result of parsing router-template-slate.kcl }, { "abs_path": false, - "commentStart": 1679, + "commentStart": 1676, "end": 0, "name": { - "commentStart": 1679, + "commentStart": 1676, "end": 0, "name": "minClampingDistance", "start": 0, @@ -2382,14 +2378,14 @@ description: Result of parsing router-template-slate.kcl "type": "ArrayExpression" }, { - "commentStart": 1707, + "commentStart": 1704, "end": 0, "start": 0, "type": "PipeSubstitution", "type": "PipeSubstitution" }, { - "commentStart": 1710, + "commentStart": 1707, "end": 0, "start": 0, "type": "TagDeclarator", @@ -2399,10 +2395,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1617, + "commentStart": 1614, "end": 0, "name": { - "commentStart": 1617, + "commentStart": 1614, "end": 0, "name": "angledLine", "start": 0, @@ -2412,7 +2408,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1617, + "commentStart": 1614, "end": 0, "start": 0, "type": "CallExpression", @@ -2421,16 +2417,16 @@ description: Result of parsing router-template-slate.kcl { "arguments": [ { - "commentStart": 1749, + "commentStart": 1746, "elements": [ { "arguments": [ { "abs_path": false, - "commentStart": 1765, + "commentStart": 1762, "end": 0, "name": { - "commentStart": 1765, + "commentStart": 1762, "end": 0, "name": "rectangleSegmentA001", "start": 0, @@ -2444,10 +2440,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1758, + "commentStart": 1755, "end": 0, "name": { - "commentStart": 1758, + "commentStart": 1755, "end": 0, "name": "segAng", "start": 0, @@ -2457,7 +2453,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1758, + "commentStart": 1755, "end": 0, "start": 0, "type": "CallExpression", @@ -2468,10 +2464,10 @@ description: Result of parsing router-template-slate.kcl "arguments": [ { "abs_path": false, - "commentStart": 1803, + "commentStart": 1800, "end": 0, "name": { - "commentStart": 1803, + "commentStart": 1800, "end": 0, "name": "rectangleSegmentA001", "start": 0, @@ -2485,10 +2481,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1796, + "commentStart": 1793, "end": 0, "name": { - "commentStart": 1796, + "commentStart": 1793, "end": 0, "name": "segLen", "start": 0, @@ -2498,13 +2494,13 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1796, + "commentStart": 1793, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" }, - "commentStart": 1795, + "commentStart": 1792, "end": 0, "operator": "-", "start": 0, @@ -2518,14 +2514,14 @@ description: Result of parsing router-template-slate.kcl "type": "ArrayExpression" }, { - "commentStart": 1833, + "commentStart": 1830, "end": 0, "start": 0, "type": "PipeSubstitution", "type": "PipeSubstitution" }, { - "commentStart": 1836, + "commentStart": 1833, "end": 0, "start": 0, "type": "TagDeclarator", @@ -2535,10 +2531,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1738, + "commentStart": 1735, "end": 0, "name": { - "commentStart": 1738, + "commentStart": 1735, "end": 0, "name": "angledLine", "start": 0, @@ -2548,7 +2544,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1738, + "commentStart": 1735, "end": 0, "start": 0, "type": "CallExpression", @@ -2559,19 +2555,19 @@ description: Result of parsing router-template-slate.kcl { "type": "LabeledArg", "label": { - "commentStart": 1869, + "commentStart": 1866, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1883, + "commentStart": 1880, "elements": [ { "arguments": [ { - "commentStart": 1898, + "commentStart": 1895, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2580,10 +2576,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1884, + "commentStart": 1881, "end": 0, "name": { - "commentStart": 1884, + "commentStart": 1881, "end": 0, "name": "profileStartX", "start": 0, @@ -2593,7 +2589,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1884, + "commentStart": 1881, "end": 0, "start": 0, "type": "CallExpression", @@ -2602,7 +2598,7 @@ description: Result of parsing router-template-slate.kcl { "arguments": [ { - "commentStart": 1916, + "commentStart": 1913, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2611,10 +2607,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1902, + "commentStart": 1899, "end": 0, "name": { - "commentStart": 1902, + "commentStart": 1899, "end": 0, "name": "profileStartY", "start": 0, @@ -2624,7 +2620,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1902, + "commentStart": 1899, "end": 0, "start": 0, "type": "CallExpression", @@ -2640,10 +2636,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1864, + "commentStart": 1861, "end": 0, "name": { - "commentStart": 1864, + "commentStart": 1861, "end": 0, "name": "line", "start": 0, @@ -2653,7 +2649,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1864, + "commentStart": 1861, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2664,10 +2660,10 @@ description: Result of parsing router-template-slate.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 1926, + "commentStart": 1923, "end": 0, "name": { - "commentStart": 1926, + "commentStart": 1923, "end": 0, "name": "close", "start": 0, @@ -2677,20 +2673,20 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1926, + "commentStart": 1923, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" } ], - "commentStart": 1418, + "commentStart": 1415, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "6": [ { - "commentStart": 1933, + "commentStart": 1930, "end": 0, "start": 0, "type": "NonCodeNode", @@ -2723,12 +2719,12 @@ description: Result of parsing router-template-slate.kcl "type": "VariableDeclaration" }, { - "commentStart": 1964, + "commentStart": 1961, "declaration": { - "commentStart": 1964, + "commentStart": 1961, "end": 0, "id": { - "commentStart": 1964, + "commentStart": 1961, "end": 0, "name": "extrude002", "start": 0, @@ -2739,14 +2735,14 @@ description: Result of parsing router-template-slate.kcl { "type": "LabeledArg", "label": { - "commentStart": 1996, + "commentStart": 1993, "end": 0, "name": "length", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2005, + "commentStart": 2002, "end": 0, "raw": "7.5", "start": 0, @@ -2761,10 +2757,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 1977, + "commentStart": 1974, "end": 0, "name": { - "commentStart": 1977, + "commentStart": 1974, "end": 0, "name": "extrude", "start": 0, @@ -2774,17 +2770,17 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 1977, + "commentStart": 1974, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 1985, + "commentStart": 1982, "end": 0, "name": { - "commentStart": 1985, + "commentStart": 1982, "end": 0, "name": "sketch002", "start": 0, @@ -2806,12 +2802,12 @@ description: Result of parsing router-template-slate.kcl "type": "VariableDeclaration" }, { - "commentStart": 2009, + "commentStart": 2006, "declaration": { - "commentStart": 2038, + "commentStart": 2035, "end": 0, "id": { - "commentStart": 2038, + "commentStart": 2035, "end": 0, "name": "sketch003", "start": 0, @@ -2823,10 +2819,10 @@ description: Result of parsing router-template-slate.kcl "arguments": [ { "abs_path": false, - "commentStart": 2064, + "commentStart": 2061, "end": 0, "name": { - "commentStart": 2064, + "commentStart": 2061, "end": 0, "name": "extrude001", "start": 0, @@ -2838,7 +2834,7 @@ description: Result of parsing router-template-slate.kcl "type": "Name" }, { - "commentStart": 2076, + "commentStart": 2073, "end": 0, "raw": "'START'", "start": 0, @@ -2849,10 +2845,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 2050, + "commentStart": 2047, "end": 0, "name": { - "commentStart": 2050, + "commentStart": 2047, "end": 0, "name": "startSketchOn", "start": 0, @@ -2862,7 +2858,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 2050, + "commentStart": 2047, "end": 0, "start": 0, "type": "CallExpression", @@ -2871,14 +2867,14 @@ description: Result of parsing router-template-slate.kcl { "arguments": [ { - "commentStart": 2105, + "commentStart": 2102, "elements": [ { "abs_path": false, - "commentStart": 2114, + "commentStart": 2111, "end": 0, "name": { - "commentStart": 2114, + "commentStart": 2111, "end": 0, "name": "slateWidthHalf", "start": 0, @@ -2890,18 +2886,18 @@ description: Result of parsing router-template-slate.kcl "type": "Name" }, { - "commentStart": 2137, + "commentStart": 2134, "end": 0, "left": { - "commentStart": 2137, + "commentStart": 2134, "end": 0, "left": { "argument": { "abs_path": false, - "commentStart": 2138, + "commentStart": 2135, "end": 0, "name": { - "commentStart": 2138, + "commentStart": 2135, "end": 0, "name": "templateGap", "start": 0, @@ -2912,7 +2908,7 @@ description: Result of parsing router-template-slate.kcl "type": "Name", "type": "Name" }, - "commentStart": 2137, + "commentStart": 2134, "end": 0, "operator": "-", "start": 0, @@ -2921,7 +2917,7 @@ description: Result of parsing router-template-slate.kcl }, "operator": "*", "right": { - "commentStart": 2152, + "commentStart": 2149, "end": 0, "raw": "2", "start": 0, @@ -2938,14 +2934,14 @@ description: Result of parsing router-template-slate.kcl }, "operator": "-", "right": { - "commentStart": 2157, + "commentStart": 2154, "end": 0, "left": { "abs_path": false, - "commentStart": 2157, + "commentStart": 2154, "end": 0, "name": { - "commentStart": 2157, + "commentStart": 2154, "end": 0, "name": "templateDiameter", "start": 0, @@ -2958,7 +2954,7 @@ description: Result of parsing router-template-slate.kcl }, "operator": "/", "right": { - "commentStart": 2176, + "commentStart": 2173, "end": 0, "raw": "2", "start": 0, @@ -2984,7 +2980,7 @@ description: Result of parsing router-template-slate.kcl "type": "ArrayExpression" }, { - "commentStart": 2187, + "commentStart": 2184, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -2993,10 +2989,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 2090, + "commentStart": 2087, "end": 0, "name": { - "commentStart": 2090, + "commentStart": 2087, "end": 0, "name": "startProfileAt", "start": 0, @@ -3006,7 +3002,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 2090, + "commentStart": 2087, "end": 0, "start": 0, "type": "CallExpression", @@ -3017,14 +3013,14 @@ description: Result of parsing router-template-slate.kcl { "type": "LabeledArg", "label": { - "commentStart": 2201, + "commentStart": 2198, "end": 0, "name": "length", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2210, + "commentStart": 2207, "end": 0, "raw": "7", "start": 0, @@ -3039,14 +3035,14 @@ description: Result of parsing router-template-slate.kcl { "type": "LabeledArg", "label": { - "commentStart": 2213, + "commentStart": 2210, "end": 0, "name": "tag", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2219, + "commentStart": 2216, "end": 0, "start": 0, "type": "TagDeclarator", @@ -3057,10 +3053,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 2195, + "commentStart": 2192, "end": 0, "name": { - "commentStart": 2195, + "commentStart": 2192, "end": 0, "name": "xLine", "start": 0, @@ -3070,7 +3066,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 2195, + "commentStart": 2192, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -3080,19 +3076,19 @@ description: Result of parsing router-template-slate.kcl { "arguments": [ { - "commentStart": 2258, + "commentStart": 2255, "elements": [ { - "commentStart": 2267, + "commentStart": 2264, "end": 0, "left": { "arguments": [ { "abs_path": false, - "commentStart": 2274, + "commentStart": 2271, "end": 0, "name": { - "commentStart": 2274, + "commentStart": 2271, "end": 0, "name": "rectangleSegmentA002", "start": 0, @@ -3106,10 +3102,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 2267, + "commentStart": 2264, "end": 0, "name": { - "commentStart": 2267, + "commentStart": 2264, "end": 0, "name": "segAng", "start": 0, @@ -3119,7 +3115,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 2267, + "commentStart": 2264, "end": 0, "start": 0, "type": "CallExpression", @@ -3127,7 +3123,7 @@ description: Result of parsing router-template-slate.kcl }, "operator": "-", "right": { - "commentStart": 2298, + "commentStart": 2295, "end": 0, "raw": "90", "start": 0, @@ -3144,10 +3140,10 @@ description: Result of parsing router-template-slate.kcl }, { "abs_path": false, - "commentStart": 2309, + "commentStart": 2306, "end": 0, "name": { - "commentStart": 2309, + "commentStart": 2306, "end": 0, "name": "minClampingDistance", "start": 0, @@ -3165,7 +3161,7 @@ description: Result of parsing router-template-slate.kcl "type": "ArrayExpression" }, { - "commentStart": 2337, + "commentStart": 2334, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3174,10 +3170,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 2247, + "commentStart": 2244, "end": 0, "name": { - "commentStart": 2247, + "commentStart": 2244, "end": 0, "name": "angledLine", "start": 0, @@ -3187,7 +3183,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 2247, + "commentStart": 2244, "end": 0, "start": 0, "type": "CallExpression", @@ -3196,16 +3192,16 @@ description: Result of parsing router-template-slate.kcl { "arguments": [ { - "commentStart": 2356, + "commentStart": 2353, "elements": [ { "arguments": [ { "abs_path": false, - "commentStart": 2372, + "commentStart": 2369, "end": 0, "name": { - "commentStart": 2372, + "commentStart": 2369, "end": 0, "name": "rectangleSegmentA002", "start": 0, @@ -3219,10 +3215,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 2365, + "commentStart": 2362, "end": 0, "name": { - "commentStart": 2365, + "commentStart": 2362, "end": 0, "name": "segAng", "start": 0, @@ -3232,7 +3228,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 2365, + "commentStart": 2362, "end": 0, "start": 0, "type": "CallExpression", @@ -3243,10 +3239,10 @@ description: Result of parsing router-template-slate.kcl "arguments": [ { "abs_path": false, - "commentStart": 2410, + "commentStart": 2407, "end": 0, "name": { - "commentStart": 2410, + "commentStart": 2407, "end": 0, "name": "rectangleSegmentA002", "start": 0, @@ -3260,10 +3256,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 2403, + "commentStart": 2400, "end": 0, "name": { - "commentStart": 2403, + "commentStart": 2400, "end": 0, "name": "segLen", "start": 0, @@ -3273,13 +3269,13 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 2403, + "commentStart": 2400, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" }, - "commentStart": 2402, + "commentStart": 2399, "end": 0, "operator": "-", "start": 0, @@ -3293,7 +3289,7 @@ description: Result of parsing router-template-slate.kcl "type": "ArrayExpression" }, { - "commentStart": 2440, + "commentStart": 2437, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3302,10 +3298,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 2345, + "commentStart": 2342, "end": 0, "name": { - "commentStart": 2345, + "commentStart": 2342, "end": 0, "name": "angledLine", "start": 0, @@ -3315,7 +3311,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 2345, + "commentStart": 2342, "end": 0, "start": 0, "type": "CallExpression", @@ -3326,19 +3322,19 @@ description: Result of parsing router-template-slate.kcl { "type": "LabeledArg", "label": { - "commentStart": 2453, + "commentStart": 2450, "end": 0, "name": "endAbsolute", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2467, + "commentStart": 2464, "elements": [ { "arguments": [ { - "commentStart": 2482, + "commentStart": 2479, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3347,10 +3343,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 2468, + "commentStart": 2465, "end": 0, "name": { - "commentStart": 2468, + "commentStart": 2465, "end": 0, "name": "profileStartX", "start": 0, @@ -3360,7 +3356,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 2468, + "commentStart": 2465, "end": 0, "start": 0, "type": "CallExpression", @@ -3369,7 +3365,7 @@ description: Result of parsing router-template-slate.kcl { "arguments": [ { - "commentStart": 2500, + "commentStart": 2497, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -3378,10 +3374,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 2486, + "commentStart": 2483, "end": 0, "name": { - "commentStart": 2486, + "commentStart": 2483, "end": 0, "name": "profileStartY", "start": 0, @@ -3391,7 +3387,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 2486, + "commentStart": 2483, "end": 0, "start": 0, "type": "CallExpression", @@ -3407,10 +3403,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 2448, + "commentStart": 2445, "end": 0, "name": { - "commentStart": 2448, + "commentStart": 2445, "end": 0, "name": "line", "start": 0, @@ -3420,7 +3416,7 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 2448, + "commentStart": 2445, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -3431,10 +3427,10 @@ description: Result of parsing router-template-slate.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 2510, + "commentStart": 2507, "end": 0, "name": { - "commentStart": 2510, + "commentStart": 2507, "end": 0, "name": "close", "start": 0, @@ -3444,20 +3440,20 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 2510, + "commentStart": 2507, "end": 0, "start": 0, "type": "CallExpression", "type": "CallExpression" } ], - "commentStart": 2050, + "commentStart": 2047, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "6": [ { - "commentStart": 2517, + "commentStart": 2514, "end": 0, "start": 0, "type": "NonCodeNode", @@ -3490,12 +3486,12 @@ description: Result of parsing router-template-slate.kcl "type": "VariableDeclaration" }, { - "commentStart": 2547, + "commentStart": 2544, "declaration": { - "commentStart": 2547, + "commentStart": 2544, "end": 0, "id": { - "commentStart": 2547, + "commentStart": 2544, "end": 0, "name": "extrude003", "start": 0, @@ -3506,14 +3502,14 @@ description: Result of parsing router-template-slate.kcl { "type": "LabeledArg", "label": { - "commentStart": 2579, + "commentStart": 2576, "end": 0, "name": "length", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 2588, + "commentStart": 2585, "end": 0, "raw": "7.5", "start": 0, @@ -3528,10 +3524,10 @@ description: Result of parsing router-template-slate.kcl ], "callee": { "abs_path": false, - "commentStart": 2560, + "commentStart": 2557, "end": 0, "name": { - "commentStart": 2560, + "commentStart": 2557, "end": 0, "name": "extrude", "start": 0, @@ -3541,17 +3537,17 @@ description: Result of parsing router-template-slate.kcl "start": 0, "type": "Name" }, - "commentStart": 2560, + "commentStart": 2557, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { "abs_path": false, - "commentStart": 2568, + "commentStart": 2565, "end": 0, "name": { - "commentStart": 2568, + "commentStart": 2565, "end": 0, "name": "sketch003", "start": 0, diff --git a/rust/kcl-lib/tests/kcl_samples/router-template-slate/program_memory.snap b/rust/kcl-lib/tests/kcl_samples/router-template-slate/program_memory.snap index 11024462b..c18415276 100644 --- a/rust/kcl-lib/tests/kcl_samples/router-template-slate/program_memory.snap +++ b/rust/kcl-lib/tests/kcl_samples/router-template-slate/program_memory.snap @@ -264,9 +264,9 @@ description: Variables in memory after executing router-template-slate.kcl -122.4938 ], "tag": { - "commentStart": 940, - "end": 946, - "start": 940, + "commentStart": 937, + "end": 943, + "start": 937, "type": "TagDeclarator", "value": "seg02" }, @@ -514,9 +514,9 @@ description: Variables in memory after executing router-template-slate.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1589, - "end": 1610, - "start": 1589, + "commentStart": 1586, + "end": 1607, + "start": 1586, "type": "TagDeclarator", "value": "rectangleSegmentA001" }, @@ -527,9 +527,9 @@ description: Variables in memory after executing router-template-slate.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1710, - "end": 1731, - "start": 1710, + "commentStart": 1707, + "end": 1728, + "start": 1707, "type": "TagDeclarator", "value": "rectangleSegmentB001" }, @@ -540,9 +540,9 @@ description: Variables in memory after executing router-template-slate.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 1836, - "end": 1857, - "start": 1836, + "commentStart": 1833, + "end": 1854, + "start": 1833, "type": "TagDeclarator", "value": "rectangleSegmentC001" }, @@ -570,9 +570,9 @@ description: Variables in memory after executing router-template-slate.kcl -12.4937 ], "tag": { - "commentStart": 1589, - "end": 1610, - "start": 1589, + "commentStart": 1586, + "end": 1607, + "start": 1586, "type": "TagDeclarator", "value": "rectangleSegmentA001" }, @@ -595,9 +595,9 @@ description: Variables in memory after executing router-template-slate.kcl -12.4937 ], "tag": { - "commentStart": 1710, - "end": 1731, - "start": 1710, + "commentStart": 1707, + "end": 1728, + "start": 1707, "type": "TagDeclarator", "value": "rectangleSegmentB001" }, @@ -620,9 +620,9 @@ description: Variables in memory after executing router-template-slate.kcl -92.4938 ], "tag": { - "commentStart": 1836, - "end": 1857, - "start": 1836, + "commentStart": 1833, + "end": 1854, + "start": 1833, "type": "TagDeclarator", "value": "rectangleSegmentC001" }, @@ -940,9 +940,9 @@ description: Variables in memory after executing router-template-slate.kcl -122.4938 ], "tag": { - "commentStart": 940, - "end": 946, - "start": 940, + "commentStart": 937, + "end": 943, + "start": 937, "type": "TagDeclarator", "value": "seg02" }, @@ -1239,9 +1239,9 @@ description: Variables in memory after executing router-template-slate.kcl "id": "[uuid]", "sourceRange": [], "tag": { - "commentStart": 2219, - "end": 2240, - "start": 2219, + "commentStart": 2216, + "end": 2237, + "start": 2216, "type": "TagDeclarator", "value": "rectangleSegmentA002" }, @@ -1283,9 +1283,9 @@ description: Variables in memory after executing router-template-slate.kcl -12.4937 ], "tag": { - "commentStart": 2219, - "end": 2240, - "start": 2219, + "commentStart": 2216, + "end": 2237, + "start": 2216, "type": "TagDeclarator", "value": "rectangleSegmentA002" }, @@ -1641,9 +1641,9 @@ description: Variables in memory after executing router-template-slate.kcl -122.4938 ], "tag": { - "commentStart": 940, - "end": 946, - "start": 940, + "commentStart": 937, + "end": 943, + "start": 937, "type": "TagDeclarator", "value": "seg02" }, @@ -2165,9 +2165,9 @@ description: Variables in memory after executing router-template-slate.kcl -122.4938 ], "tag": { - "commentStart": 940, - "end": 946, - "start": 940, + "commentStart": 937, + "end": 943, + "start": 937, "type": "TagDeclarator", "value": "seg02" }, @@ -2412,9 +2412,9 @@ description: Variables in memory after executing router-template-slate.kcl -12.4937 ], "tag": { - "commentStart": 1589, - "end": 1610, - "start": 1589, + "commentStart": 1586, + "end": 1607, + "start": 1586, "type": "TagDeclarator", "value": "rectangleSegmentA001" }, @@ -2437,9 +2437,9 @@ description: Variables in memory after executing router-template-slate.kcl -12.4937 ], "tag": { - "commentStart": 1710, - "end": 1731, - "start": 1710, + "commentStart": 1707, + "end": 1728, + "start": 1707, "type": "TagDeclarator", "value": "rectangleSegmentB001" }, @@ -2462,9 +2462,9 @@ description: Variables in memory after executing router-template-slate.kcl -92.4938 ], "tag": { - "commentStart": 1836, - "end": 1857, - "start": 1836, + "commentStart": 1833, + "end": 1854, + "start": 1833, "type": "TagDeclarator", "value": "rectangleSegmentC001" }, @@ -2782,9 +2782,9 @@ description: Variables in memory after executing router-template-slate.kcl -122.4938 ], "tag": { - "commentStart": 940, - "end": 946, - "start": 940, + "commentStart": 937, + "end": 943, + "start": 937, "type": "TagDeclarator", "value": "seg02" }, @@ -3078,9 +3078,9 @@ description: Variables in memory after executing router-template-slate.kcl -12.4937 ], "tag": { - "commentStart": 2219, - "end": 2240, - "start": 2219, + "commentStart": 2216, + "end": 2237, + "start": 2216, "type": "TagDeclarator", "value": "rectangleSegmentA002" }, @@ -3436,9 +3436,9 @@ description: Variables in memory after executing router-template-slate.kcl -122.4938 ], "tag": { - "commentStart": 940, - "end": 946, - "start": 940, + "commentStart": 937, + "end": 943, + "start": 937, "type": "TagDeclarator", "value": "seg02" }, diff --git a/rust/kcl-lib/tests/kcl_samples/sheet-metal-bracket/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/sheet-metal-bracket/artifact_commands.snap index c32759dd1..4816f9016 100644 --- a/rust/kcl-lib/tests/kcl_samples/sheet-metal-bracket/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/sheet-metal-bracket/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands sheet-metal-bracket.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/socket-head-cap-screw/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/socket-head-cap-screw/artifact_commands.snap index 267e44d0c..b04405acf 100644 --- a/rust/kcl-lib/tests/kcl_samples/socket-head-cap-screw/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/socket-head-cap-screw/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands socket-head-cap-screw.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/walkie-talkie/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/walkie-talkie/artifact_commands.snap index e2eb2891c..a647e1932 100644 --- a/rust/kcl-lib/tests/kcl_samples/walkie-talkie/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/walkie-talkie/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands walkie-talkie.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kcl_samples/walkie-talkie/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/kcl_samples/walkie-talkie/artifact_graph_flowchart.snap.md index 5460744d6..5705ab3a9 100644 --- a/rust/kcl-lib/tests/kcl_samples/walkie-talkie/artifact_graph_flowchart.snap.md +++ b/rust/kcl-lib/tests/kcl_samples/walkie-talkie/artifact_graph_flowchart.snap.md @@ -1,186 +1,186 @@ ```mermaid flowchart LR subgraph path2 [Path] - 2["Path
[458, 501, 5]"] - 3["Segment
[509, 547, 5]"] - 4["Segment
[555, 595, 5]"] - 5["Segment
[603, 642, 5]"] - 6["Segment
[650, 672, 5]"] + 2["Path
[458, 501, 6]"] + 3["Segment
[509, 547, 6]"] + 4["Segment
[555, 595, 6]"] + 5["Segment
[603, 642, 6]"] + 6["Segment
[650, 672, 6]"] 7[Solid2d] end subgraph path27 [Path] - 27["Path
[1082, 1213, 5]"] - 28["Segment
[1221, 1279, 5]"] - 29["Segment
[1287, 1418, 5]"] - 30["Segment
[1426, 1484, 5]"] - 31["Segment
[1492, 1626, 5]"] - 32["Segment
[1634, 1720, 5]"] - 33["Segment
[1728, 1863, 5]"] - 34["Segment
[1871, 1956, 5]"] - 35["Segment
[1964, 1971, 5]"] + 27["Path
[1082, 1213, 6]"] + 28["Segment
[1221, 1279, 6]"] + 29["Segment
[1287, 1418, 6]"] + 30["Segment
[1426, 1484, 6]"] + 31["Segment
[1492, 1626, 6]"] + 32["Segment
[1634, 1720, 6]"] + 33["Segment
[1728, 1863, 6]"] + 34["Segment
[1871, 1956, 6]"] + 35["Segment
[1964, 1971, 6]"] 36[Solid2d] end subgraph path63 [Path] - 63["Path
[2119, 2173, 5]"] - 64["Segment
[2181, 2222, 5]"] - 65["Segment
[2230, 2259, 5]"] - 66["Segment
[2267, 2297, 5]"] - 67["Segment
[2305, 2361, 5]"] - 68["Segment
[2369, 2376, 5]"] + 63["Path
[2119, 2173, 6]"] + 64["Segment
[2181, 2222, 6]"] + 65["Segment
[2230, 2259, 6]"] + 66["Segment
[2267, 2297, 6]"] + 67["Segment
[2305, 2361, 6]"] + 68["Segment
[2369, 2376, 6]"] 69[Solid2d] end subgraph path84 [Path] - 84["Path
[2518, 2555, 5]"] - 85["Segment
[2563, 2594, 5]"] - 86["Segment
[2602, 2635, 5]"] - 87["Segment
[2643, 2675, 5]"] - 88["Segment
[2683, 2690, 5]"] + 84["Path
[2518, 2555, 6]"] + 85["Segment
[2563, 2594, 6]"] + 86["Segment
[2602, 2635, 6]"] + 87["Segment
[2643, 2675, 6]"] + 88["Segment
[2683, 2690, 6]"] 89[Solid2d] end subgraph path105 [Path] - 105["Path
[346, 371, 8]"] - 106["Segment
[379, 412, 8]"] - 107["Segment
[420, 455, 8]"] - 108["Segment
[463, 497, 8]"] - 109["Segment
[505, 512, 8]"] + 105["Path
[346, 371, 9]"] + 106["Segment
[379, 412, 9]"] + 107["Segment
[420, 455, 9]"] + 108["Segment
[463, 497, 9]"] + 109["Segment
[505, 512, 9]"] 110[Solid2d] end subgraph path112 [Path] - 112["Path
[649, 781, 8]"] + 112["Path
[649, 781, 9]"] 117[Solid2d] end subgraph path130 [Path] - 130["Path
[551, 605, 6]"] - 131["Segment
[613, 640, 6]"] - 132["Segment
[648, 677, 6]"] - 133["Segment
[685, 713, 6]"] - 134["Segment
[721, 777, 6]"] - 135["Segment
[785, 792, 6]"] + 130["Path
[551, 605, 7]"] + 131["Segment
[613, 640, 7]"] + 132["Segment
[648, 677, 7]"] + 133["Segment
[685, 713, 7]"] + 134["Segment
[721, 777, 7]"] + 135["Segment
[785, 792, 7]"] 136[Solid2d] end subgraph path138 [Path] - 138["Path
[1098, 1145, 6]"] - 139["Segment
[1153, 1194, 6]"] - 140["Segment
[1202, 1244, 6]"] - 141["Segment
[1252, 1294, 6]"] - 142["Segment
[1302, 1309, 6]"] + 138["Path
[1098, 1145, 7]"] + 139["Segment
[1153, 1194, 7]"] + 140["Segment
[1202, 1244, 7]"] + 141["Segment
[1252, 1294, 7]"] + 142["Segment
[1302, 1309, 7]"] 143[Solid2d] end subgraph path145 [Path] - 145["Path
[1597, 1762, 6]"] - 146["Segment
[1770, 1871, 6]"] - 147["Segment
[1879, 2046, 6]"] - 148["Segment
[2054, 2155, 6]"] - 149["Segment
[2163, 2333, 6]"] - 150["Segment
[2341, 2443, 6]"] - 151["Segment
[2451, 2620, 6]"] - 152["Segment
[2628, 2729, 6]"] - 153["Segment
[2737, 2744, 6]"] + 145["Path
[1597, 1762, 7]"] + 146["Segment
[1770, 1871, 7]"] + 147["Segment
[1879, 2046, 7]"] + 148["Segment
[2054, 2155, 7]"] + 149["Segment
[2163, 2333, 7]"] + 150["Segment
[2341, 2443, 7]"] + 151["Segment
[2451, 2620, 7]"] + 152["Segment
[2628, 2729, 7]"] + 153["Segment
[2737, 2744, 7]"] 154[Solid2d] end subgraph path156 [Path] - 156["Path
[123, 210, 7]"] - 157["Segment
[218, 247, 7]"] - 158["Segment
[255, 283, 7]"] - 159["Segment
[291, 388, 7]"] - 160["Segment
[396, 443, 7]"] - 161["Segment
[451, 479, 7]"] - 162["Segment
[487, 516, 7]"] - 163["Segment
[524, 553, 7]"] - 164["Segment
[561, 652, 7]"] - 165["Segment
[660, 688, 7]"] - 166["Segment
[696, 725, 7]"] - 167["Segment
[733, 821, 7]"] - 168["Segment
[829, 857, 7]"] - 169["Segment
[865, 899, 7]"] - 170["Segment
[907, 937, 7]"] - 171["Segment
[945, 1054, 7]"] - 172["Segment
[1062, 1069, 7]"] + 156["Path
[123, 210, 8]"] + 157["Segment
[218, 247, 8]"] + 158["Segment
[255, 283, 8]"] + 159["Segment
[291, 388, 8]"] + 160["Segment
[396, 443, 8]"] + 161["Segment
[451, 479, 8]"] + 162["Segment
[487, 516, 8]"] + 163["Segment
[524, 553, 8]"] + 164["Segment
[561, 652, 8]"] + 165["Segment
[660, 688, 8]"] + 166["Segment
[696, 725, 8]"] + 167["Segment
[733, 821, 8]"] + 168["Segment
[829, 857, 8]"] + 169["Segment
[865, 899, 8]"] + 170["Segment
[907, 937, 8]"] + 171["Segment
[945, 1054, 8]"] + 172["Segment
[1062, 1069, 8]"] 173[Solid2d] end subgraph path175 [Path] - 175["Path
[1203, 1301, 7]"] - 176["Segment
[1309, 1428, 7]"] - 177["Segment
[1436, 1490, 7]"] - 178["Segment
[1498, 1619, 7]"] - 179["Segment
[1627, 1634, 7]"] + 175["Path
[1203, 1301, 8]"] + 176["Segment
[1309, 1428, 8]"] + 177["Segment
[1436, 1490, 8]"] + 178["Segment
[1498, 1619, 8]"] + 179["Segment
[1627, 1634, 8]"] 180[Solid2d] end subgraph path182 [Path] - 182["Path
[1731, 1828, 7]"] - 183["Segment
[1836, 1955, 7]"] - 184["Segment
[1963, 2018, 7]"] - 185["Segment
[2026, 2147, 7]"] - 186["Segment
[2155, 2162, 7]"] + 182["Path
[1731, 1828, 8]"] + 183["Segment
[1836, 1955, 8]"] + 184["Segment
[1963, 2018, 8]"] + 185["Segment
[2026, 2147, 8]"] + 186["Segment
[2155, 2162, 8]"] 187[Solid2d] end subgraph path189 [Path] - 189["Path
[1203, 1301, 7]"] - 190["Segment
[1309, 1428, 7]"] - 191["Segment
[1436, 1490, 7]"] - 192["Segment
[1498, 1619, 7]"] - 193["Segment
[1627, 1634, 7]"] + 189["Path
[1203, 1301, 8]"] + 190["Segment
[1309, 1428, 8]"] + 191["Segment
[1436, 1490, 8]"] + 192["Segment
[1498, 1619, 8]"] + 193["Segment
[1627, 1634, 8]"] 194[Solid2d] end subgraph path196 [Path] - 196["Path
[1731, 1828, 7]"] - 197["Segment
[1836, 1955, 7]"] - 198["Segment
[1963, 2018, 7]"] - 199["Segment
[2026, 2147, 7]"] - 200["Segment
[2155, 2162, 7]"] + 196["Path
[1731, 1828, 8]"] + 197["Segment
[1836, 1955, 8]"] + 198["Segment
[1963, 2018, 8]"] + 199["Segment
[2026, 2147, 8]"] + 200["Segment
[2155, 2162, 8]"] 201[Solid2d] end subgraph path230 [Path] - 230["Path
[288, 387, 9]"] - 231["Segment
[395, 444, 9]"] - 232["Segment
[452, 502, 9]"] - 233["Segment
[510, 560, 9]"] - 234["Segment
[568, 586, 9]"] + 230["Path
[288, 387, 10]"] + 231["Segment
[395, 444, 10]"] + 232["Segment
[452, 502, 10]"] + 233["Segment
[510, 560, 10]"] + 234["Segment
[568, 586, 10]"] 235[Solid2d] end subgraph path256 [Path] - 256["Path
[377, 407, 10]"] - 257["Segment
[415, 447, 10]"] - 258["Segment
[455, 488, 10]"] - 259["Segment
[496, 585, 10]"] - 260["Segment
[593, 620, 10]"] - 261["Segment
[628, 635, 10]"] + 256["Path
[377, 407, 11]"] + 257["Segment
[415, 447, 11]"] + 258["Segment
[455, 488, 11]"] + 259["Segment
[496, 585, 11]"] + 260["Segment
[593, 620, 11]"] + 261["Segment
[628, 635, 11]"] 262[Solid2d] end subgraph path274 [Path] - 274["Path
[311, 336, 11]"] - 275["Segment
[344, 403, 11]"] - 276["Segment
[411, 471, 11]"] - 277["Segment
[479, 529, 11]"] - 278["Segment
[537, 544, 11]"] + 274["Path
[311, 336, 12]"] + 275["Segment
[344, 403, 12]"] + 276["Segment
[411, 471, 12]"] + 277["Segment
[479, 529, 12]"] + 278["Segment
[537, 544, 12]"] 279[Solid2d] end subgraph path298 [Path] - 298["Path
[311, 336, 11]"] - 299["Segment
[344, 403, 11]"] - 300["Segment
[411, 471, 11]"] - 301["Segment
[479, 529, 11]"] - 302["Segment
[537, 544, 11]"] + 298["Path
[311, 336, 12]"] + 299["Segment
[344, 403, 12]"] + 300["Segment
[411, 471, 12]"] + 301["Segment
[479, 529, 12]"] + 302["Segment
[537, 544, 12]"] 303[Solid2d] end subgraph path322 [Path] - 322["Path
[311, 336, 11]"] - 323["Segment
[344, 403, 11]"] - 324["Segment
[411, 471, 11]"] - 325["Segment
[479, 529, 11]"] - 326["Segment
[537, 544, 11]"] + 322["Path
[311, 336, 12]"] + 323["Segment
[344, 403, 12]"] + 324["Segment
[411, 471, 12]"] + 325["Segment
[479, 529, 12]"] + 326["Segment
[537, 544, 12]"] 327[Solid2d] end subgraph path346 [Path] - 346["Path
[311, 336, 11]"] - 347["Segment
[344, 403, 11]"] - 348["Segment
[411, 471, 11]"] - 349["Segment
[479, 529, 11]"] - 350["Segment
[537, 544, 11]"] + 346["Path
[311, 336, 12]"] + 347["Segment
[344, 403, 12]"] + 348["Segment
[411, 471, 12]"] + 349["Segment
[479, 529, 12]"] + 350["Segment
[537, 544, 12]"] 351[Solid2d] end - 1["Plane
[433, 450, 5]"] - 8["Sweep Extrusion
[689, 728, 5]"] + 1["Plane
[433, 450, 6]"] + 8["Sweep Extrusion
[689, 728, 6]"] 9[Wall] 10[Wall] 11[Wall] @@ -195,11 +195,11 @@ flowchart LR 20["SweepEdge Adjacent"] 21["SweepEdge Opposite"] 22["SweepEdge Adjacent"] - 23["EdgeCut Chamfer
[736, 983, 5]"] - 24["EdgeCut Chamfer
[736, 983, 5]"] - 25["EdgeCut Chamfer
[736, 983, 5]"] - 26["EdgeCut Chamfer
[736, 983, 5]"] - 37["Sweep Extrusion
[1987, 2023, 5]"] + 23["EdgeCut Chamfer
[736, 983, 6]"] + 24["EdgeCut Chamfer
[736, 983, 6]"] + 25["EdgeCut Chamfer
[736, 983, 6]"] + 26["EdgeCut Chamfer
[736, 983, 6]"] + 37["Sweep Extrusion
[1987, 2023, 6]"] 38[Wall] 39[Wall] 40[Wall] @@ -225,7 +225,7 @@ flowchart LR 60["SweepEdge Adjacent"] 61["SweepEdge Opposite"] 62["SweepEdge Adjacent"] - 70["Sweep Extrusion
[2392, 2432, 5]"] + 70["Sweep Extrusion
[2392, 2432, 6]"] 71[Wall] 72[Wall] 73[Wall] @@ -239,7 +239,7 @@ flowchart LR 81["SweepEdge Adjacent"] 82["SweepEdge Opposite"] 83["SweepEdge Adjacent"] - 90["Sweep Extrusion
[2701, 2733, 5]"] + 90["Sweep Extrusion
[2701, 2733, 6]"] 91[Wall] 92[Wall] 93[Wall] @@ -253,13 +253,13 @@ flowchart LR 101["SweepEdge Adjacent"] 102["SweepEdge Opposite"] 103["SweepEdge Adjacent"] - 104["Plane
[321, 338, 8]"] - 111["Plane
[563, 602, 8]"] + 104["Plane
[321, 338, 9]"] + 111["Plane
[563, 602, 9]"] 113["SweepEdge Opposite"] 114["SweepEdge Opposite"] 115["SweepEdge Opposite"] 116["SweepEdge Opposite"] - 118["Sweep Loft
[967, 995, 8]"] + 118["Sweep Loft
[967, 995, 9]"] 119[Wall] 120[Wall] 121[Wall] @@ -270,15 +270,15 @@ flowchart LR 126["SweepEdge Adjacent"] 127["SweepEdge Adjacent"] 128["SweepEdge Adjacent"] - 129["Plane
[525, 542, 6]"] - 137["Plane
[1072, 1089, 6]"] - 144["Plane
[1571, 1588, 6]"] - 155["Plane
[2857, 2874, 6]"] - 174["Plane
[2919, 2936, 6]"] - 181["Plane
[2983, 3000, 6]"] - 188["Plane
[3046, 3063, 6]"] - 195["Plane
[3109, 3126, 6]"] - 202["Sweep Extrusion
[3162, 3198, 6]"] + 129["Plane
[525, 542, 7]"] + 137["Plane
[1072, 1089, 7]"] + 144["Plane
[1571, 1588, 7]"] + 155["Plane
[2857, 2874, 7]"] + 174["Plane
[2919, 2936, 7]"] + 181["Plane
[2983, 3000, 7]"] + 188["Plane
[3046, 3063, 7]"] + 195["Plane
[3109, 3126, 7]"] + 202["Sweep Extrusion
[3162, 3198, 7]"] 203[Wall] 204[Wall] 205[Wall] @@ -305,8 +305,8 @@ flowchart LR 226["SweepEdge Adjacent"] 227["SweepEdge Opposite"] 228["SweepEdge Adjacent"] - 229["Plane
[263, 280, 9]"] - 236["Sweep Extrusion
[649, 701, 9]"] + 229["Plane
[263, 280, 10]"] + 236["Sweep Extrusion
[649, 701, 10]"] 237[Wall] 238[Wall] 239[Wall] @@ -321,12 +321,12 @@ flowchart LR 248["SweepEdge Adjacent"] 249["SweepEdge Opposite"] 250["SweepEdge Adjacent"] - 251["EdgeCut Fillet
[709, 931, 9]"] - 252["EdgeCut Fillet
[709, 931, 9]"] - 253["EdgeCut Fillet
[709, 931, 9]"] - 254["EdgeCut Fillet
[709, 931, 9]"] - 255["Plane
[352, 369, 10]"] - 263["Sweep Revolve
[643, 662, 10]"] + 251["EdgeCut Fillet
[709, 931, 10]"] + 252["EdgeCut Fillet
[709, 931, 10]"] + 253["EdgeCut Fillet
[709, 931, 10]"] + 254["EdgeCut Fillet
[709, 931, 10]"] + 255["Plane
[352, 369, 11]"] + 263["Sweep Revolve
[643, 662, 11]"] 264[Wall] 265[Wall] 266[Wall] @@ -336,8 +336,8 @@ flowchart LR 270["SweepEdge Adjacent"] 271["SweepEdge Adjacent"] 272["SweepEdge Adjacent"] - 273["Plane
[286, 303, 11]"] - 280["Sweep Extrusion
[563, 610, 11]"] + 273["Plane
[286, 303, 12]"] + 280["Sweep Extrusion
[563, 610, 12]"] 281[Wall] 282[Wall] 283[Wall] @@ -352,10 +352,10 @@ flowchart LR 292["SweepEdge Adjacent"] 293["SweepEdge Opposite"] 294["SweepEdge Adjacent"] - 295["EdgeCut Chamfer
[618, 764, 11]"] - 296["EdgeCut Chamfer
[618, 764, 11]"] - 297["Plane
[286, 303, 11]"] - 304["Sweep Extrusion
[563, 610, 11]"] + 295["EdgeCut Chamfer
[618, 764, 12]"] + 296["EdgeCut Chamfer
[618, 764, 12]"] + 297["Plane
[286, 303, 12]"] + 304["Sweep Extrusion
[563, 610, 12]"] 305[Wall] 306[Wall] 307[Wall] @@ -370,10 +370,10 @@ flowchart LR 316["SweepEdge Adjacent"] 317["SweepEdge Opposite"] 318["SweepEdge Adjacent"] - 319["EdgeCut Chamfer
[618, 764, 11]"] - 320["EdgeCut Chamfer
[618, 764, 11]"] - 321["Plane
[286, 303, 11]"] - 328["Sweep Extrusion
[563, 610, 11]"] + 319["EdgeCut Chamfer
[618, 764, 12]"] + 320["EdgeCut Chamfer
[618, 764, 12]"] + 321["Plane
[286, 303, 12]"] + 328["Sweep Extrusion
[563, 610, 12]"] 329[Wall] 330[Wall] 331[Wall] @@ -388,10 +388,10 @@ flowchart LR 340["SweepEdge Adjacent"] 341["SweepEdge Opposite"] 342["SweepEdge Adjacent"] - 343["EdgeCut Chamfer
[618, 764, 11]"] - 344["EdgeCut Chamfer
[618, 764, 11]"] - 345["Plane
[286, 303, 11]"] - 352["Sweep Extrusion
[563, 610, 11]"] + 343["EdgeCut Chamfer
[618, 764, 12]"] + 344["EdgeCut Chamfer
[618, 764, 12]"] + 345["Plane
[286, 303, 12]"] + 352["Sweep Extrusion
[563, 610, 12]"] 353[Wall] 354[Wall] 355[Wall] @@ -406,18 +406,18 @@ flowchart LR 364["SweepEdge Adjacent"] 365["SweepEdge Opposite"] 366["SweepEdge Adjacent"] - 367["EdgeCut Chamfer
[618, 764, 11]"] - 368["EdgeCut Chamfer
[618, 764, 11]"] - 369["StartSketchOnFace
[1041, 1074, 5]"] - 370["StartSketchOnFace
[2077, 2111, 5]"] - 371["StartSketchOnFace
[2476, 2510, 5]"] - 372["StartSketchOnFace
[1041, 1074, 5]"] - 373["StartSketchOnFace
[2077, 2111, 5]"] - 374["StartSketchOnFace
[2476, 2510, 5]"] - 375["StartSketchOnPlane
[617, 641, 8]"] - 376["StartSketchOnPlane
[511, 543, 6]"] - 377["StartSketchOnPlane
[1058, 1090, 6]"] - 378["StartSketchOnPlane
[1557, 1589, 6]"] + 367["EdgeCut Chamfer
[618, 764, 12]"] + 368["EdgeCut Chamfer
[618, 764, 12]"] + 369["StartSketchOnFace
[1041, 1074, 6]"] + 370["StartSketchOnFace
[2077, 2111, 6]"] + 371["StartSketchOnFace
[2476, 2510, 6]"] + 372["StartSketchOnFace
[1041, 1074, 6]"] + 373["StartSketchOnFace
[2077, 2111, 6]"] + 374["StartSketchOnFace
[2476, 2510, 6]"] + 375["StartSketchOnPlane
[617, 641, 9]"] + 376["StartSketchOnPlane
[511, 543, 7]"] + 377["StartSketchOnPlane
[1058, 1090, 7]"] + 378["StartSketchOnPlane
[1557, 1589, 7]"] 1 --- 2 2 --- 3 2 --- 4 diff --git a/rust/kcl-lib/tests/kcl_samples/walkie-talkie/ast.snap b/rust/kcl-lib/tests/kcl_samples/walkie-talkie/ast.snap index 426588857..f26b222a4 100644 --- a/rust/kcl-lib/tests/kcl_samples/walkie-talkie/ast.snap +++ b/rust/kcl-lib/tests/kcl_samples/walkie-talkie/ast.snap @@ -280,108 +280,25 @@ description: Result of parsing walkie-talkie.kcl "label": { "commentStart": 730, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 742, - "elements": [ - { - "commentStart": 743, - "end": 0, - "left": { - "commentStart": 743, - "end": 0, - "left": { - "argument": { - "abs_path": false, - "commentStart": 744, - "end": 0, - "name": { - "commentStart": 744, - "end": 0, - "name": "width", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "commentStart": 743, - "end": 0, - "operator": "-", - "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" - }, - "operator": "/", - "right": { - "commentStart": 752, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "operator": "+", - "right": { - "commentStart": 756, - "end": 0, - "raw": ".45", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.45, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - { + "commentStart": 734, + "end": 0, + "left": { + "commentStart": 734, + "end": 0, + "left": { "argument": { - "commentStart": 762, - "end": 0, - "raw": "0.10", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.1, - "suffix": "None" - } - }, - "commentStart": 761, - "end": 0, - "operator": "-", - "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" - }, - { - "commentStart": 768, - "end": 0, - "left": { "abs_path": false, - "commentStart": 768, + "commentStart": 735, "end": 0, "name": { - "commentStart": 768, + "commentStart": 735, "end": 0, - "name": "height", + "name": "width", "start": 0, "type": "Identifier" }, @@ -390,28 +307,122 @@ description: Result of parsing walkie-talkie.kcl "type": "Name", "type": "Name" }, - "operator": "/", - "right": { - "commentStart": 777, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, + "commentStart": 734, + "end": 0, + "operator": "-", "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" + "type": "UnaryExpression", + "type": "UnaryExpression" + }, + "operator": "/", + "right": { + "commentStart": 743, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "operator": "+", + "right": { + "commentStart": 747, + "end": 0, + "raw": ".45", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.45, + "suffix": "None" } - ], - "end": 0, + }, "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "BinaryExpression", + "type": "BinaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 752, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "argument": { + "commentStart": 757, + "end": 0, + "raw": "0.10", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.1, + "suffix": "None" + } + }, + "commentStart": 756, + "end": 0, + "operator": "-", + "start": 0, + "type": "UnaryExpression", + "type": "UnaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 763, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 767, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 767, + "end": 0, + "name": { + "commentStart": 767, + "end": 0, + "name": "height", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "/", + "right": { + "commentStart": 776, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" } } ], @@ -444,7 +455,7 @@ description: Result of parsing walkie-talkie.kcl "nonCodeNodes": { "1": [ { - "commentStart": 780, + "commentStart": 778, "end": 0, "start": 0, "type": "NonCodeNode", @@ -472,7 +483,7 @@ description: Result of parsing walkie-talkie.kcl "type": "ExpressionStatement" }, { - "commentStart": 801, + "commentStart": 799, "end": 0, "expression": { "body": [ @@ -480,10 +491,10 @@ description: Result of parsing walkie-talkie.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 801, + "commentStart": 799, "end": 0, "name": { - "commentStart": 801, + "commentStart": 799, "end": 0, "name": "case", "start": 0, @@ -493,7 +504,7 @@ description: Result of parsing walkie-talkie.kcl "start": 0, "type": "Name" }, - "commentStart": 801, + "commentStart": 799, "end": 0, "start": 0, "type": "CallExpression", @@ -504,73 +515,84 @@ description: Result of parsing walkie-talkie.kcl { "type": "LabeledArg", "label": { - "commentStart": 823, + "commentStart": 821, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 835, - "elements": [ - { - "commentStart": 836, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - }, - { - "argument": { - "commentStart": 840, - "end": 0, - "raw": "1", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 1.0, - "suffix": "None" - } - }, - "commentStart": 839, - "end": 0, - "operator": "-", - "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" - }, - { - "commentStart": 843, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - } - ], + "commentStart": 825, "end": 0, + "raw": "0", "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 828, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "argument": { + "commentStart": 833, + "end": 0, + "raw": "1", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 1.0, + "suffix": "None" + } + }, + "commentStart": 832, + "end": 0, + "operator": "-", + "start": 0, + "type": "UnaryExpression", + "type": "UnaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 836, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 840, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } } } ], "callee": { "abs_path": false, - "commentStart": 813, + "commentStart": 811, "end": 0, "name": { - "commentStart": 813, + "commentStart": 811, "end": 0, "name": "translate", "start": 0, @@ -580,7 +602,7 @@ description: Result of parsing walkie-talkie.kcl "start": 0, "type": "Name" }, - "commentStart": 813, + "commentStart": 811, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -588,13 +610,13 @@ description: Result of parsing walkie-talkie.kcl "unlabeled": null } ], - "commentStart": 801, + "commentStart": 799, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "1": [ { - "commentStart": 846, + "commentStart": 842, "end": 0, "start": 0, "type": "NonCodeNode", @@ -617,7 +639,7 @@ description: Result of parsing walkie-talkie.kcl "type": "ExpressionStatement" }, { - "commentStart": 874, + "commentStart": 870, "end": 0, "expression": { "body": [ @@ -625,10 +647,10 @@ description: Result of parsing walkie-talkie.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 874, + "commentStart": 870, "end": 0, "name": { - "commentStart": 874, + "commentStart": 870, "end": 0, "name": "talkButton", "start": 0, @@ -638,7 +660,7 @@ description: Result of parsing walkie-talkie.kcl "start": 0, "type": "Name" }, - "commentStart": 874, + "commentStart": 870, "end": 0, "start": 0, "type": "CallExpression", @@ -649,121 +671,132 @@ description: Result of parsing walkie-talkie.kcl { "type": "LabeledArg", "label": { - "commentStart": 902, + "commentStart": 898, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 914, - "elements": [ - { - "commentStart": 915, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 915, - "end": 0, - "name": { - "commentStart": 915, - "end": 0, - "name": "width", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "/", - "right": { - "commentStart": 923, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - { - "commentStart": 926, - "end": 0, - "left": { - "argument": { - "abs_path": false, - "commentStart": 927, - "end": 0, - "name": { - "commentStart": 927, - "end": 0, - "name": "thickness", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "commentStart": 926, - "end": 0, - "operator": "-", - "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" - }, - "operator": "/", - "right": { - "commentStart": 939, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - { - "commentStart": 942, - "end": 0, - "raw": ".5", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.5, - "suffix": "None" - } - } - ], + "commentStart": 902, "end": 0, + "left": { + "abs_path": false, + "commentStart": 902, + "end": 0, + "name": { + "commentStart": 902, + "end": 0, + "name": "width", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "/", + "right": { + "commentStart": 910, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "BinaryExpression", + "type": "BinaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 913, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 917, + "end": 0, + "left": { + "argument": { + "abs_path": false, + "commentStart": 918, + "end": 0, + "name": { + "commentStart": 918, + "end": 0, + "name": "thickness", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "commentStart": 917, + "end": 0, + "operator": "-", + "start": 0, + "type": "UnaryExpression", + "type": "UnaryExpression" + }, + "operator": "/", + "right": { + "commentStart": 930, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 933, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 937, + "end": 0, + "raw": ".5", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.5, + "suffix": "None" + } } } ], "callee": { "abs_path": false, - "commentStart": 892, + "commentStart": 888, "end": 0, "name": { - "commentStart": 892, + "commentStart": 888, "end": 0, "name": "translate", "start": 0, @@ -773,7 +806,7 @@ description: Result of parsing walkie-talkie.kcl "start": 0, "type": "Name" }, - "commentStart": 892, + "commentStart": 888, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -781,13 +814,13 @@ description: Result of parsing walkie-talkie.kcl "unlabeled": null } ], - "commentStart": 874, + "commentStart": 870, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "1": [ { - "commentStart": 946, + "commentStart": 940, "end": 0, "start": 0, "type": "NonCodeNode", @@ -810,7 +843,7 @@ description: Result of parsing walkie-talkie.kcl "type": "ExpressionStatement" }, { - "commentStart": 977, + "commentStart": 971, "end": 0, "expression": { "body": [ @@ -818,10 +851,10 @@ description: Result of parsing walkie-talkie.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 977, + "commentStart": 971, "end": 0, "name": { - "commentStart": 977, + "commentStart": 971, "end": 0, "name": "knob", "start": 0, @@ -831,7 +864,7 @@ description: Result of parsing walkie-talkie.kcl "start": 0, "type": "Name" }, - "commentStart": 977, + "commentStart": 971, "end": 0, "start": 0, "type": "CallExpression", @@ -842,165 +875,176 @@ description: Result of parsing walkie-talkie.kcl { "type": "LabeledArg", "label": { - "commentStart": 999, + "commentStart": 993, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1011, - "elements": [ - { + "commentStart": 997, + "end": 0, + "left": { + "commentStart": 997, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 997, + "end": 0, + "name": { + "commentStart": 997, + "end": 0, + "name": "width", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "/", + "right": { + "commentStart": 1005, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "operator": "-", + "right": { + "commentStart": 1009, + "end": 0, + "raw": "0.70", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.7, + "suffix": "None" + } + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1015, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1019, + "end": 0, + "left": { + "argument": { + "abs_path": false, "commentStart": 1020, "end": 0, - "left": { + "name": { "commentStart": 1020, "end": 0, - "left": { - "abs_path": false, - "commentStart": 1020, - "end": 0, - "name": { - "commentStart": 1020, - "end": 0, - "name": "width", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "/", - "right": { - "commentStart": 1028, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, + "name": "thickness", "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "operator": "-", - "right": { - "commentStart": 1032, - "end": 0, - "raw": "0.70", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.7, - "suffix": "None" - } + "type": "Identifier" }, + "path": [], "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" + "type": "Name", + "type": "Name" }, - { - "commentStart": 1045, - "end": 0, - "left": { - "argument": { - "abs_path": false, - "commentStart": 1046, - "end": 0, - "name": { - "commentStart": 1046, - "end": 0, - "name": "thickness", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "commentStart": 1045, - "end": 0, - "operator": "-", - "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" - }, - "operator": "/", - "right": { - "commentStart": 1058, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - { - "commentStart": 1068, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 1068, - "end": 0, - "name": { - "commentStart": 1068, - "end": 0, - "name": "height", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "/", - "right": { - "commentStart": 1077, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" + "commentStart": 1019, + "end": 0, + "operator": "-", + "start": 0, + "type": "UnaryExpression", + "type": "UnaryExpression" + }, + "operator": "/", + "right": { + "commentStart": 1032, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" } - ], - "end": 0, + }, "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "BinaryExpression", + "type": "BinaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1035, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1039, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 1039, + "end": 0, + "name": { + "commentStart": 1039, + "end": 0, + "name": "height", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "/", + "right": { + "commentStart": 1048, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" } } ], "callee": { "abs_path": false, - "commentStart": 989, + "commentStart": 983, "end": 0, "name": { - "commentStart": 989, + "commentStart": 983, "end": 0, "name": "translate", "start": 0, @@ -1010,7 +1054,7 @@ description: Result of parsing walkie-talkie.kcl "start": 0, "type": "Name" }, - "commentStart": 989, + "commentStart": 983, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1018,13 +1062,13 @@ description: Result of parsing walkie-talkie.kcl "unlabeled": null } ], - "commentStart": 977, + "commentStart": 971, "end": 0, "nonCodeMeta": { "nonCodeNodes": { "1": [ { - "commentStart": 1086, + "commentStart": 1050, "end": 0, "start": 0, "type": "NonCodeNode", @@ -1047,7 +1091,7 @@ description: Result of parsing walkie-talkie.kcl "type": "ExpressionStatement" }, { - "commentStart": 1110, + "commentStart": 1074, "end": 0, "expression": { "body": [ @@ -1055,10 +1099,10 @@ description: Result of parsing walkie-talkie.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 1110, + "commentStart": 1074, "end": 0, "name": { - "commentStart": 1110, + "commentStart": 1074, "end": 0, "name": "button", "start": 0, @@ -1068,7 +1112,7 @@ description: Result of parsing walkie-talkie.kcl "start": 0, "type": "Name" }, - "commentStart": 1110, + "commentStart": 1074, "end": 0, "start": 0, "type": "CallExpression", @@ -1079,109 +1123,330 @@ description: Result of parsing walkie-talkie.kcl { "type": "LabeledArg", "label": { - "commentStart": 1134, + "commentStart": 1098, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1146, - "elements": [ - { - "argument": { - "commentStart": 1157, - "end": 0, - "left": { - "commentStart": 1157, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 1157, - "end": 0, - "name": { - "commentStart": 1157, - "end": 0, - "name": "screenWidth", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "/", - "right": { - "commentStart": 1171, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "operator": "+", - "right": { - "abs_path": false, - "commentStart": 1175, - "end": 0, - "name": { - "commentStart": 1175, - "end": 0, - "name": "tolerance", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "commentStart": 1155, + "argument": { + "commentStart": 1104, + "end": 0, + "left": { + "commentStart": 1104, "end": 0, - "operator": "-", - "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" - }, - { - "argument": { - "commentStart": 1195, + "left": { + "abs_path": false, + "commentStart": 1104, "end": 0, - "raw": "1", + "name": { + "commentStart": 1104, + "end": 0, + "name": "screenWidth", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "/", + "right": { + "commentStart": 1118, + "end": 0, + "raw": "2", "start": 0, "type": "Literal", "type": "Literal", "value": { - "value": 1.0, + "value": 2.0, "suffix": "None" } }, - "commentStart": 1194, - "end": 0, - "operator": "-", "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" + "type": "BinaryExpression", + "type": "BinaryExpression" }, - { + "operator": "+", + "right": { "abs_path": false, - "commentStart": 1205, + "commentStart": 1122, "end": 0, "name": { - "commentStart": 1205, + "commentStart": 1122, + "end": 0, + "name": "tolerance", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "commentStart": 1102, + "end": 0, + "operator": "-", + "start": 0, + "type": "UnaryExpression", + "type": "UnaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1134, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "argument": { + "commentStart": 1139, + "end": 0, + "raw": "1", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 1.0, + "suffix": "None" + } + }, + "commentStart": 1138, + "end": 0, + "operator": "-", + "start": 0, + "type": "UnaryExpression", + "type": "UnaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1142, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "abs_path": false, + "commentStart": 1146, + "end": 0, + "name": { + "commentStart": 1146, + "end": 0, + "name": "screenYPosition", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + } + } + ], + "callee": { + "abs_path": false, + "commentStart": 1088, + "end": 0, + "name": { + "commentStart": 1088, + "end": 0, + "name": "translate", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name" + }, + "commentStart": 1088, + "end": 0, + "start": 0, + "type": "CallExpressionKw", + "type": "CallExpressionKw", + "unlabeled": null + } + ], + "commentStart": 1074, + "end": 0, + "start": 0, + "type": "PipeExpression", + "type": "PipeExpression" + }, + "start": 0, + "type": "ExpressionStatement", + "type": "ExpressionStatement" + }, + { + "commentStart": 1163, + "end": 0, + "expression": { + "body": [ + { + "arguments": [], + "callee": { + "abs_path": false, + "commentStart": 1163, + "end": 0, + "name": { + "commentStart": 1163, + "end": 0, + "name": "button", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name" + }, + "commentStart": 1163, + "end": 0, + "start": 0, + "type": "CallExpression", + "type": "CallExpression" + }, + { + "arguments": [ + { + "type": "LabeledArg", + "label": { + "commentStart": 1187, + "end": 0, + "name": "x", + "start": 0, + "type": "Identifier" + }, + "arg": { + "argument": { + "commentStart": 1193, + "end": 0, + "left": { + "commentStart": 1193, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 1193, + "end": 0, + "name": { + "commentStart": 1193, + "end": 0, + "name": "screenWidth", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "/", + "right": { + "commentStart": 1207, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "operator": "+", + "right": { + "abs_path": false, + "commentStart": 1211, + "end": 0, + "name": { + "commentStart": 1211, + "end": 0, + "name": "tolerance", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "commentStart": 1191, + "end": 0, + "operator": "-", + "start": 0, + "type": "UnaryExpression", + "type": "UnaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1223, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "argument": { + "commentStart": 1228, + "end": 0, + "raw": "1", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 1.0, + "suffix": "None" + } + }, + "commentStart": 1227, + "end": 0, + "operator": "-", + "start": 0, + "type": "UnaryExpression", + "type": "UnaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1231, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1235, + "end": 0, + "left": { + "commentStart": 1235, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 1235, + "end": 0, + "name": { + "commentStart": 1235, "end": 0, "name": "screenYPosition", "start": 0, @@ -1191,21 +1456,77 @@ description: Result of parsing walkie-talkie.kcl "start": 0, "type": "Name", "type": "Name" - } - ], - "end": 0, + }, + "operator": "-", + "right": { + "abs_path": false, + "commentStart": 1253, + "end": 0, + "name": { + "commentStart": 1253, + "end": 0, + "name": "buttonHeight", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "operator": "-", + "right": { + "commentStart": 1269, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 1269, + "end": 0, + "name": { + "commentStart": 1269, + "end": 0, + "name": "tolerance", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "*", + "right": { + "commentStart": 1281, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "BinaryExpression", + "type": "BinaryExpression" } } ], "callee": { "abs_path": false, - "commentStart": 1124, + "commentStart": 1177, "end": 0, "name": { - "commentStart": 1124, + "commentStart": 1177, "end": 0, "name": "translate", "start": 0, @@ -1215,7 +1536,7 @@ description: Result of parsing walkie-talkie.kcl "start": 0, "type": "Name" }, - "commentStart": 1124, + "commentStart": 1177, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -1223,7 +1544,7 @@ description: Result of parsing walkie-talkie.kcl "unlabeled": null } ], - "commentStart": 1110, + "commentStart": 1163, "end": 0, "start": 0, "type": "PipeExpression", @@ -1234,7 +1555,7 @@ description: Result of parsing walkie-talkie.kcl "type": "ExpressionStatement" }, { - "commentStart": 1229, + "commentStart": 1285, "end": 0, "expression": { "body": [ @@ -1242,10 +1563,10 @@ description: Result of parsing walkie-talkie.kcl "arguments": [], "callee": { "abs_path": false, - "commentStart": 1229, + "commentStart": 1285, "end": 0, "name": { - "commentStart": 1229, + "commentStart": 1285, "end": 0, "name": "button", "start": 0, @@ -1255,7 +1576,7 @@ description: Result of parsing walkie-talkie.kcl "start": 0, "type": "Name" }, - "commentStart": 1229, + "commentStart": 1285, "end": 0, "start": 0, "type": "CallExpression", @@ -1266,269 +1587,14 @@ description: Result of parsing walkie-talkie.kcl { "type": "LabeledArg", "label": { - "commentStart": 1253, - "end": 0, - "name": "translate", - "start": 0, - "type": "Identifier" - }, - "arg": { - "commentStart": 1265, - "elements": [ - { - "argument": { - "commentStart": 1276, - "end": 0, - "left": { - "commentStart": 1276, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 1276, - "end": 0, - "name": { - "commentStart": 1276, - "end": 0, - "name": "screenWidth", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "/", - "right": { - "commentStart": 1290, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "operator": "+", - "right": { - "abs_path": false, - "commentStart": 1294, - "end": 0, - "name": { - "commentStart": 1294, - "end": 0, - "name": "tolerance", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "commentStart": 1274, - "end": 0, - "operator": "-", - "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" - }, - { - "argument": { - "commentStart": 1314, - "end": 0, - "raw": "1", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 1.0, - "suffix": "None" - } - }, - "commentStart": 1313, - "end": 0, - "operator": "-", - "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" - }, - { - "commentStart": 1324, - "end": 0, - "left": { - "commentStart": 1324, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 1324, - "end": 0, - "name": { - "commentStart": 1324, - "end": 0, - "name": "screenYPosition", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "-", - "right": { - "abs_path": false, - "commentStart": 1342, - "end": 0, - "name": { - "commentStart": 1342, - "end": 0, - "name": "buttonHeight", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "operator": "-", - "right": { - "commentStart": 1358, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 1358, - "end": 0, - "name": { - "commentStart": 1358, - "end": 0, - "name": "tolerance", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "*", - "right": { - "commentStart": 1370, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - } - ], - "end": 0, - "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" - } - } - ], - "callee": { - "abs_path": false, - "commentStart": 1243, - "end": 0, - "name": { - "commentStart": 1243, - "end": 0, - "name": "translate", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name" - }, - "commentStart": 1243, - "end": 0, - "start": 0, - "type": "CallExpressionKw", - "type": "CallExpressionKw", - "unlabeled": null - } - ], - "commentStart": 1229, - "end": 0, - "start": 0, - "type": "PipeExpression", - "type": "PipeExpression" - }, - "start": 0, - "type": "ExpressionStatement", - "type": "ExpressionStatement" - }, - { - "commentStart": 1381, - "end": 0, - "expression": { - "body": [ - { - "arguments": [], - "callee": { - "abs_path": false, - "commentStart": 1381, - "end": 0, - "name": { - "commentStart": 1381, - "end": 0, - "name": "button", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name" - }, - "commentStart": 1381, - "end": 0, - "start": 0, - "type": "CallExpression", - "type": "CallExpression" - }, - { - "arguments": [ - { - "type": "LabeledArg", - "label": { - "commentStart": 1420, + "commentStart": 1324, "end": 0, "name": "roll", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1427, + "commentStart": 1331, "end": 0, "raw": "0", "start": 0, @@ -1543,14 +1609,14 @@ description: Result of parsing walkie-talkie.kcl { "type": "LabeledArg", "label": { - "commentStart": 1437, + "commentStart": 1341, "end": 0, "name": "pitch", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1445, + "commentStart": 1349, "end": 0, "raw": "180", "start": 0, @@ -1565,14 +1631,14 @@ description: Result of parsing walkie-talkie.kcl { "type": "LabeledArg", "label": { - "commentStart": 1457, + "commentStart": 1361, "end": 0, "name": "yaw", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1463, + "commentStart": 1367, "end": 0, "raw": "0", "start": 0, @@ -1587,10 +1653,10 @@ description: Result of parsing walkie-talkie.kcl ], "callee": { "abs_path": false, - "commentStart": 1395, + "commentStart": 1299, "end": 0, "name": { - "commentStart": 1395, + "commentStart": 1299, "end": 0, "name": "rotate", "start": 0, @@ -1600,13 +1666,13 @@ description: Result of parsing walkie-talkie.kcl "start": 0, "type": "Name" }, - "commentStart": 1395, + "commentStart": 1299, "end": 0, "start": 0, "type": "CallExpressionKw", "type": "CallExpressionKw", "unlabeled": { - "commentStart": 1410, + "commentStart": 1314, "end": 0, "start": 0, "type": "PipeSubstitution", @@ -1618,121 +1684,474 @@ description: Result of parsing walkie-talkie.kcl { "type": "LabeledArg", "label": { - "commentStart": 1496, + "commentStart": 1400, "end": 0, - "name": "translate", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1508, - "elements": [ - { - "commentStart": 1519, + "commentStart": 1404, + "end": 0, + "left": { + "commentStart": 1404, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 1404, "end": 0, - "left": { - "commentStart": 1519, + "name": { + "commentStart": 1404, "end": 0, - "left": { - "abs_path": false, - "commentStart": 1519, - "end": 0, - "name": { - "commentStart": 1519, - "end": 0, - "name": "screenWidth", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "/", - "right": { - "commentStart": 1533, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, + "name": "screenWidth", "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "operator": "+", - "right": { - "abs_path": false, - "commentStart": 1537, - "end": 0, - "name": { - "commentStart": 1537, - "end": 0, - "name": "tolerance", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" + "type": "Identifier" }, + "path": [], "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" + "type": "Name", + "type": "Name" }, - { - "argument": { - "commentStart": 1558, - "end": 0, - "raw": "1", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 1.0, - "suffix": "None" - } - }, - "commentStart": 1557, + "operator": "/", + "right": { + "commentStart": 1418, "end": 0, - "operator": "-", + "raw": "2", "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } }, - { - "commentStart": 1570, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "operator": "+", + "right": { + "abs_path": false, + "commentStart": 1422, + "end": 0, + "name": { + "commentStart": 1422, + "end": 0, + "name": "tolerance", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1440, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "argument": { + "commentStart": 1445, + "end": 0, + "raw": "1", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 1.0, + "suffix": "None" + } + }, + "commentStart": 1444, + "end": 0, + "operator": "-", + "start": 0, + "type": "UnaryExpression", + "type": "UnaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1455, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1459, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 1459, + "end": 0, + "name": { + "commentStart": 1459, + "end": 0, + "name": "screenYPosition", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "-", + "right": { + "abs_path": false, + "commentStart": 1477, + "end": 0, + "name": { + "commentStart": 1477, + "end": 0, + "name": "buttonHeight", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1498, + "end": 0, + "name": "global", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1507, + "end": 0, + "raw": "true", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": true + } + } + ], + "callee": { + "abs_path": false, + "commentStart": 1382, + "end": 0, + "name": { + "commentStart": 1382, + "end": 0, + "name": "translate", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name" + }, + "commentStart": 1382, + "end": 0, + "start": 0, + "type": "CallExpressionKw", + "type": "CallExpressionKw", + "unlabeled": null + } + ], + "commentStart": 1285, + "end": 0, + "start": 0, + "type": "PipeExpression", + "type": "PipeExpression" + }, + "start": 0, + "type": "ExpressionStatement", + "type": "ExpressionStatement" + }, + { + "commentStart": 1520, + "end": 0, + "expression": { + "body": [ + { + "arguments": [], + "callee": { + "abs_path": false, + "commentStart": 1520, + "end": 0, + "name": { + "commentStart": 1520, + "end": 0, + "name": "button", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name" + }, + "commentStart": 1520, + "end": 0, + "start": 0, + "type": "CallExpression", + "type": "CallExpression" + }, + { + "arguments": [ + { + "type": "LabeledArg", + "label": { + "commentStart": 1559, + "end": 0, + "name": "roll", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1566, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1576, + "end": 0, + "name": "pitch", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1584, + "end": 0, + "raw": "180", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 180.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1596, + "end": 0, + "name": "yaw", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1602, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + } + ], + "callee": { + "abs_path": false, + "commentStart": 1534, + "end": 0, + "name": { + "commentStart": 1534, + "end": 0, + "name": "rotate", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name" + }, + "commentStart": 1534, + "end": 0, + "start": 0, + "type": "CallExpressionKw", + "type": "CallExpressionKw", + "unlabeled": { + "commentStart": 1549, + "end": 0, + "start": 0, + "type": "PipeSubstitution", + "type": "PipeSubstitution" + } + }, + { + "arguments": [ + { + "type": "LabeledArg", + "label": { + "commentStart": 1635, + "end": 0, + "name": "x", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1639, + "end": 0, + "left": { + "commentStart": 1639, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 1639, + "end": 0, + "name": { + "commentStart": 1639, + "end": 0, + "name": "screenWidth", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "/", + "right": { + "commentStart": 1653, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "operator": "+", + "right": { + "abs_path": false, + "commentStart": 1657, + "end": 0, + "name": { + "commentStart": 1657, + "end": 0, + "name": "tolerance", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1675, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "argument": { + "commentStart": 1680, + "end": 0, + "raw": "1", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 1.0, + "suffix": "None" + } + }, + "commentStart": 1679, + "end": 0, + "operator": "-", + "start": 0, + "type": "UnaryExpression", + "type": "UnaryExpression" + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1690, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1694, + "end": 0, + "left": { + "commentStart": 1694, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 1694, + "end": 0, + "name": { + "commentStart": 1694, + "end": 0, + "name": "screenYPosition", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "-", + "right": { + "commentStart": 1713, "end": 0, "left": { "abs_path": false, - "commentStart": 1570, + "commentStart": 1713, "end": 0, "name": { - "commentStart": 1570, - "end": 0, - "name": "screenYPosition", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "-", - "right": { - "abs_path": false, - "commentStart": 1588, - "end": 0, - "name": { - "commentStart": 1588, + "commentStart": 1713, "end": 0, "name": "buttonHeight", "start": 0, @@ -1743,411 +2162,80 @@ description: Result of parsing walkie-talkie.kcl "type": "Name", "type": "Name" }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - } - ], - "end": 0, - "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" - } - }, - { - "type": "LabeledArg", - "label": { - "commentStart": 1618, - "end": 0, - "name": "global", - "start": 0, - "type": "Identifier" - }, - "arg": { - "commentStart": 1627, - "end": 0, - "raw": "true", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": true - } - } - ], - "callee": { - "abs_path": false, - "commentStart": 1478, - "end": 0, - "name": { - "commentStart": 1478, - "end": 0, - "name": "translate", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name" - }, - "commentStart": 1478, - "end": 0, - "start": 0, - "type": "CallExpressionKw", - "type": "CallExpressionKw", - "unlabeled": null - } - ], - "commentStart": 1381, - "end": 0, - "start": 0, - "type": "PipeExpression", - "type": "PipeExpression" - }, - "start": 0, - "type": "ExpressionStatement", - "type": "ExpressionStatement" - }, - { - "commentStart": 1640, - "end": 0, - "expression": { - "body": [ - { - "arguments": [], - "callee": { - "abs_path": false, - "commentStart": 1640, - "end": 0, - "name": { - "commentStart": 1640, - "end": 0, - "name": "button", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name" - }, - "commentStart": 1640, - "end": 0, - "start": 0, - "type": "CallExpression", - "type": "CallExpression" - }, - { - "arguments": [ - { - "type": "LabeledArg", - "label": { - "commentStart": 1679, - "end": 0, - "name": "roll", - "start": 0, - "type": "Identifier" - }, - "arg": { - "commentStart": 1686, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - } - }, - { - "type": "LabeledArg", - "label": { - "commentStart": 1696, - "end": 0, - "name": "pitch", - "start": 0, - "type": "Identifier" - }, - "arg": { - "commentStart": 1704, - "end": 0, - "raw": "180", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 180.0, - "suffix": "None" - } - } - }, - { - "type": "LabeledArg", - "label": { - "commentStart": 1716, - "end": 0, - "name": "yaw", - "start": 0, - "type": "Identifier" - }, - "arg": { - "commentStart": 1722, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - } - } - ], - "callee": { - "abs_path": false, - "commentStart": 1654, - "end": 0, - "name": { - "commentStart": 1654, - "end": 0, - "name": "rotate", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name" - }, - "commentStart": 1654, - "end": 0, - "start": 0, - "type": "CallExpressionKw", - "type": "CallExpressionKw", - "unlabeled": { - "commentStart": 1669, - "end": 0, - "start": 0, - "type": "PipeSubstitution", - "type": "PipeSubstitution" - } - }, - { - "arguments": [ - { - "type": "LabeledArg", - "label": { - "commentStart": 1755, - "end": 0, - "name": "translate", - "start": 0, - "type": "Identifier" - }, - "arg": { - "commentStart": 1767, - "elements": [ - { - "commentStart": 1778, - "end": 0, - "left": { - "commentStart": 1778, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 1778, - "end": 0, - "name": { - "commentStart": 1778, - "end": 0, - "name": "screenWidth", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "/", - "right": { - "commentStart": 1792, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "operator": "+", + "operator": "*", "right": { - "abs_path": false, - "commentStart": 1796, + "commentStart": 1728, "end": 0, - "name": { - "commentStart": 1796, - "end": 0, - "name": "tolerance", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - { - "argument": { - "commentStart": 1817, - "end": 0, - "raw": "1", + "raw": "2", "start": 0, "type": "Literal", "type": "Literal", "value": { - "value": 1.0, + "value": 2.0, "suffix": "None" } }, - "commentStart": 1816, - "end": 0, - "operator": "-", - "start": 0, - "type": "UnaryExpression", - "type": "UnaryExpression" - }, - { - "commentStart": 1829, - "end": 0, - "left": { - "commentStart": 1829, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 1829, - "end": 0, - "name": { - "commentStart": 1829, - "end": 0, - "name": "screenYPosition", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "-", - "right": { - "commentStart": 1848, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 1848, - "end": 0, - "name": { - "commentStart": 1848, - "end": 0, - "name": "buttonHeight", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "*", - "right": { - "commentStart": 1863, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, - "operator": "-", - "right": { - "commentStart": 1869, - "end": 0, - "left": { - "abs_path": false, - "commentStart": 1869, - "end": 0, - "name": { - "commentStart": 1869, - "end": 0, - "name": "tolerance", - "start": 0, - "type": "Identifier" - }, - "path": [], - "start": 0, - "type": "Name", - "type": "Name" - }, - "operator": "*", - "right": { - "commentStart": 1881, - "end": 0, - "raw": "2", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 2.0, - "suffix": "None" - } - }, - "start": 0, - "type": "BinaryExpression", - "type": "BinaryExpression" - }, "start": 0, "type": "BinaryExpression", "type": "BinaryExpression" - } - ], - "end": 0, + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "operator": "-", + "right": { + "commentStart": 1734, + "end": 0, + "left": { + "abs_path": false, + "commentStart": 1734, + "end": 0, + "name": { + "commentStart": 1734, + "end": 0, + "name": "tolerance", + "start": 0, + "type": "Identifier" + }, + "path": [], + "start": 0, + "type": "Name", + "type": "Name" + }, + "operator": "*", + "right": { + "commentStart": 1746, + "end": 0, + "raw": "2", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, + "start": 0, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "BinaryExpression", + "type": "BinaryExpression" } }, { "type": "LabeledArg", "label": { - "commentStart": 1901, + "commentStart": 1757, "end": 0, "name": "global", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1910, + "commentStart": 1766, "end": 0, "raw": "true", "start": 0, @@ -2159,10 +2247,10 @@ description: Result of parsing walkie-talkie.kcl ], "callee": { "abs_path": false, - "commentStart": 1737, + "commentStart": 1617, "end": 0, "name": { - "commentStart": 1737, + "commentStart": 1617, "end": 0, "name": "translate", "start": 0, @@ -2172,7 +2260,7 @@ description: Result of parsing walkie-talkie.kcl "start": 0, "type": "Name" }, - "commentStart": 1737, + "commentStart": 1617, "end": 0, "start": 0, "type": "CallExpressionKw", @@ -2180,7 +2268,7 @@ description: Result of parsing walkie-talkie.kcl "unlabeled": null } ], - "commentStart": 1640, + "commentStart": 1520, "end": 0, "start": 0, "type": "PipeExpression", diff --git a/rust/kcl-lib/tests/kcl_samples/walkie-talkie/ops.snap b/rust/kcl-lib/tests/kcl_samples/walkie-talkie/ops.snap index d420379e4..959b9886b 100644 --- a/rust/kcl-lib/tests/kcl_samples/walkie-talkie/ops.snap +++ b/rust/kcl-lib/tests/kcl_samples/walkie-talkie/ops.snap @@ -9,7 +9,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 359, 2786, - 5 + 6 ], "unlabeledArg": null, "labeledArgs": {}, @@ -355,7 +355,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 359, 2786, - 5 + 6 ], "unlabeledArg": null, "labeledArgs": {}, @@ -701,7 +701,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 266, 1051, - 8 + 9 ], "unlabeledArg": null, "labeledArgs": {}, @@ -804,7 +804,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 454, 3283, - 6 + 7 ], "unlabeledArg": null, "labeledArgs": {}, @@ -1890,7 +1890,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 69, 1088, - 7 + 8 ], "unlabeledArg": null, "labeledArgs": {}, @@ -1946,7 +1946,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 1146, 1656, - 7 + 8 ], "unlabeledArg": null, "labeledArgs": {}, @@ -2002,7 +2002,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 1674, 2184, - 7 + 8 ], "unlabeledArg": null, "labeledArgs": {}, @@ -2058,7 +2058,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 1146, 1656, - 7 + 8 ], "unlabeledArg": null, "labeledArgs": {}, @@ -2114,7 +2114,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 1674, 2184, - 7 + 8 ], "unlabeledArg": null, "labeledArgs": {}, @@ -2190,7 +2190,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 202, 1023, - 9 + 10 ], "unlabeledArg": null, "labeledArgs": {}, @@ -2308,7 +2308,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 298, 748, - 10 + 11 ], "unlabeledArg": null, "labeledArgs": {}, @@ -2361,7 +2361,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 221, 827, - 11 + 12 ], "unlabeledArg": null, "labeledArgs": {}, @@ -2471,7 +2471,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 221, 827, - 11 + 12 ], "unlabeledArg": null, "labeledArgs": {}, @@ -2581,7 +2581,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 221, 827, - 11 + 12 ], "unlabeledArg": null, "labeledArgs": {}, @@ -2691,7 +2691,7 @@ description: Operations executed walkie-talkie.kcl "functionSourceRange": [ 221, 827, - 11 + 12 ], "unlabeledArg": null, "labeledArgs": {}, diff --git a/rust/kcl-lib/tests/kcl_samples/washer/artifact_commands.snap b/rust/kcl-lib/tests/kcl_samples/washer/artifact_commands.snap index 8b83f2e68..6e405f5a6 100644 --- a/rust/kcl-lib/tests/kcl_samples/washer/artifact_commands.snap +++ b/rust/kcl-lib/tests/kcl_samples/washer/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands washer.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kittycad_svg/artifact_commands.snap b/rust/kcl-lib/tests/kittycad_svg/artifact_commands.snap index 775f58ba4..2f0884759 100644 --- a/rust/kcl-lib/tests/kittycad_svg/artifact_commands.snap +++ b/rust/kcl-lib/tests/kittycad_svg/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands kittycad_svg.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kw_fn/artifact_commands.snap b/rust/kcl-lib/tests/kw_fn/artifact_commands.snap index 544a4f7d4..6bbd1fc4e 100644 --- a/rust/kcl-lib/tests/kw_fn/artifact_commands.snap +++ b/rust/kcl-lib/tests/kw_fn/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands kw_fn.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kw_fn_too_few_args/artifact_commands.snap b/rust/kcl-lib/tests/kw_fn_too_few_args/artifact_commands.snap index 8cf5dfd3e..1b849e3cc 100644 --- a/rust/kcl-lib/tests/kw_fn_too_few_args/artifact_commands.snap +++ b/rust/kcl-lib/tests/kw_fn_too_few_args/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands kw_fn_too_few_args.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kw_fn_unlabeled_but_has_label/artifact_commands.snap b/rust/kcl-lib/tests/kw_fn_unlabeled_but_has_label/artifact_commands.snap index a3ee9277d..7f52f6ee2 100644 --- a/rust/kcl-lib/tests/kw_fn_unlabeled_but_has_label/artifact_commands.snap +++ b/rust/kcl-lib/tests/kw_fn_unlabeled_but_has_label/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands kw_fn_unlabeled_but_has_label.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/kw_fn_with_defaults/artifact_commands.snap b/rust/kcl-lib/tests/kw_fn_with_defaults/artifact_commands.snap index 56a2d58c2..e604be4b8 100644 --- a/rust/kcl-lib/tests/kw_fn_with_defaults/artifact_commands.snap +++ b/rust/kcl-lib/tests/kw_fn_with_defaults/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands kw_fn_with_defaults.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/linear_pattern3d_a_pattern/artifact_commands.snap b/rust/kcl-lib/tests/linear_pattern3d_a_pattern/artifact_commands.snap index 572908ee2..071dc3c37 100644 --- a/rust/kcl-lib/tests/linear_pattern3d_a_pattern/artifact_commands.snap +++ b/rust/kcl-lib/tests/linear_pattern3d_a_pattern/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands linear_pattern3d_a_pattern.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/mike_stress_test/artifact_commands.snap b/rust/kcl-lib/tests/mike_stress_test/artifact_commands.snap index b6bd6ccc9..75ae6551f 100644 --- a/rust/kcl-lib/tests/mike_stress_test/artifact_commands.snap +++ b/rust/kcl-lib/tests/mike_stress_test/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands mike_stress_test.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/multi_transform/artifact_commands.snap b/rust/kcl-lib/tests/multi_transform/artifact_commands.snap index d1d0c82c0..a42d8a434 100644 --- a/rust/kcl-lib/tests/multi_transform/artifact_commands.snap +++ b/rust/kcl-lib/tests/multi_transform/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands multi_transform.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/neg_xz_plane/artifact_commands.snap b/rust/kcl-lib/tests/neg_xz_plane/artifact_commands.snap index a803f20d2..f76b9f0d4 100644 --- a/rust/kcl-lib/tests/neg_xz_plane/artifact_commands.snap +++ b/rust/kcl-lib/tests/neg_xz_plane/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands neg_xz_plane.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/non_string_key_of_object/artifact_commands.snap b/rust/kcl-lib/tests/non_string_key_of_object/artifact_commands.snap index 2e9335f3c..346495b20 100644 --- a/rust/kcl-lib/tests/non_string_key_of_object/artifact_commands.snap +++ b/rust/kcl-lib/tests/non_string_key_of_object/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands non_string_key_of_object.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/object_prop_not_found/artifact_commands.snap b/rust/kcl-lib/tests/object_prop_not_found/artifact_commands.snap index 2f4ee8596..1425055e3 100644 --- a/rust/kcl-lib/tests/object_prop_not_found/artifact_commands.snap +++ b/rust/kcl-lib/tests/object_prop_not_found/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands object_prop_not_found.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/out_of_band_sketches/artifact_commands.snap b/rust/kcl-lib/tests/out_of_band_sketches/artifact_commands.snap index c1f5ba1f1..f73f2f84a 100644 --- a/rust/kcl-lib/tests/out_of_band_sketches/artifact_commands.snap +++ b/rust/kcl-lib/tests/out_of_band_sketches/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands out_of_band_sketches.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/parametric/artifact_commands.snap b/rust/kcl-lib/tests/parametric/artifact_commands.snap index fbd4dfa29..964e9c8ad 100644 --- a/rust/kcl-lib/tests/parametric/artifact_commands.snap +++ b/rust/kcl-lib/tests/parametric/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands parametric.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/parametric_with_tan_arc/artifact_commands.snap b/rust/kcl-lib/tests/parametric_with_tan_arc/artifact_commands.snap index 4f4b60860..f7be42358 100644 --- a/rust/kcl-lib/tests/parametric_with_tan_arc/artifact_commands.snap +++ b/rust/kcl-lib/tests/parametric_with_tan_arc/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands parametric_with_tan_arc.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/pentagon_fillet_sugar/artifact_commands.snap b/rust/kcl-lib/tests/pentagon_fillet_sugar/artifact_commands.snap index f12fd872d..add89aa8d 100644 --- a/rust/kcl-lib/tests/pentagon_fillet_sugar/artifact_commands.snap +++ b/rust/kcl-lib/tests/pentagon_fillet_sugar/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands pentagon_fillet_sugar.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/pipe_as_arg/artifact_commands.snap b/rust/kcl-lib/tests/pipe_as_arg/artifact_commands.snap index 9b89cbb3f..9b440bdd0 100644 --- a/rust/kcl-lib/tests/pipe_as_arg/artifact_commands.snap +++ b/rust/kcl-lib/tests/pipe_as_arg/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands pipe_as_arg.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/pipe_substitution_inside_function_called_from_pipeline/artifact_commands.snap b/rust/kcl-lib/tests/pipe_substitution_inside_function_called_from_pipeline/artifact_commands.snap index 84d21eecd..8ab594fcb 100644 --- a/rust/kcl-lib/tests/pipe_substitution_inside_function_called_from_pipeline/artifact_commands.snap +++ b/rust/kcl-lib/tests/pipe_substitution_inside_function_called_from_pipeline/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands pipe_substitution_inside_function_called_from_pip "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/poop_chute/artifact_commands.snap b/rust/kcl-lib/tests/poop_chute/artifact_commands.snap index 37a8f580d..020bc0418 100644 --- a/rust/kcl-lib/tests/poop_chute/artifact_commands.snap +++ b/rust/kcl-lib/tests/poop_chute/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands poop_chute.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/property_of_object/artifact_commands.snap b/rust/kcl-lib/tests/property_of_object/artifact_commands.snap index fbe3e57a0..513d26c0b 100644 --- a/rust/kcl-lib/tests/property_of_object/artifact_commands.snap +++ b/rust/kcl-lib/tests/property_of_object/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands property_of_object.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/revolve_about_edge/artifact_commands.snap b/rust/kcl-lib/tests/revolve_about_edge/artifact_commands.snap index d6cb74271..e5d3120b8 100644 --- a/rust/kcl-lib/tests/revolve_about_edge/artifact_commands.snap +++ b/rust/kcl-lib/tests/revolve_about_edge/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands revolve_about_edge.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/riddle_small/artifact_commands.snap b/rust/kcl-lib/tests/riddle_small/artifact_commands.snap index 5fdc8f6c9..222b2b5f7 100644 --- a/rust/kcl-lib/tests/riddle_small/artifact_commands.snap +++ b/rust/kcl-lib/tests/riddle_small/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands riddle_small.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/rotate_after_fillet/artifact_commands.snap b/rust/kcl-lib/tests/rotate_after_fillet/artifact_commands.snap index a94b0be47..8c18be435 100644 --- a/rust/kcl-lib/tests/rotate_after_fillet/artifact_commands.snap +++ b/rust/kcl-lib/tests/rotate_after_fillet/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands rotate_after_fillet.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/scale_after_fillet/artifact_commands.snap b/rust/kcl-lib/tests/scale_after_fillet/artifact_commands.snap index 5d911b59c..6e1139869 100644 --- a/rust/kcl-lib/tests/scale_after_fillet/artifact_commands.snap +++ b/rust/kcl-lib/tests/scale_after_fillet/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands scale_after_fillet.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/scale_after_fillet/ast.snap b/rust/kcl-lib/tests/scale_after_fillet/ast.snap index ceb4fd731..61ed95ce4 100644 --- a/rust/kcl-lib/tests/scale_after_fillet/ast.snap +++ b/rust/kcl-lib/tests/scale_after_fillet/ast.snap @@ -2097,54 +2097,65 @@ description: Result of parsing scale_after_fillet.kcl "label": { "commentStart": 1593, "end": 0, - "name": "scale", + "name": "x", "start": 0, "type": "Identifier" }, "arg": { - "commentStart": 1601, - "elements": [ - { - "commentStart": 1602, - "end": 0, - "raw": "3.14", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 3.14, - "suffix": "None" - } - }, - { - "commentStart": 1608, - "end": 0, - "raw": "3.14", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 3.14, - "suffix": "None" - } - }, - { - "commentStart": 1614, - "end": 0, - "raw": "3.14", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 3.14, - "suffix": "None" - } - } - ], + "commentStart": 1597, "end": 0, + "raw": "3.14", "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "Literal", + "type": "Literal", + "value": { + "value": 3.14, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1603, + "end": 0, + "name": "y", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1607, + "end": 0, + "raw": "3.14", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 3.14, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1613, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1617, + "end": 0, + "raw": "3.14", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 3.14, + "suffix": "None" + } } } ], @@ -2177,7 +2188,7 @@ description: Result of parsing scale_after_fillet.kcl "nonCodeNodes": { "1": [ { - "commentStart": 1620, + "commentStart": 1622, "end": 0, "start": 0, "type": "NonCodeNode", diff --git a/rust/kcl-lib/tests/scale_after_fillet/input.kcl b/rust/kcl-lib/tests/scale_after_fillet/input.kcl index 975256834..df0fa29ab 100644 --- a/rust/kcl-lib/tests/scale_after_fillet/input.kcl +++ b/rust/kcl-lib/tests/scale_after_fillet/input.kcl @@ -52,6 +52,6 @@ export fn bolt() { } bolt() - |> scale(scale = [3.14, 3.14, 3.14]) + |> scale(x = 3.14, y = 3.14, z = 3.14) // https://www.mcmaster.com/91251a404/ diff --git a/rust/kcl-lib/tests/scale_after_fillet/unparsed.snap b/rust/kcl-lib/tests/scale_after_fillet/unparsed.snap index c2e54902a..412227e5a 100644 --- a/rust/kcl-lib/tests/scale_after_fillet/unparsed.snap +++ b/rust/kcl-lib/tests/scale_after_fillet/unparsed.snap @@ -56,6 +56,6 @@ export fn bolt() { } bolt() - |> scale(scale = [3.14, 3.14, 3.14]) + |> scale(x = 3.14, y = 3.14, z = 3.14) // https://www.mcmaster.com/91251a404/ diff --git a/rust/kcl-lib/tests/sketch-on-chamfer-two-times-different-order/artifact_commands.snap b/rust/kcl-lib/tests/sketch-on-chamfer-two-times-different-order/artifact_commands.snap index 6e036a30c..7b02e81ed 100644 --- a/rust/kcl-lib/tests/sketch-on-chamfer-two-times-different-order/artifact_commands.snap +++ b/rust/kcl-lib/tests/sketch-on-chamfer-two-times-different-order/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands sketch-on-chamfer-two-times-different-order.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/sketch-on-chamfer-two-times/artifact_commands.snap b/rust/kcl-lib/tests/sketch-on-chamfer-two-times/artifact_commands.snap index 6a6f00d85..0d3adf5aa 100644 --- a/rust/kcl-lib/tests/sketch-on-chamfer-two-times/artifact_commands.snap +++ b/rust/kcl-lib/tests/sketch-on-chamfer-two-times/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands sketch-on-chamfer-two-times.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/sketch_in_object/artifact_commands.snap b/rust/kcl-lib/tests/sketch_in_object/artifact_commands.snap index c7fbc4106..c260a3a0d 100644 --- a/rust/kcl-lib/tests/sketch_in_object/artifact_commands.snap +++ b/rust/kcl-lib/tests/sketch_in_object/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands sketch_in_object.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/sketch_on_face/artifact_commands.snap b/rust/kcl-lib/tests/sketch_on_face/artifact_commands.snap index 7f733af2b..f37c2234b 100644 --- a/rust/kcl-lib/tests/sketch_on_face/artifact_commands.snap +++ b/rust/kcl-lib/tests/sketch_on_face/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands sketch_on_face.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/sketch_on_face_after_fillets_referencing_face/artifact_commands.snap b/rust/kcl-lib/tests/sketch_on_face_after_fillets_referencing_face/artifact_commands.snap index b9c8b2e5a..f171056e3 100644 --- a/rust/kcl-lib/tests/sketch_on_face_after_fillets_referencing_face/artifact_commands.snap +++ b/rust/kcl-lib/tests/sketch_on_face_after_fillets_referencing_face/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands sketch_on_face_after_fillets_referencing_face.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/sketch_on_face_circle_tagged/artifact_commands.snap b/rust/kcl-lib/tests/sketch_on_face_circle_tagged/artifact_commands.snap index a6839fac1..75da18b40 100644 --- a/rust/kcl-lib/tests/sketch_on_face_circle_tagged/artifact_commands.snap +++ b/rust/kcl-lib/tests/sketch_on_face_circle_tagged/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands sketch_on_face_circle_tagged.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/sketch_on_face_end/artifact_commands.snap b/rust/kcl-lib/tests/sketch_on_face_end/artifact_commands.snap index ead803a03..a86e87380 100644 --- a/rust/kcl-lib/tests/sketch_on_face_end/artifact_commands.snap +++ b/rust/kcl-lib/tests/sketch_on_face_end/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands sketch_on_face_end.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/sketch_on_face_end_negative_extrude/artifact_commands.snap b/rust/kcl-lib/tests/sketch_on_face_end_negative_extrude/artifact_commands.snap index 6fc2dd25b..9832f6e82 100644 --- a/rust/kcl-lib/tests/sketch_on_face_end_negative_extrude/artifact_commands.snap +++ b/rust/kcl-lib/tests/sketch_on_face_end_negative_extrude/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands sketch_on_face_end_negative_extrude.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/sketch_on_face_start/artifact_commands.snap b/rust/kcl-lib/tests/sketch_on_face_start/artifact_commands.snap index 5699daa3e..ba5108432 100644 --- a/rust/kcl-lib/tests/sketch_on_face_start/artifact_commands.snap +++ b/rust/kcl-lib/tests/sketch_on_face_start/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands sketch_on_face_start.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/ssi_pattern/artifact_commands.snap b/rust/kcl-lib/tests/ssi_pattern/artifact_commands.snap index 2f5343f95..4d3ca26ce 100644 --- a/rust/kcl-lib/tests/ssi_pattern/artifact_commands.snap +++ b/rust/kcl-lib/tests/ssi_pattern/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands ssi_pattern.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/subtract_cylinder_from_cube/artifact_commands.snap b/rust/kcl-lib/tests/subtract_cylinder_from_cube/artifact_commands.snap index bb6a03ef3..86815f4f1 100644 --- a/rust/kcl-lib/tests/subtract_cylinder_from_cube/artifact_commands.snap +++ b/rust/kcl-lib/tests/subtract_cylinder_from_cube/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands subtract_cylinder_from_cube.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/tan_arc_x_line/artifact_commands.snap b/rust/kcl-lib/tests/tan_arc_x_line/artifact_commands.snap index c2c2b045c..3628827d6 100644 --- a/rust/kcl-lib/tests/tan_arc_x_line/artifact_commands.snap +++ b/rust/kcl-lib/tests/tan_arc_x_line/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands tan_arc_x_line.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/tangential_arc/artifact_commands.snap b/rust/kcl-lib/tests/tangential_arc/artifact_commands.snap index 5798d0d31..01e609007 100644 --- a/rust/kcl-lib/tests/tangential_arc/artifact_commands.snap +++ b/rust/kcl-lib/tests/tangential_arc/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands tangential_arc.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/translate_after_fillet/artifact_commands.snap b/rust/kcl-lib/tests/translate_after_fillet/artifact_commands.snap index 5a51ad708..46afdef21 100644 --- a/rust/kcl-lib/tests/translate_after_fillet/artifact_commands.snap +++ b/rust/kcl-lib/tests/translate_after_fillet/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands translate_after_fillet.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/translate_after_fillet/ast.snap b/rust/kcl-lib/tests/translate_after_fillet/ast.snap index 66a7ca7c6..eeefb9b59 100644 --- a/rust/kcl-lib/tests/translate_after_fillet/ast.snap +++ b/rust/kcl-lib/tests/translate_after_fillet/ast.snap @@ -2097,54 +2097,65 @@ description: Result of parsing translate_after_fillet.kcl "label": { "commentStart": 1597, "end": 0, - "name": "translate", + "name": "x", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1601, + "end": 0, + "raw": "10", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 10.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1605, + "end": 0, + "name": "y", "start": 0, "type": "Identifier" }, "arg": { "commentStart": 1609, - "elements": [ - { - "commentStart": 1610, - "end": 0, - "raw": "10", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 10.0, - "suffix": "None" - } - }, - { - "commentStart": 1614, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - }, - { - "commentStart": 1617, - "end": 0, - "raw": "0", - "start": 0, - "type": "Literal", - "type": "Literal", - "value": { - "value": 0.0, - "suffix": "None" - } - } - ], "end": 0, + "raw": "0", "start": 0, - "type": "ArrayExpression", - "type": "ArrayExpression" + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + }, + { + "type": "LabeledArg", + "label": { + "commentStart": 1612, + "end": 0, + "name": "z", + "start": 0, + "type": "Identifier" + }, + "arg": { + "commentStart": 1616, + "end": 0, + "raw": "0", + "start": 0, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } } } ], @@ -2177,7 +2188,7 @@ description: Result of parsing translate_after_fillet.kcl "nonCodeNodes": { "1": [ { - "commentStart": 1620, + "commentStart": 1618, "end": 0, "start": 0, "type": "NonCodeNode", diff --git a/rust/kcl-lib/tests/translate_after_fillet/input.kcl b/rust/kcl-lib/tests/translate_after_fillet/input.kcl index 99489a82a..a53c193c7 100644 --- a/rust/kcl-lib/tests/translate_after_fillet/input.kcl +++ b/rust/kcl-lib/tests/translate_after_fillet/input.kcl @@ -52,6 +52,6 @@ export fn bolt() { } bolt() - |> translate(translate = [10, 0, 0]) + |> translate(x = 10, y = 0, z = 0) // https://www.mcmaster.com/91251a404/ diff --git a/rust/kcl-lib/tests/translate_after_fillet/unparsed.snap b/rust/kcl-lib/tests/translate_after_fillet/unparsed.snap index 54648c487..c7233b53a 100644 --- a/rust/kcl-lib/tests/translate_after_fillet/unparsed.snap +++ b/rust/kcl-lib/tests/translate_after_fillet/unparsed.snap @@ -56,6 +56,6 @@ export fn bolt() { } bolt() - |> translate(translate = [10, 0, 0]) + |> translate(x = 10, y = 0, z = 0) // https://www.mcmaster.com/91251a404/ diff --git a/rust/kcl-lib/tests/union_cubes/artifact_commands.snap b/rust/kcl-lib/tests/union_cubes/artifact_commands.snap index 725a7ecef..4a790e730 100644 --- a/rust/kcl-lib/tests/union_cubes/artifact_commands.snap +++ b/rust/kcl-lib/tests/union_cubes/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands union_cubes.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-lib/tests/xz_plane/artifact_commands.snap b/rust/kcl-lib/tests/xz_plane/artifact_commands.snap index 7d289fd6c..7dc70cd21 100644 --- a/rust/kcl-lib/tests/xz_plane/artifact_commands.snap +++ b/rust/kcl-lib/tests/xz_plane/artifact_commands.snap @@ -11,14 +11,6 @@ description: Artifact commands xz_plane.kcl "hidden": false } }, - { - "cmdId": "[uuid]", - "range": [], - "command": { - "type": "set_scene_units", - "unit": "mm" - } - }, { "cmdId": "[uuid]", "range": [], diff --git a/rust/kcl-python-bindings/Cargo.toml b/rust/kcl-python-bindings/Cargo.toml index 6983fab29..06d0a8036 100644 --- a/rust/kcl-python-bindings/Cargo.toml +++ b/rust/kcl-python-bindings/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kcl-python-bindings" -version = "0.3.55" +version = "0.3.56" edition = "2021" repository = "https://github.com/kittycad/modeling-app" diff --git a/rust/kcl-test-server/Cargo.toml b/rust/kcl-test-server/Cargo.toml index 1ebf22028..b7a8591f6 100644 --- a/rust/kcl-test-server/Cargo.toml +++ b/rust/kcl-test-server/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kcl-test-server" description = "A test server for KCL" -version = "0.1.55" +version = "0.1.56" edition = "2021" license = "MIT" diff --git a/rust/kcl-test-server/src/lib.rs b/rust/kcl-test-server/src/lib.rs index f23680119..308534269 100644 --- a/rust/kcl-test-server/src/lib.rs +++ b/rust/kcl-test-server/src/lib.rs @@ -15,7 +15,7 @@ use hyper::{ service::{make_service_fn, service_fn}, Body, Error, Response, Server, }; -use kcl_lib::{test_server::RequestBody, ExecState, ExecutorContext, Program, UnitLength}; +use kcl_lib::{test_server::RequestBody, ExecState, ExecutorContext, Program}; use tokio::{ sync::{mpsc, oneshot}, task::JoinHandle, @@ -69,9 +69,7 @@ fn start_worker(i: u8, engine_addr: Option) -> mpsc::Sender { // Make a work queue for this worker. let (tx, mut rx) = mpsc::channel(1); tokio::task::spawn(async move { - let state = ExecutorContext::new_for_unit_test(UnitLength::Mm, engine_addr) - .await - .unwrap(); + let state = ExecutorContext::new_for_unit_test(engine_addr).await.unwrap(); println!("Worker {i} ready"); while let Some(req) = rx.recv().await { let req: WorkerReq = req; diff --git a/rust/kcl-to-core/Cargo.toml b/rust/kcl-to-core/Cargo.toml index 3c863872a..a7157d158 100644 --- a/rust/kcl-to-core/Cargo.toml +++ b/rust/kcl-to-core/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kcl-to-core" description = "Utility methods to convert kcl to engine core executable tests" -version = "0.1.55" +version = "0.1.56" edition = "2021" license = "MIT" repository = "https://github.com/KittyCAD/modeling-app" diff --git a/rust/kcl-wasm-lib/Cargo.toml b/rust/kcl-wasm-lib/Cargo.toml index 6a48b1d36..b05826044 100644 --- a/rust/kcl-wasm-lib/Cargo.toml +++ b/rust/kcl-wasm-lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kcl-wasm-lib" -version = "0.1.55" +version = "0.1.56" edition = "2021" repository = "https://github.com/KittyCAD/modeling-app" rust-version = "1.83" diff --git a/rust/kcl-wasm-lib/src/context.rs b/rust/kcl-wasm-lib/src/context.rs index 9fc236254..411807715 100644 --- a/rust/kcl-wasm-lib/src/context.rs +++ b/rust/kcl-wasm-lib/src/context.rs @@ -85,6 +85,21 @@ impl Context { } } + /// Reset the scene and bust the cache. + /// ONLY use this if you absolutely need to reset the scene and bust the cache. + #[wasm_bindgen(js_name = bustCacheAndResetScene)] + pub async fn bust_cache_and_reset_scene(&self, settings: &str, path: Option) -> Result { + console_error_panic_hook::set_once(); + + let ctx = self.create_executor_ctx(settings, path, false)?; + match ctx.bust_cache_and_reset_scene().await { + // The serde-wasm-bindgen does not work here because of weird HashMap issues. + // DO NOT USE serde_wasm_bindgen::to_value it will break the frontend. + Ok(outcome) => JsValue::from_serde(&outcome).map_err(|e| e.to_string()), + Err(err) => Err(serde_json::to_string(&err).map_err(|serde_err| serde_err.to_string())?), + } + } + /// Execute a program in mock mode. #[wasm_bindgen(js_name = executeMock)] pub async fn execute_mock( diff --git a/rust/kcl-wasm-lib/src/lsp.rs b/rust/kcl-wasm-lib/src/lsp.rs index 1a5359c3d..79a5f807e 100644 --- a/rust/kcl-wasm-lib/src/lsp.rs +++ b/rust/kcl-wasm-lib/src/lsp.rs @@ -69,7 +69,6 @@ pub async fn lsp_run_kcl(config: LspServerConfig, token: String, baseurl: String let (service, socket) = LspService::build(|client| { kcl_lib::KclLspBackend::new_wasm(client, executor_ctx, fs, zoo_client, can_send_telemetry).unwrap() }) - .custom_method("kcl/updateUnits", kcl_lib::KclLspBackend::update_units) .custom_method("kcl/updateCanExecute", kcl_lib::KclLspBackend::update_can_execute) .finish(); diff --git a/rust/kcl-wasm-lib/src/wasm.rs b/rust/kcl-wasm-lib/src/wasm.rs index 74cc7f398..e9171e4fa 100644 --- a/rust/kcl-wasm-lib/src/wasm.rs +++ b/rust/kcl-wasm-lib/src/wasm.rs @@ -269,6 +269,17 @@ pub fn change_kcl_settings(code: &str, settings_str: &str) -> Result Result { + console_error_panic_hook::set_once(); + + let program = Program::parse_no_errs(code).map_err(|e| e.to_string())?; + + JsValue::from_serde(&program.is_empty_or_only_settings()).map_err(|e| e.to_string()) +} + /// Get the version of the kcl library. #[wasm_bindgen] pub fn get_kcl_version() -> String { diff --git a/src/App.tsx b/src/App.tsx index eb910ea68..d6a63dd45 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -30,6 +30,7 @@ import { commandBarActor } from 'machines/commandBarMachine' import { useToken } from 'machines/appMachine' import { useSettings } from 'machines/appMachine' import { rustContext } from 'lib/singletons' +import toast from 'react-hot-toast' maybeWriteToDisk() .then(() => {}) .catch(() => {}) @@ -98,6 +99,10 @@ export function App() { } ) + useHotkeyWrapper(['mod + s'], () => { + toast.success('Your work is auto-saved in real-time') + }) + const paneOpacity = [onboardingPaths.CAMERA, onboardingPaths.STREAMING].some( (p) => p === onboardingStatus.current ) diff --git a/src/Toolbar.tsx b/src/Toolbar.tsx index a0736af64..7a0aa1348 100644 --- a/src/Toolbar.tsx +++ b/src/Toolbar.tsx @@ -1,6 +1,6 @@ import { useRef, useMemo, memo, useCallback, useState } from 'react' import { isCursorInSketchCommandRange } from 'lang/util' -import { editorManager, engineCommandManager, kclManager } from 'lib/singletons' +import { editorManager, kclManager } from 'lib/singletons' import { useModelingContext } from 'hooks/useModelingContext' import { useNetworkContext } from 'hooks/useNetworkContext' import { NetworkHealthState } from 'hooks/useNetworkStatus' @@ -45,10 +45,10 @@ export function Toolbar({ ) return false return isCursorInSketchCommandRange( - engineCommandManager.artifactGraph, + kclManager.artifactGraph, context.selectionRanges ) - }, [engineCommandManager.artifactGraph, context.selectionRanges]) + }, [kclManager.artifactGraph, context.selectionRanges]) const toolbarButtonsRef = useRef(null) const { overallState } = useNetworkContext() diff --git a/src/clientSideScene/sceneEntities.ts b/src/clientSideScene/sceneEntities.ts index 521e3ab97..e2181ed94 100644 --- a/src/clientSideScene/sceneEntities.ts +++ b/src/clientSideScene/sceneEntities.ts @@ -3700,7 +3700,7 @@ function computeSelectionFromSourceRangeAndAST( sourceRange: SourceRange, ast: Node ): Selections { - const artifactGraph = engineCommandManager.artifactGraph + const artifactGraph = kclManager.artifactGraph const artifact = getArtifactFromRange(sourceRange, artifactGraph) || undefined const selection: Selections = { graphSelections: [ diff --git a/src/components/AstExplorer.tsx b/src/components/AstExplorer.tsx index 625036621..5d85ab7b4 100644 --- a/src/components/AstExplorer.tsx +++ b/src/components/AstExplorer.tsx @@ -1,5 +1,5 @@ import { useModelingContext } from 'hooks/useModelingContext' -import { editorManager, engineCommandManager, kclManager } from 'lib/singletons' +import { editorManager, kclManager } from 'lib/singletons' import { getNodeFromPath } from 'lang/queryAst' import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils' import { useEffect, useRef, useState } from 'react' @@ -135,12 +135,10 @@ function DisplayObj({ const range = topLevelRange(obj?.start || 0, obj.end || 0) const idInfo = codeToIdSelections( [{ codeRef: codeRefFromRange(range, kclManager.ast) }], - engineCommandManager.artifactGraph, - engineCommandManager.artifactIndex + kclManager.artifactGraph, + kclManager.artifactIndex )[0] - const artifact = engineCommandManager.artifactGraph.get( - idInfo?.id || '' - ) + const artifact = kclManager.artifactGraph.get(idInfo?.id || '') if (!artifact) return send({ type: 'Set selection', diff --git a/src/components/CommandBarOverwriteWarning.tsx b/src/components/CommandBarOverwriteWarning.tsx index 9e9dd239f..1d5ac41f2 100644 --- a/src/components/CommandBarOverwriteWarning.tsx +++ b/src/components/CommandBarOverwriteWarning.tsx @@ -1,11 +1,11 @@ interface CommandBarOverwriteWarningProps { - heading?: string - message?: string + heading: string + message: string } export function CommandBarOverwriteWarning({ - heading = 'Overwrite current file and units?', - message = 'This will permanently replace the current code in the editor, and overwrite your current units.', + heading, + message, }: CommandBarOverwriteWarningProps) { return ( <> diff --git a/src/components/DebugArtifactGraph.tsx b/src/components/DebugArtifactGraph.tsx index b09f3485a..5436ab237 100644 --- a/src/components/DebugArtifactGraph.tsx +++ b/src/components/DebugArtifactGraph.tsx @@ -1,13 +1,13 @@ import { useMemo } from 'react' -import { engineCommandManager } from 'lib/singletons' +import { kclManager } from 'lib/singletons' import { expandPlane, PlaneArtifactRich } from 'lang/std/artifactGraph' import { ArtifactGraph } from 'lang/wasm' import { DebugDisplayArray, GenericObj } from './DebugDisplayObj' export function DebugArtifactGraph() { const artifactGraphTree = useMemo(() => { - return computeTree(engineCommandManager.artifactGraph) - }, [engineCommandManager.artifactGraph]) + return computeTree(kclManager.artifactGraph) + }, [kclManager.artifactGraph]) const filterKeys: string[] = ['codeRef', 'pathToNode'] return ( diff --git a/src/components/FileMachineProvider.tsx b/src/components/FileMachineProvider.tsx index 3d73b0ee4..1860d74d1 100644 --- a/src/components/FileMachineProvider.tsx +++ b/src/components/FileMachineProvider.tsx @@ -15,6 +15,7 @@ import { import { fileMachine } from 'machines/fileMachine' import { isDesktop } from 'lib/isDesktop' import { + DEFAULT_DEFAULT_LENGTH_UNIT, DEFAULT_FILE_NAME, DEFAULT_PROJECT_KCL_FILE, FILE_EXT, @@ -29,11 +30,12 @@ import { } from 'lib/getKclSamplesManifest' import { markOnce } from 'lib/performance' import { commandBarActor } from 'machines/commandBarMachine' -import { settingsActor, useSettings } from 'machines/appMachine' +import { useSettings } from 'machines/appMachine' import { createRouteCommands } from 'lib/commandBarConfigs/routeCommandConfig' import { useToken } from 'machines/appMachine' import { createNamedViewsCommand } from 'lib/commandBarConfigs/namedViewsConfig' -import { reportRejection } from 'lib/trap' +import { err, reportRejection } from 'lib/trap' +import { newKclFile } from 'lang/project' type MachineContext = { state: StateFrom @@ -237,7 +239,12 @@ export const FileMachineProvider = ({ createdPath ) } else { - await window.electron.writeFile(createdPath, input.content ?? '') + const codeToWrite = newKclFile( + input.content, + settings.modeling.defaultUnit.current + ) + if (err(codeToWrite)) return Promise.reject(codeToWrite) + await window.electron.writeFile(createdPath, codeToWrite) } } @@ -266,7 +273,12 @@ export const FileMachineProvider = ({ }) createdName = name createdPath = path - await window.electron.writeFile(createdPath, input.content ?? '') + const codeToWrite = newKclFile( + input.content, + settings.modeling.defaultUnit.current + ) + if (err(codeToWrite)) return Promise.reject(codeToWrite) + await window.electron.writeFile(createdPath, codeToWrite) } return { @@ -357,10 +369,16 @@ export const FileMachineProvider = ({ const hasKclEntries = entries.filter((e: string) => e.endsWith('.kcl')).length !== 0 if (!hasKclEntries) { - await window.electron.writeFile( - window.electron.path.join(project.path, DEFAULT_PROJECT_KCL_FILE), - '' + const codeToWrite = newKclFile( + undefined, + settings.modeling.defaultUnit.current ) + if (err(codeToWrite)) return Promise.reject(codeToWrite) + const path = window.electron.path.join( + project.path, + DEFAULT_PROJECT_KCL_FILE + ) + await window.electron.writeFile(path, codeToWrite) // Refresh the route selected above because it's possible we're on // the same path on the navigate, which doesn't cause anything to // refresh, leaving a stale execution state. @@ -401,7 +419,9 @@ export const FileMachineProvider = ({ authToken: token ?? '', projectData, settings: { - defaultUnit: settings.modeling.defaultUnit.current ?? 'mm', + defaultUnit: + settings.modeling.defaultUnit.current ?? + DEFAULT_DEFAULT_LENGTH_UNIT, }, specialPropsForSampleCommand: { onSubmit: async (data) => { @@ -419,18 +439,6 @@ export const FileMachineProvider = ({ }, }) } - - // Either way, we want to overwrite the defaultUnit project setting - // with the sample's setting. - if (data.sampleUnits) { - settingsActor.send({ - type: 'set.modeling.defaultUnit', - data: { - level: 'project', - value: data.sampleUnits, - }, - }) - } }, providedOptions: kclSamples.map((sample) => ({ value: sample.pathFromProjectDirectoryToFirstFile, diff --git a/src/components/ModelingMachineProvider.tsx b/src/components/ModelingMachineProvider.tsx index 9a8e0c93c..e26f67d23 100644 --- a/src/components/ModelingMachineProvider.tsx +++ b/src/components/ModelingMachineProvider.tsx @@ -566,7 +566,7 @@ export const ModelingMachineProvider = ({ // See if the selection is "close enough" to be coerced to the plane later const maybePlane = getPlaneFromArtifact( selectionRanges.graphSelections[0].artifact, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) return !err(maybePlane) } @@ -579,7 +579,7 @@ export const ModelingMachineProvider = ({ return false } return !!isCursorInSketchCommandRange( - engineCommandManager.artifactGraph, + kclManager.artifactGraph, selectionRanges ) }, @@ -841,7 +841,7 @@ export const ModelingMachineProvider = ({ const artifact = selectionRanges.graphSelections[0].artifact const plane = getPlaneFromArtifact( artifact, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(plane)) return Promise.reject(plane) // if the user selected a segment, make sure we enter the right sketch as there can be multiple on a plane @@ -917,14 +917,13 @@ export const ModelingMachineProvider = ({ info?.sketchDetails?.faceId || '' ) - const sketchArtifact = - engineCommandManager.artifactGraph.get(mainPath) + const sketchArtifact = kclManager.artifactGraph.get(mainPath) if (sketchArtifact?.type !== 'path') return Promise.reject(new Error('No sketch artifact')) const sketchPaths = getPathsFromArtifact({ - artifact: engineCommandManager.artifactGraph.get(plane.id), + artifact: kclManager.artifactGraph.get(plane.id), sketchPathToNode: sketchArtifact?.codeRef?.pathToNode, - artifactGraph: engineCommandManager.artifactGraph, + artifactGraph: kclManager.artifactGraph, ast: kclManager.ast, }) if (err(sketchPaths)) return Promise.reject(sketchPaths) @@ -1743,7 +1742,7 @@ export const ModelingMachineProvider = ({ prompt: input.prompt, selections: input.selection, token, - artifactGraph: engineCommandManager.artifactGraph, + artifactGraph: kclManager.artifactGraph, projectName: context.project.name, }) }), diff --git a/src/components/ModelingSidebar/ModelingPanes/FeatureTreePane.tsx b/src/components/ModelingSidebar/ModelingPanes/FeatureTreePane.tsx index 8d51b4401..ed0b90747 100644 --- a/src/components/ModelingSidebar/ModelingPanes/FeatureTreePane.tsx +++ b/src/components/ModelingSidebar/ModelingPanes/FeatureTreePane.tsx @@ -13,7 +13,7 @@ import { getOperationLabel, stdLibMap, } from 'lib/operations' -import { editorManager, engineCommandManager, kclManager } from 'lib/singletons' +import { editorManager, kclManager } from 'lib/singletons' import { ComponentProps, useEffect, useMemo, useRef, useState } from 'react' import { Operation } from '@rust/kcl-lib/bindings/Operation' import { Actor, Prop } from 'xstate' @@ -58,7 +58,7 @@ export const FeatureTreePane = () => { const artifact = context.targetSourceRange ? getArtifactFromRange( context.targetSourceRange, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) : null diff --git a/src/components/ProjectsContextProvider.tsx b/src/components/ProjectsContextProvider.tsx index 176934b67..0c6559f98 100644 --- a/src/components/ProjectsContextProvider.tsx +++ b/src/components/ProjectsContextProvider.tsx @@ -32,6 +32,8 @@ import { } from 'lib/constants' import { codeManager, kclManager } from 'lib/singletons' import { Project } from 'lib/project' +import { newKclFile } from 'lang/project' +import { err } from 'lib/trap' type MachineContext = { state?: StateFrom @@ -120,7 +122,13 @@ const ProjectsContextWeb = ({ children }: { children: React.ReactNode }) => { createFile: fromPromise(async ({ input }) => { // Browser version doesn't navigate, just overwrites the current file clearImportSearchParams() - codeManager.updateCodeStateEditor(input.code || '') + + const codeToWrite = newKclFile( + input.code, + settings.modeling.defaultUnit.current + ) + if (err(codeToWrite)) return Promise.reject(codeToWrite) + codeManager.updateCodeStateEditor(codeToWrite) await codeManager.writeToFile() await kclManager.executeCode(true) @@ -388,8 +396,10 @@ const ProjectsContextDesktop = ({ } // Create the project around the file if newProject + let fileLoaded = false if (input.method === 'newProject') { await createNewProjectDirectory(projectName, input.code) + fileLoaded = true message = `Project "${projectName}" created successfully with link contents` } else { message = `File "${fileName}" created successfully` @@ -406,8 +416,16 @@ const ProjectsContextDesktop = ({ }) fileName = name - await window.electron.writeFile(path, input.code || '') + if (!fileLoaded) { + const codeToWrite = newKclFile( + input.code, + settings.modeling.defaultUnit.current + ) + if (err(codeToWrite)) return Promise.reject(codeToWrite) + await window.electron.writeFile(path, codeToWrite) + } + // TODO: Return the project's file name if one was created. return { message, fileName, diff --git a/src/components/Stream.tsx b/src/components/Stream.tsx index 2057da33f..f64b45431 100644 --- a/src/components/Stream.tsx +++ b/src/components/Stream.tsx @@ -304,7 +304,7 @@ export const Stream = () => { } const path = getArtifactOfTypes( { key: entity_id, types: ['path', 'solid2d', 'segment', 'helix'] }, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(path)) { return path diff --git a/src/components/Toolbar/Intersect.tsx b/src/components/Toolbar/Intersect.tsx index 88728bfee..762fd38cd 100644 --- a/src/components/Toolbar/Intersect.tsx +++ b/src/components/Toolbar/Intersect.tsx @@ -16,7 +16,7 @@ import { TransformInfo } from 'lang/std/stdTypes' import { GetInfoModal, createInfoModal } from '../SetHorVertDistanceModal' import { createVariableDeclaration } from '../../lang/modifyAst' import { removeDoubleNegatives } from '../AvailableVarsHelpers' -import { engineCommandManager, kclManager } from 'lib/singletons' +import { kclManager } from 'lib/singletons' import { err } from 'lib/trap' import { Node } from '@rust/kcl-lib/bindings/Node' @@ -45,7 +45,7 @@ export function intersectInfo({ selectionRanges.graphSelections.length > 1 && isLinesParallelAndConstrained( kclManager.ast, - engineCommandManager.artifactGraph, + kclManager.artifactGraph, kclManager.variables, selectionRanges.graphSelections[0], selectionRanges.graphSelections[1] diff --git a/src/components/Toolbar/SetAbsDistance.tsx b/src/components/Toolbar/SetAbsDistance.tsx index 57ed0609a..4efeb7fff 100644 --- a/src/components/Toolbar/SetAbsDistance.tsx +++ b/src/components/Toolbar/SetAbsDistance.tsx @@ -13,10 +13,7 @@ import { SetAngleLengthModal, createSetAngleLengthModal, } from '../SetAngleLengthModal' -import { - createLocalName, - createVariableDeclaration, -} from '../../lang/modifyAst' +import { createName, createVariableDeclaration } from '../../lang/modifyAst' import { removeDoubleNegatives } from '../AvailableVarsHelpers' import { kclManager } from 'lib/singletons' import { err } from 'lib/trap' @@ -169,7 +166,7 @@ export function applyConstraintAxisAlign({ if (err(info)) return info const transformInfos = info.transforms - let finalValue = createLocalName('ZERO') + let finalValue = createName(['turns'], 'ZERO') return transformAstSketchLines({ ast: structuredClone(kclManager.ast), diff --git a/src/components/Toolbar/setAngleLength.tsx b/src/components/Toolbar/setAngleLength.tsx index 30d72b7f4..ac04f093c 100644 --- a/src/components/Toolbar/setAngleLength.tsx +++ b/src/components/Toolbar/setAngleLength.tsx @@ -16,6 +16,7 @@ import { import { createBinaryExpressionWithUnary, createLocalName, + createName, createVariableDeclaration, } from '../../lang/modifyAst' import { removeDoubleNegatives } from '../AvailableVarsHelpers' @@ -167,14 +168,16 @@ export async function applyConstraintAngleLength({ isReferencingXAxis && angleOrLength === 'setAngle' let forceVal = valueUsedInTransform || 0 - let calcIdentifier = createLocalName('ZERO') + let calcIdentifier = createName(['turns'], 'ZERO') if (isReferencingYAxisAngle) { - calcIdentifier = createLocalName( + calcIdentifier = createName( + ['turns'], forceVal < 0 ? 'THREE_QUARTER_TURN' : 'QUARTER_TURN' ) forceVal = normaliseAngle(forceVal + (forceVal < 0 ? 90 : -90)) } else if (isReferencingXAxisAngle) { - calcIdentifier = createLocalName( + calcIdentifier = createName( + ['turns'], Math.abs(forceVal) > 90 ? 'HALF_TURN' : 'ZERO' ) forceVal = diff --git a/src/components/UnitsMenu.tsx b/src/components/UnitsMenu.tsx index 57b23c11b..6be30d721 100644 --- a/src/components/UnitsMenu.tsx +++ b/src/components/UnitsMenu.tsx @@ -1,6 +1,11 @@ import { Popover } from '@headlessui/react' -import { settingsActor, useSettings } from 'machines/appMachine' -import { changeKclSettings, unitLengthToUnitLen } from 'lang/wasm' +import { + changeKclSettings, + unitAngleToUnitAng, + unitLengthToUnitLen, +} from 'lang/wasm' +import { DEFAULT_DEFAULT_ANGLE_UNIT } from 'lib/constants' +import { DEFAULT_DEFAULT_LENGTH_UNIT } from 'lib/constants' import { baseUnitLabels, baseUnitsUnion } from 'lib/settings/settingsTypes' import { codeManager, kclManager } from 'lib/singletons' import { err, reportRejection } from 'lib/trap' @@ -8,24 +13,10 @@ import { useEffect, useState } from 'react' import toast from 'react-hot-toast' export function UnitsMenu() { - const settings = useSettings() - const [hasPerFileLengthUnit, setHasPerFileLengthUnit] = useState( - Boolean(kclManager.fileSettings.defaultLengthUnit) - ) - const [lengthSetting, setLengthSetting] = useState( - kclManager.fileSettings.defaultLengthUnit || - settings.modeling.defaultUnit.current - ) + const [fileSettings, setFileSettings] = useState(kclManager.fileSettings) useEffect(() => { - setHasPerFileLengthUnit(Boolean(kclManager.fileSettings.defaultLengthUnit)) - setLengthSetting( - kclManager.fileSettings.defaultLengthUnit || - settings.modeling.defaultUnit.current - ) - }, [ - kclManager.fileSettings.defaultLengthUnit, - settings.modeling.defaultUnit.current, - ]) + setFileSettings(kclManager.fileSettings) + }, [kclManager.fileSettings]) return ( @@ -41,7 +32,7 @@ export function UnitsMenu() {
Current units are:  - {lengthSetting} + {fileSettings.defaultLengthUnit ?? DEFAULT_DEFAULT_LENGTH_UNIT} { - if (hasPerFileLengthUnit) { - const newCode = changeKclSettings(codeManager.code, { - defaultLengthUnits: unitLengthToUnitLen(unit), - defaultAngleUnits: { type: 'Degrees' }, - }) - if (err(newCode)) { - toast.error( - `Failed to set per-file units: ${newCode.message}` - ) - } else { - codeManager.updateCodeStateEditor(newCode) - Promise.all([ - codeManager.writeToFile(), - kclManager.executeCode(), - ]) - .then(() => { - toast.success(`Updated per-file units to ${unit}`) - }) - .catch(reportRejection) - } + const newCode = changeKclSettings(codeManager.code, { + defaultLengthUnits: unitLengthToUnitLen(unit), + defaultAngleUnits: unitAngleToUnitAng( + fileSettings.defaultAngleUnit ?? + DEFAULT_DEFAULT_ANGLE_UNIT + ), + }) + if (err(newCode)) { + toast.error( + `Failed to set per-file units: ${newCode.message}` + ) } else { - settingsActor.send({ - type: 'set.modeling.defaultUnit', - data: { - level: 'project', - value: unit, - }, - }) + codeManager.updateCodeStateEditor(newCode) + Promise.all([ + codeManager.writeToFile(), + kclManager.executeCode(), + ]) + .then(() => { + toast.success(`Updated per-file units to ${unit}`) + }) + .catch(reportRejection) } close() }} > {baseUnitLabels[unit]} - {unit === lengthSetting && ( + {unit === + (fileSettings.defaultLengthUnit ?? + DEFAULT_DEFAULT_LENGTH_UNIT) && ( current )} diff --git a/src/editor/manager.ts b/src/editor/manager.ts index b7cfeb158..8b97d97cf 100644 --- a/src/editor/manager.ts +++ b/src/editor/manager.ts @@ -374,7 +374,7 @@ export default class EditorManager { selectionRanges: this._selectionRanges, isShiftDown: this._isShiftDown, ast: kclManager.ast, - artifactGraph: engineCommandManager.artifactGraph, + artifactGraph: kclManager.artifactGraph, }) if (!eventInfo) { diff --git a/src/hooks/useEngineConnectionSubscriptions.ts b/src/hooks/useEngineConnectionSubscriptions.ts index 196940a9b..ff7c94108 100644 --- a/src/hooks/useEngineConnectionSubscriptions.ts +++ b/src/hooks/useEngineConnectionSubscriptions.ts @@ -39,7 +39,7 @@ export function useEngineConnectionSubscriptions() { if (data?.entity_id) { const codeRefs = getCodeRefsByArtifactId( data.entity_id, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (codeRefs) { editorManager.setHighlightRange(codeRefs.map(({ range }) => range)) @@ -140,8 +140,7 @@ export function useEngineConnectionSubscriptions() { }) return } - const artifact = - engineCommandManager.artifactGraph.get(planeOrFaceId) + const artifact = kclManager.artifactGraph.get(planeOrFaceId) if (artifact?.type === 'plane') { const planeInfo = await getFaceDetails(planeOrFaceId) @@ -179,7 +178,7 @@ export function useEngineConnectionSubscriptions() { const faceId = planeOrFaceId const extrusion = getSweepFromSuspectedSweepSurface( faceId, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if ( @@ -193,9 +192,9 @@ export function useEngineConnectionSubscriptions() { const codeRef = artifact.type === 'cap' - ? getCapCodeRef(artifact, engineCommandManager.artifactGraph) + ? getCapCodeRef(artifact, kclManager.artifactGraph) : artifact.type === 'wall' - ? getWallCodeRef(artifact, engineCommandManager.artifactGraph) + ? getWallCodeRef(artifact, kclManager.artifactGraph) : artifact.codeRef const faceInfo = await getFaceDetails(faceId) @@ -221,7 +220,7 @@ export function useEngineConnectionSubscriptions() { key: artifact.consumedEdgeId, types: ['segment', 'sweepEdge'], }, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(consumedArtifact)) return null if (consumedArtifact.type === 'segment') { @@ -232,7 +231,7 @@ export function useEngineConnectionSubscriptions() { } else { const segment = getArtifactOfTypes( { key: consumedArtifact.segId, types: ['segment'] }, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(segment)) return null chamferInfo = { diff --git a/src/lang/KclSingleton.ts b/src/lang/KclSingleton.ts index 45def4d56..10d518866 100644 --- a/src/lang/KclSingleton.ts +++ b/src/lang/KclSingleton.ts @@ -5,10 +5,12 @@ import { compilationErrorsToDiagnostics, kclErrorsToDiagnostics, } from './errors' -import { uuidv4 } from 'lib/utils' +import { uuidv4, isOverlap, deferExecution } from 'lib/utils' import { EngineCommandManager } from './std/engineConnection' import { err, reportRejection } from 'lib/trap' import { EXECUTE_AST_INTERRUPT_ERROR_MESSAGE } from 'lib/constants' +import { buildArtifactIndex } from 'lib/artifactIndex' +import { ArtifactIndex } from 'lib/artifactIndex' import { emptyExecState, @@ -24,6 +26,7 @@ import { SourceRange, topLevelRange, VariableMap, + ArtifactGraph, } from 'lang/wasm' import { getNodeFromPath, getSettingsAnnotation } from './queryAst' import { @@ -53,6 +56,14 @@ interface ExecuteArgs { } export class KclManager { + /** + * The artifactGraph is a client-side representation of the commands that have been sent + * see: src/lang/std/artifactGraph-README.md for a full explanation. + */ + artifactGraph: ArtifactGraph = new Map() + artifactIndex: ArtifactIndex = [] + defaultPlanesShown: boolean = false + private _ast: Node = { body: [], shebang: null, @@ -289,6 +300,47 @@ export class KclManager { } } + private async updateArtifactGraph( + execStateArtifactGraph: ExecState['artifactGraph'] + ) { + this.artifactGraph = execStateArtifactGraph + this.artifactIndex = buildArtifactIndex(execStateArtifactGraph) + if (this.artifactGraph.size) { + // TODO: we wanna remove this logic from xstate, it is racey + // This defer is bullshit but playwright wants it + // It was like this in engineConnection.ts already + deferExecution((a?: null) => { + this.engineCommandManager.modelingSend({ + type: 'Artifact graph emptied', + }) + }, 200)(null) + } else { + deferExecution((a?: null) => { + this.engineCommandManager.modelingSend({ + type: 'Artifact graph populated', + }) + }, 200)(null) + } + } + + // Some "objects" have the same source range, such as sketch_mode_start and start_path. + // So when passing a range, we need to also specify the command type + private mapRangeToObjectId( + range: SourceRange, + commandTypeToTarget: string + ): string | undefined { + for (const [artifactId, artifact] of this.artifactGraph) { + if ( + 'codeRef' in artifact && + artifact.codeRef && + isOverlap(range, artifact.codeRef.range) + ) { + if (commandTypeToTarget === artifact.type) return artifactId + } + } + return undefined + } + async safeParse(code: string): Promise | null> { const result = parse(code) this.diagnostics = [] @@ -330,6 +382,7 @@ export class KclManager { } // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (e) { + console.error(e) this.wasmInitFailed = true } } @@ -370,12 +423,12 @@ export class KclManager { // Do not send send scene commands if the program was interrupted, go to clean up if (!isInterrupted) { this.addDiagnostics(await lintAst({ ast: ast })) - setSelectionFilterToDefault(this.engineCommandManager) + await setSelectionFilterToDefault(this.engineCommandManager) if (args.zoomToFit) { let zoomObjectId: string | undefined = '' if (args.zoomOnRangeAndType) { - zoomObjectId = this.engineCommandManager?.mapRangeToObjectId( + zoomObjectId = this.mapRangeToObjectId( args.zoomOnRangeAndType.range, args.zoomOnRangeAndType.type ) @@ -429,7 +482,7 @@ export class KclManager { } this.ast = { ...ast } // updateArtifactGraph relies on updated executeState/variables - this.engineCommandManager.updateArtifactGraph(execState.artifactGraph) + await this.updateArtifactGraph(execState.artifactGraph) this._executeCallback() if (!isInterrupted) { sceneInfra.modelingSend({ type: 'code edit during sketch' }) diff --git a/src/lang/modifyAst.ts b/src/lang/modifyAst.ts index 550bc4794..f7423c95a 100644 --- a/src/lang/modifyAst.ts +++ b/src/lang/modifyAst.ts @@ -1087,6 +1087,22 @@ export function createLocalName(name: string): Node { } } +export function createName(path: [string], name: string): Node { + return { + type: 'Name', + start: 0, + end: 0, + moduleId: 0, + outerAttrs: [], + preComments: [], + commentStart: 0, + + abs_path: false, + path: path.map(createIdentifier), + name: createIdentifier(name), + } +} + export function createPipeSubstitution(): Node { return { type: 'PipeSubstitution', diff --git a/src/lang/modifyAst/addEdgeTreatment.test.ts b/src/lang/modifyAst/addEdgeTreatment.test.ts index a4f387c6c..aa91f9389 100644 --- a/src/lang/modifyAst/addEdgeTreatment.test.ts +++ b/src/lang/modifyAst/addEdgeTreatment.test.ts @@ -139,7 +139,7 @@ const runGetPathToExtrudeForSegmentSelectionTest = async ( // executeAst and artifactGraph await kclManager.executeAst({ ast }) - const artifactGraph = engineCommandManager.artifactGraph + const artifactGraph = kclManager.artifactGraph // find artifact const maybeArtifact = [...artifactGraph].find(([, artifact]) => { @@ -348,7 +348,7 @@ const runModifyAstCloneWithEdgeTreatmentAndTag = async ( // executeAst await kclManager.executeAst({ ast }) - const artifactGraph = engineCommandManager.artifactGraph + const artifactGraph = kclManager.artifactGraph const selection: Selections = { graphSelections: segmentRanges.map((segmentRange) => { @@ -390,7 +390,7 @@ const runDeleteEdgeTreatmentTest = async ( // update artifact graph await kclManager.executeAst({ ast }) - const artifactGraph = engineCommandManager.artifactGraph + const artifactGraph = kclManager.artifactGraph // define snippet range const edgeTreatmentRange = topLevelRange( diff --git a/src/lang/modifyAst/addEdgeTreatment.ts b/src/lang/modifyAst/addEdgeTreatment.ts index 2b4e7de5c..5ad37acfe 100644 --- a/src/lang/modifyAst/addEdgeTreatment.ts +++ b/src/lang/modifyAst/addEdgeTreatment.ts @@ -118,7 +118,7 @@ export function modifyAstWithEdgeTreatmentAndTag( const astResult = insertParametersIntoAst(clonedAst, parameters) if (err(astResult)) return astResult - const artifactGraph = dependencies.engineCommandManager.artifactGraph + const artifactGraph = dependencies.kclManager.artifactGraph // Step 1: modify ast with tags and group them by extrude nodes (bodies) const extrudeToTagsMap: Map< diff --git a/src/lang/modifyAst/boolean.ts b/src/lang/modifyAst/boolean.ts index 28b547147..322907cc2 100644 --- a/src/lang/modifyAst/boolean.ts +++ b/src/lang/modifyAst/boolean.ts @@ -42,11 +42,11 @@ export async function applySubtractFromTargetOperatorSelections( } const orderedChildrenTarget = findAllChildrenAndOrderByPlaceInCode( target.artifact, - dependencies.engineCommandManager.artifactGraph + dependencies.kclManager.artifactGraph ) const orderedChildrenTool = findAllChildrenAndOrderByPlaceInCode( tool.artifact, - dependencies.engineCommandManager.artifactGraph + dependencies.kclManager.artifactGraph ) const lastVarTarget = getLastVariable(orderedChildrenTarget, ast) @@ -89,7 +89,7 @@ export async function applyUnionFromTargetOperatorSelections( const orderedChildrenEach = artifacts.map((artifact) => findAllChildrenAndOrderByPlaceInCode( artifact, - dependencies.engineCommandManager.artifactGraph + dependencies.kclManager.artifactGraph ) ) @@ -136,7 +136,7 @@ export async function applyIntersectFromTargetOperatorSelections( const orderedChildrenEach = artifacts.map((artifact) => findAllChildrenAndOrderByPlaceInCode( artifact, - dependencies.engineCommandManager.artifactGraph + dependencies.kclManager.artifactGraph ) ) diff --git a/src/lang/modifyAst/deleteSelection.ts b/src/lang/modifyAst/deleteSelection.ts index 5d09ec5db..95b46921b 100644 --- a/src/lang/modifyAst/deleteSelection.ts +++ b/src/lang/modifyAst/deleteSelection.ts @@ -4,7 +4,6 @@ import { deleteFromSelection } from 'lang/modifyAst' import { codeManager, editorManager, - engineCommandManager, kclManager, rustContext, } from 'lib/singletons' @@ -25,7 +24,7 @@ export async function deleteSelectionPromise( ast, selection, kclManager.variables, - engineCommandManager.artifactGraph, + kclManager.artifactGraph, getFaceDetails ) if (err(modifiedAst)) { diff --git a/src/lang/project.ts b/src/lang/project.ts new file mode 100644 index 000000000..17141a034 --- /dev/null +++ b/src/lang/project.ts @@ -0,0 +1,33 @@ +import { UnitLength } from '@rust/kcl-lib/bindings/ModelingCmd' +import { + changeKclSettings, + unitAngleToUnitAng, + unitLengthToUnitLen, +} from './wasm' +import { DEFAULT_DEFAULT_ANGLE_UNIT } from 'lib/constants' +import { DEFAULT_DEFAULT_LENGTH_UNIT } from 'lib/constants' + +/** + * Create a new KCL file with the given initial content and default length unit. + * @returns KCL string + */ +export function newKclFile( + initialContent: string | undefined, + defaultLengthUnit: UnitLength +): string | Error { + // If we're given initial content, we're loading a file that should already + // have units in it. Don't modify it. + if (initialContent !== undefined) { + return initialContent + } + // If the default length unit is the same as the default default length unit, + // there's no need to add the attribute. + if (defaultLengthUnit === DEFAULT_DEFAULT_LENGTH_UNIT) { + return '' + } + + return changeKclSettings('', { + defaultLengthUnits: unitLengthToUnitLen(defaultLengthUnit), + defaultAngleUnits: unitAngleToUnitAng(DEFAULT_DEFAULT_ANGLE_UNIT), + }) +} diff --git a/src/lang/std/engineConnection.ts b/src/lang/std/engineConnection.ts index a27d7ab06..e68cd924e 100644 --- a/src/lang/std/engineConnection.ts +++ b/src/lang/std/engineConnection.ts @@ -1,13 +1,8 @@ -import { - ArtifactGraph, - defaultSourceRange, - ExecState, - SourceRange, -} from 'lang/wasm' +import { defaultSourceRange, SourceRange } from 'lang/wasm' import { VITE_KC_API_WS_MODELING_URL, VITE_KC_DEV_TOKEN } from 'env' import { Models } from '@kittycad/lib' -import { deferExecution, isOverlap, uuidv4 } from 'lib/utils' -import { BSON, Binary as BSONBinary } from 'bson' +import { uuidv4, binaryToUuid } from 'lib/utils' +import { BSON } from 'bson' import { Themes, getThemeColorForEngine, @@ -22,8 +17,6 @@ import { KclManager } from 'lang/KclSingleton' import { reportRejection } from 'lib/trap' import { markOnce } from 'lib/performance' import { MachineManager } from 'components/MachineManagerProvider' -import { buildArtifactIndex } from 'lib/artifactIndex' -import { ArtifactIndex } from 'lib/artifactIndex' // TODO(paultag): This ought to be tweakable. const pingIntervalMs = 5_000 @@ -1047,11 +1040,9 @@ class EngineConnection extends EventTarget { }) .join('\n') if (message.request_id) { - const artifactThatFailed = - this.engineCommandManager.artifactGraph.get(message.request_id) console.error( `Error in response to request ${message.request_id}:\n${errorsString} - failed cmd type was ${artifactThatFailed?.type}` + failed` ) } else { console.error(`Error from server:\n${errorsString}`) @@ -1355,8 +1346,7 @@ export enum EngineCommandManagerEvents { * * As commands are send their state is tracked in {@link pendingCommands} and clear as soon as we receive a response. * - * Also all commands that are sent are kept track of in WASM artifactCommands and their responses are kept in {@link responseMap} - * Both of these data structures are used to process the {@link artifactGraph}. + * Also all commands that are sent are kept track of in WASM and their responses are kept in {@link responseMap} */ interface PendingMessage { @@ -1369,12 +1359,6 @@ interface PendingMessage { isSceneCommand: boolean } export class EngineCommandManager extends EventTarget { - /** - * The artifactGraph is a client-side representation of the commands that have been sent - * see: src/lang/std/artifactGraph-README.md for a full explanation. - */ - artifactGraph: ArtifactGraph = new Map() - artifactIndex: ArtifactIndex = [] /** * The pendingCommands object is a map of the commands that have been sent to the engine that are still waiting on a reply */ @@ -1382,7 +1366,7 @@ export class EngineCommandManager extends EventTarget { [commandId: string]: PendingMessage } = {} /** - * A map of the responses to the WASM artifactCommands, when processing the commands into the artifactGraph, this response map allow + * A map of the responses to the WASM, this response map allow * us to look up the response by command id */ responseMap: ResponseMap = {} @@ -1878,7 +1862,7 @@ export class EngineCommandManager extends EventTarget { registerCommandLogCallback(callback: (command: CommandLog[]) => void) { this._commandLogCallBack = callback } - sendSceneCommand( + async sendSceneCommand( command: EngineCommand, forceWebsocket = false ): Promise { @@ -2032,13 +2016,6 @@ export class EngineCommandManager extends EventTarget { return promise } - deferredArtifactPopulated = deferExecution((a?: null) => { - this.modelingSend({ type: 'Artifact graph populated' }) - }, 200) - deferredArtifactEmptied = deferExecution((a?: null) => { - this.modelingSend({ type: 'Artifact graph emptied' }) - }, 200) - /** * When an execution takes place we want to wait until we've got replies for all of the commands * When this is done when we build the artifact map synchronously. @@ -2048,16 +2025,6 @@ export class EngineCommandManager extends EventTarget { Object.values(this.pendingCommands).map((a) => a.promise) ) } - updateArtifactGraph(execStateArtifactGraph: ExecState['artifactGraph']) { - this.artifactGraph = execStateArtifactGraph - this.artifactIndex = buildArtifactIndex(execStateArtifactGraph) - // TODO check if these still need to be deferred once e2e tests are working again. - if (this.artifactGraph.size) { - this.deferredArtifactEmptied(null) - } else { - this.deferredArtifactPopulated(null) - } - } /** * Reject all of the modeling pendingCommands created from sendModelingCommandFromWasm @@ -2121,24 +2088,6 @@ export class EngineCommandManager extends EventTarget { }, }).catch(reportRejection) } - - // Some "objects" have the same source range, such as sketch_mode_start and start_path. - // So when passing a range, we need to also specify the command type - mapRangeToObjectId( - range: SourceRange, - commandTypeToTarget: string - ): string | undefined { - for (const [artifactId, artifact] of this.artifactGraph) { - if ( - 'codeRef' in artifact && - artifact.codeRef && - isOverlap(range, artifact.codeRef.range) - ) { - if (commandTypeToTarget === artifact.type) return artifactId - } - } - return undefined - } } function promiseFactory() { @@ -2150,65 +2099,3 @@ function promiseFactory() { }) return { promise, resolve, reject } } - -/** - * Converts a binary buffer to a UUID string. - * - * @param buffer - The binary buffer containing the UUID bytes. - * @returns A string representation of the UUID in the format 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'. - */ -function binaryToUuid( - binaryData: Buffer | Uint8Array | BSONBinary | string -): string { - if (typeof binaryData === 'string') { - return binaryData - } - - let buffer: Uint8Array - - // Handle MongoDB BSON Binary object - if ( - binaryData && - '_bsontype' in binaryData && - binaryData._bsontype === 'Binary' - ) { - // Extract the buffer from the BSON Binary object - buffer = binaryData.buffer - } - // Handle case where buffer property exists (some MongoDB drivers structure) - else if (binaryData && binaryData.buffer instanceof Uint8Array) { - buffer = binaryData.buffer - } - // Handle direct Buffer or Uint8Array - else if (binaryData instanceof Uint8Array || Buffer.isBuffer(binaryData)) { - buffer = binaryData - } else { - console.error( - 'Invalid input type: expected MongoDB BSON Binary, Buffer, or Uint8Array' - ) - return '' - } - - // Ensure we have exactly 16 bytes (128 bits) for a UUID - if (buffer.length !== 16) { - // For debugging - console.log('Buffer length:', buffer.length) - console.log('Buffer content:', Array.from(buffer)) - console.error('UUID must be exactly 16 bytes') - return '' - } - - // Convert each byte to a hex string and pad with zeros if needed - const hexValues = Array.from(buffer).map((byte) => - byte.toString(16).padStart(2, '0') - ) - - // Format into UUID structure (8-4-4-4-12 characters) - return [ - hexValues.slice(0, 4).join(''), - hexValues.slice(4, 6).join(''), - hexValues.slice(6, 8).join(''), - hexValues.slice(8, 10).join(''), - hexValues.slice(10, 16).join(''), - ].join('-') -} diff --git a/src/lang/std/sketchcombos.ts b/src/lang/std/sketchcombos.ts index ff750387b..a5ba6029a 100644 --- a/src/lang/std/sketchcombos.ts +++ b/src/lang/std/sketchcombos.ts @@ -35,6 +35,7 @@ import { createLabeledArg, createLiteral, createLocalName, + createName, createObjectExpression, createPipeSubstitution, createUnaryExpression, @@ -612,7 +613,7 @@ const setAngledIntersectLineForLines: CreateStdLibSketchCallExpr = ({ 270: 'THREE_QUARTER_TURN', } const angleVal = [0, 90, 180, 270].includes(angle) - ? createLocalName(varNamMap[angle]) + ? createName(['turns'], varNamMap[angle]) : createLiteral(angle) return intersectCallWrapper({ fnName: 'angledLineThatIntersects', @@ -665,7 +666,7 @@ const setAngleBetweenCreateNode = firstHalfValue = createBinaryExpression([ firstHalfValue, '+', - createLocalName('HALF_TURN'), + createName(['turns'], 'HALF_TURN'), ]) valueUsedInTransform = normaliseAngle(valueUsedInTransform - 180) } diff --git a/src/lang/wasm.ts b/src/lang/wasm.ts index 3cfe0950f..df3d6c235 100644 --- a/src/lang/wasm.ts +++ b/src/lang/wasm.ts @@ -18,6 +18,7 @@ import { serialize_project_configuration, serialize_configuration, reloadModule, + is_kcl_empty_or_only_settings, } from 'lib/wasm_lib_wrapper' import { KCLError } from './errors' @@ -55,6 +56,10 @@ import { UnitAngle as UnitAng } from '@rust/kcl-lib/bindings/UnitAngle' import { ModulePath } from '@rust/kcl-lib/bindings/ModulePath' import { DefaultPlanes } from '@rust/kcl-lib/bindings/DefaultPlanes' import { isArray } from 'lib/utils' +import { + DEFAULT_DEFAULT_ANGLE_UNIT, + DEFAULT_DEFAULT_LENGTH_UNIT, +} from 'lib/constants' export type { Artifact } from '@rust/kcl-lib/bindings/Artifact' export type { ArtifactCommand } from '@rust/kcl-lib/bindings/Artifact' @@ -607,7 +612,27 @@ export function changeKclSettings( } /** - * Convert a `UnitLength_type` to a `UnitLen` + * Returns true if the given KCL is empty or only contains settings that would + * be auto-generated. + */ +export function isKclEmptyOrOnlySettings(kcl: string): boolean { + if (kcl === '') { + // Fast path. + return true + } + + try { + return is_kcl_empty_or_only_settings(kcl) + } catch (e) { + console.debug('Caught error checking if KCL is empty', e) + // If there's a parse error, it can't be empty or auto-generated. + return false + } +} + +/** + * Convert a `UnitLength` (used in settings and modeling commands) to a + * `UnitLen` (used in execution). */ export function unitLengthToUnitLen(input: UnitLength): UnitLen { switch (input) { @@ -627,7 +652,8 @@ export function unitLengthToUnitLen(input: UnitLength): UnitLen { } /** - * Convert `UnitLen` to `UnitLength_type`. + * Convert `UnitLen` (used in execution) to `UnitLength` (used in settings + * and modeling commands). */ export function unitLenToUnitLength(input: UnitLen): UnitLength { switch (input.type) { @@ -642,19 +668,33 @@ export function unitLenToUnitLength(input: UnitLen): UnitLength { case 'Inches': return 'in' default: - return 'mm' + return DEFAULT_DEFAULT_LENGTH_UNIT } } /** - * Convert `UnitAngle` to `UnitAngle_type`. + * Convert a `UnitAngle` (used in modeling commands) to a `UnitAng` (used in + * execution). + */ +export function unitAngleToUnitAng(input: UnitAngle): UnitAng { + switch (input) { + case 'radians': + return { type: 'Radians' } + default: + return { type: 'Degrees' } + } +} + +/** + * Convert `UnitAng` (used in execution) to `UnitAngle` (used in modeling + * commands). */ export function unitAngToUnitAngle(input: UnitAng): UnitAngle { switch (input.type) { case 'Radians': return 'radians' default: - return 'degrees' + return DEFAULT_DEFAULT_ANGLE_UNIT } } diff --git a/src/lib/commandBarConfigs/validators.ts b/src/lib/commandBarConfigs/validators.ts index 2a7192717..b199ced47 100644 --- a/src/lib/commandBarConfigs/validators.ts +++ b/src/lib/commandBarConfigs/validators.ts @@ -1,5 +1,5 @@ import { Models } from '@kittycad/lib' -import { engineCommandManager } from 'lib/singletons' +import { engineCommandManager, kclManager } from 'lib/singletons' import { uuidv4 } from 'lib/utils' import { CommandBarContext } from 'machines/commandBarMachine' import { Selections } from 'lib/selections' @@ -188,7 +188,7 @@ export const shellValidator = async ({ // So we're listing out the sweeps as if they were solids and taking the first one, just like in Rust for Shell: // https://github.com/KittyCAD/modeling-app/blob/e61fff115b9fa94aaace6307b1842cc15d41655e/src/wasm-lib/kcl/src/std/shell.rs#L237-L238 // TODO: This is one cheap way to make sketch-on-face supported now but will likely fail multiple solids - const object_id = engineCommandManager.artifactGraph + const object_id = kclManager.artifactGraph .values() .find((v) => v.type === 'sweep')?.pathId diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 2007ba35b..3731990b0 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -1,4 +1,5 @@ import { Models } from '@kittycad/lib/dist/types/src' +import { UnitAngle, UnitLength } from '@rust/kcl-lib/bindings/ModelingCmd' export const APP_NAME = 'Modeling App' /** Search string in new project names to increment as an index */ @@ -168,6 +169,18 @@ export const ZOO_STUDIO_PROTOCOL = 'zoo-studio' */ export const ASK_TO_OPEN_QUERY_PARAM = 'ask-open-desktop' +/** + * When no annotation is in the KCL file to specify the defaults, we use these + * default units. + */ +export const DEFAULT_DEFAULT_ANGLE_UNIT: UnitAngle = 'degrees' + +/** + * When no annotation is in the KCL file to specify the defaults, we use these + * default units. + */ +export const DEFAULT_DEFAULT_LENGTH_UNIT: UnitLength = 'mm' + /** Real execution. */ export const EXECUTION_TYPE_REAL = 'real' /** Mock execution. */ diff --git a/src/lib/coredump.ts b/src/lib/coredump.ts index 9d05c5147..326cd4871 100644 --- a/src/lib/coredump.ts +++ b/src/lib/coredump.ts @@ -200,17 +200,6 @@ export class CoreDumpManager { // engine_command_manager debugLog('CoreDump: engineCommandManager', this.engineCommandManager) - // artifact map - this.engineCommandManager.artifactGraph - if (this.engineCommandManager?.artifactGraph) { - debugLog( - 'CoreDump: Engine Command Manager artifact map', - this.engineCommandManager.artifactGraph - ) - clientState.engine_command_manager.artifact_map = structuredClone( - this.engineCommandManager.artifactGraph - ) - } - // command logs - this.engineCommandManager.commandLogs if (this.engineCommandManager?.commandLogs) { debugLog( @@ -274,6 +263,21 @@ export class CoreDumpManager { clientState.kcl_manager.ast = structuredClone(kclManager.ast) } + // artifact map - this.kclManager.artifactGraph + debugLog( + 'CoreDump: KCL Manager artifact map', + kclManager?.artifactGraph + ) + if (kclManager.artifactGraph) { + debugLog( + 'CoreDump: Engine Command Manager artifact map', + kclManager.artifactGraph + ) + clientState.engine_command_manager.artifact_map = structuredClone( + kclManager.artifactGraph + ) + } + // KCL Errors debugLog('CoreDump: KCL Errors', kclManager?.kclErrors) if (kclManager?.kclErrors) { diff --git a/src/lib/desktop.ts b/src/lib/desktop.ts index f154b9308..0b591d117 100644 --- a/src/lib/desktop.ts +++ b/src/lib/desktop.ts @@ -9,6 +9,7 @@ import { parseProjectSettings, } from 'lang/wasm' import { + DEFAULT_DEFAULT_LENGTH_UNIT, PROJECT_ENTRYPOINT, PROJECT_FOLDER, PROJECT_IMAGE_NAME, @@ -21,6 +22,7 @@ import { import { DeepPartial } from './types' import { ProjectConfiguration } from '@rust/kcl-lib/bindings/ProjectConfiguration' import { Configuration } from '@rust/kcl-lib/bindings/Configuration' +import { newKclFile } from 'lang/project' export async function renameProjectDirectory( projectPath: string, @@ -113,7 +115,15 @@ export async function createNewProjectDirectory( } const projectFile = window.electron.path.join(projectDir, PROJECT_ENTRYPOINT) - await window.electron.writeFile(projectFile, initialCode ?? '') + // When initialCode is present, we're loading existing code. If it's not + // present, we're creating a new project, and we want to incorporate the + // user's settings. + const codeToWrite = newKclFile( + initialCode, + configuration?.settings?.modeling?.base_unit ?? DEFAULT_DEFAULT_LENGTH_UNIT + ) + if (err(codeToWrite)) return Promise.reject(codeToWrite) + await window.electron.writeFile(projectFile, codeToWrite) const metadata = await window.electron.stat(projectFile) return { diff --git a/src/lib/kclCommands.ts b/src/lib/kclCommands.ts index f8c478627..923c24202 100644 --- a/src/lib/kclCommands.ts +++ b/src/lib/kclCommands.ts @@ -2,11 +2,22 @@ import { CommandBarOverwriteWarning } from 'components/CommandBarOverwriteWarnin import { Command, CommandArgumentOption } from './commandTypes' import { codeManager, kclManager } from './singletons' import { isDesktop } from './isDesktop' -import { FILE_EXT } from './constants' +import { + DEFAULT_DEFAULT_ANGLE_UNIT, + DEFAULT_DEFAULT_LENGTH_UNIT, + FILE_EXT, +} from './constants' import { UnitLength_type } from '@kittycad/lib/dist/types/src/models' -import { reportRejection } from './trap' +import { err, reportRejection } from './trap' import { IndexLoaderData } from './types' import { copyFileShareLink } from './links' +import { baseUnitsUnion } from './settings/settingsTypes' +import toast from 'react-hot-toast' +import { + changeKclSettings, + unitLengthToUnitLen, + unitAngleToUnitAng, +} from 'lang/wasm' interface OnSubmitProps { sampleName: string @@ -31,6 +42,59 @@ interface KclCommandConfig { export function kclCommands(commandProps: KclCommandConfig): Command[] { return [ + { + name: 'set-file-units', + displayName: 'Set file units', + description: + 'Set the length unit for all dimensions not given explicit units in the current file.', + needsReview: false, + groupId: 'code', + icon: 'code', + args: { + unit: { + required: true, + inputType: 'options', + defaultValue: + kclManager.fileSettings.defaultLengthUnit || + DEFAULT_DEFAULT_LENGTH_UNIT, + options: () => + Object.values(baseUnitsUnion).map((v) => { + return { + name: v, + value: v, + isCurrent: kclManager.fileSettings.defaultLengthUnit + ? v === kclManager.fileSettings.defaultLengthUnit + : v === DEFAULT_DEFAULT_LENGTH_UNIT, + } + }), + }, + }, + onSubmit: (data) => { + if (typeof data === 'object' && 'unit' in data) { + const newCode = changeKclSettings(codeManager.code, { + defaultLengthUnits: unitLengthToUnitLen(data.unit), + defaultAngleUnits: unitAngleToUnitAng( + kclManager.fileSettings.defaultAngleUnit ?? + DEFAULT_DEFAULT_ANGLE_UNIT + ), + }) + if (err(newCode)) { + toast.error(`Failed to set per-file units: ${newCode.message}`) + } else { + codeManager.updateCodeStateEditor(newCode) + Promise.all([codeManager.writeToFile(), kclManager.executeCode()]) + .then(() => { + toast.success(`Updated per-file units to ${data.unit}`) + }) + .catch(reportRejection) + } + } else { + toast.error( + 'Failed to set per-file units: no value provided to submit function. This is a bug.' + ) + } + }, + }, { name: 'format-code', displayName: 'Format Code', @@ -49,12 +113,18 @@ export function kclCommands(commandProps: KclCommandConfig): Command[] { needsReview: true, icon: 'code', reviewMessage: ({ argumentsToSubmit }) => - argumentsToSubmit.method === 'newFile' - ? CommandBarOverwriteWarning({ - heading: 'Create a new file, overwrite project units?', - message: `This will add the sample as a new file to your project, and replace your current project units with the sample's units.`, - }) - : CommandBarOverwriteWarning({}), + CommandBarOverwriteWarning({ + heading: + 'method' in argumentsToSubmit && + argumentsToSubmit.method === 'newFile' + ? 'Create a new file from sample?' + : 'Overwrite current file with sample?', + message: + 'method' in argumentsToSubmit && + argumentsToSubmit.method === 'newFile' + ? 'This will create a new file in the current project and open it.' + : 'This will erase your current file and load the sample part.', + }), groupId: 'code', onSubmit(data) { if (!data?.sample) { diff --git a/src/lib/operations.ts b/src/lib/operations.ts index a348fc167..f41359ea7 100644 --- a/src/lib/operations.ts +++ b/src/lib/operations.ts @@ -8,7 +8,7 @@ import { getWallCodeRef, } from 'lang/std/artifactGraph' import { Operation } from '@rust/kcl-lib/bindings/Operation' -import { codeManager, engineCommandManager, kclManager } from './singletons' +import { codeManager, kclManager, rustContext } from './singletons' import { err } from './trap' import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils' import { sourceRangeFromRust } from 'lang/wasm' @@ -20,7 +20,6 @@ import { } from './commandBarConfigs/modelingCommandConfig' import { isDefaultPlaneStr } from './planes' import { Selection, Selections } from './selections' -import { rustContext } from './singletons' import { KclExpression } from './commandTypes' type ExecuteCommandEvent = CommandBarMachineEvent & { @@ -73,7 +72,7 @@ const prepareToEditExtrude: PrepareToEditCallback = key: artifact.pathId, types: ['path'], }, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if ( err(pathArtifact) || @@ -86,7 +85,7 @@ const prepareToEditExtrude: PrepareToEditCallback = key: pathArtifact.solid2dId, types: ['solid2d'], }, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(solid2DArtifact) || solid2DArtifact.type !== 'solid2d') { return baseCommand @@ -157,7 +156,7 @@ const prepareToEditEdgeTreatment: PrepareToEditCallback = async ({ key: artifact.consumedEdgeId, types: ['segment', 'sweepEdge'], }, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(edgeArtifact)) { return { reason: "Couldn't find edge artifact" } @@ -165,7 +164,7 @@ const prepareToEditEdgeTreatment: PrepareToEditCallback = async ({ let edgeCodeRef = getEdgeCutConsumedCodeRef( artifact, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(edgeCodeRef)) { return { reason: "Couldn't find edge coderef" } @@ -272,16 +271,13 @@ const prepareToEditShell: PrepareToEditCallback = // that we can query in another loop later const sweepId = operation.unlabeledArg.value.value.artifactId const candidates: Map = new Map() - for (const artifact of engineCommandManager.artifactGraph.values()) { + for (const artifact of kclManager.artifactGraph.values()) { if ( artifact.type === 'cap' && artifact.sweepId === sweepId && artifact.subType ) { - const codeRef = getCapCodeRef( - artifact, - engineCommandManager.artifactGraph - ) + const codeRef = getCapCodeRef(artifact, kclManager.artifactGraph) if (err(codeRef)) { return baseCommand } @@ -297,7 +293,7 @@ const prepareToEditShell: PrepareToEditCallback = ) { const segArtifact = getArtifactOfTypes( { key: artifact.segId, types: ['segment'] }, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(segArtifact)) { return baseCommand @@ -461,7 +457,7 @@ const prepareToEditSweep: PrepareToEditCallback = async ({ key: artifact.pathId, types: ['path'], }, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if ( @@ -477,7 +473,7 @@ const prepareToEditSweep: PrepareToEditCallback = async ({ key: pathArtifact.solid2dId, types: ['solid2d'], }, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(targetArtifact) || targetArtifact.type !== 'solid2d') { @@ -508,7 +504,7 @@ const prepareToEditSweep: PrepareToEditCallback = async ({ key: operation.labeledArgs.path.value.value.artifactId, types: ['path'], }, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(trajectoryPathArtifact) || trajectoryPathArtifact.type !== 'path') { @@ -520,7 +516,7 @@ const prepareToEditSweep: PrepareToEditCallback = async ({ key: trajectoryPathArtifact.segIds[0], types: ['segment'], }, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(trajectoryArtifact) || trajectoryArtifact.type !== 'segment') { @@ -607,7 +603,7 @@ const prepareToEditHelix: PrepareToEditCallback = async ({ operation }) => { key: axisValue.artifact_id, types: ['segment'], }, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(artifact)) { return { reason: "Couldn't find related edge artifact" } @@ -630,16 +626,13 @@ const prepareToEditHelix: PrepareToEditCallback = async ({ operation }) => { key: axisValue.value, types: ['sweepEdge'], }, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(artifact)) { return { reason: "Couldn't find related edge artifact" } } - const codeRef = getSweepEdgeCodeRef( - artifact, - engineCommandManager.artifactGraph - ) + const codeRef = getSweepEdgeCodeRef(artifact, kclManager.artifactGraph) if (err(codeRef)) { return { reason: "Couldn't find related edge code ref" } } @@ -667,7 +660,7 @@ const prepareToEditHelix: PrepareToEditCallback = async ({ operation }) => { } const sweepId = operation.labeledArgs.cylinder.value.value.artifactId - const wallArtifact = [...engineCommandManager.artifactGraph.values()].find( + const wallArtifact = [...kclManager.artifactGraph.values()].find( (p) => p.type === 'wall' && p.sweepId === sweepId ) if (!wallArtifact || wallArtifact.type !== 'wall') { @@ -676,10 +669,7 @@ const prepareToEditHelix: PrepareToEditCallback = async ({ operation }) => { } } - const wallCodeRef = getWallCodeRef( - wallArtifact, - engineCommandManager.artifactGraph - ) + const wallCodeRef = getWallCodeRef(wallArtifact, kclManager.artifactGraph) if (err(wallCodeRef)) { return { reason: "Cylinder arg found doesn't point to a valid sweep code ref", diff --git a/src/lib/rustContext.ts b/src/lib/rustContext.ts index 765090d1c..4f29bc3cf 100644 --- a/src/lib/rustContext.ts +++ b/src/lib/rustContext.ts @@ -146,16 +146,13 @@ export default class RustContext { return this._defaultPlanes } - // Clear the scene and bust the cache. + // Clear/reset the scene and bust the cache. async clearSceneAndBustCache( settings: DeepPartial, path?: string - ) { - // Send through and empty ast to clear the scene. - // This will also bust the cache and reset the default planes. - // We do it like this so it works better with adding stuff later and the - // cache. - // It also works better with the id generator. + ): Promise { + const instance = await this._checkInstance() + const ast: Node = { body: [], shebang: null, @@ -172,7 +169,23 @@ export default class RustContext { commentStart: 0, } - await this.execute(ast, settings, path) + try { + const result = await instance.bustCacheAndResetScene( + JSON.stringify(settings), + path + ) + /* Set the default planes, safe to call after execute. */ + const outcome = execStateFromRust(result, ast) + + this._defaultPlanes = outcome.defaultPlanes + + // Return the result. + return outcome + } catch (e: any) { + const err = errFromErrWithOutputs(e) + this._defaultPlanes = err.defaultPlanes + return Promise.reject(err) + } } getDefaultPlaneId(name: DefaultPlaneStr): string | Error { diff --git a/src/lib/selections.ts b/src/lib/selections.ts index cb28f32d8..0fb624f17 100644 --- a/src/lib/selections.ts +++ b/src/lib/selections.ts @@ -102,10 +102,10 @@ export async function getEventForSelectWithPoint({ } } - let _artifact = engineCommandManager.artifactGraph.get(data.entity_id) + let _artifact = kclManager.artifactGraph.get(data.entity_id) const codeRefs = getCodeRefsByArtifactId( data.entity_id, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (_artifact && codeRefs) { return { @@ -140,15 +140,15 @@ export function getEventForSegmentSelection( // id does not match up with the artifact graph when in sketch mode, because mock executions // do not update the artifact graph, therefore we match up the pathToNode instead // we can reliably use `type === 'segment'` since it's in sketch mode and we're concerned with segments - const segWithMatchingPathToNode__Id = [ - ...engineCommandManager.artifactGraph, - ].find((entry) => { - return ( - entry[1].type === 'segment' && - JSON.stringify(entry[1].codeRef.pathToNode) === - JSON.stringify(group?.userData?.pathToNode) - ) - })?.[0] + const segWithMatchingPathToNode__Id = [...kclManager.artifactGraph].find( + (entry) => { + return ( + entry[1].type === 'segment' && + JSON.stringify(entry[1].codeRef.pathToNode) === + JSON.stringify(group?.userData?.pathToNode) + ) + } + )?.[0] const id = segWithMatchingPathToNode__Id @@ -172,7 +172,7 @@ export function getEventForSegmentSelection( } } if (!id || !group) return null - const artifact = engineCommandManager.artifactGraph.get(id) + const artifact = kclManager.artifactGraph.get(id) if (!artifact) return null const node = getNodeFromPath(kclManager.ast, group.userData.pathToNode) if (err(node)) return null @@ -208,10 +208,8 @@ export function handleSelectionBatch({ selectionToEngine.push({ id: artifact?.id, range: - getCodeRefsByArtifactId( - artifact.id, - engineCommandManager.artifactGraph - )?.[0].range || defaultSourceRange(), + getCodeRefsByArtifactId(artifact.id, kclManager.artifactGraph)?.[0] + .range || defaultSourceRange(), }) }) const engineEvents: Models['WebSocketRequest_type'][] = @@ -291,7 +289,7 @@ export function processCodeMirrorRanges({ const idBasedSelections: SelectionToEngine[] = codeToIdSelections( codeBasedSelections, artifactGraph, - engineCommandManager.artifactIndex + kclManager.artifactIndex ) const selections: Selection[] = [] for (const { id, range } of idBasedSelections) { @@ -396,10 +394,7 @@ function resetAndSetEngineEntitySelectionCmds( */ export function isSketchPipe(selectionRanges: Selections) { if (!isSingleCursorInPipe(selectionRanges, kclManager.ast)) return false - return isCursorInSketchCommandRange( - engineCommandManager.artifactGraph, - selectionRanges - ) + return isCursorInSketchCommandRange(kclManager.artifactGraph, selectionRanges) } // This accounts for non-geometry selections under "other" @@ -692,12 +687,9 @@ export function updateSelections( if (err(nodeMeta)) return undefined const node = nodeMeta.node let artifact: Artifact | null = null - for (const [id, a] of engineCommandManager.artifactGraph) { + for (const [id, a] of kclManager.artifactGraph) { if (previousSelection?.artifact?.type === a.type) { - const codeRefs = getCodeRefsByArtifactId( - id, - engineCommandManager.artifactGraph - ) + const codeRefs = getCodeRefsByArtifactId(id, kclManager.artifactGraph) if (!codeRefs) continue if ( JSON.stringify(codeRefs[0].pathToNode) === diff --git a/src/lib/settings/initialSettings.tsx b/src/lib/settings/initialSettings.tsx index f266612f3..21bccdb79 100644 --- a/src/lib/settings/initialSettings.tsx +++ b/src/lib/settings/initialSettings.tsx @@ -22,6 +22,7 @@ import { CameraProjectionType } from '@rust/kcl-lib/bindings/CameraProjectionTyp import { OnboardingStatus } from '@rust/kcl-lib/bindings/OnboardingStatus' import { NamedView } from '@rust/kcl-lib/bindings/NamedView' import { CameraOrbitType } from '@rust/kcl-lib/bindings/CameraOrbitType' +import { DEFAULT_DEFAULT_LENGTH_UNIT } from 'lib/constants' /** * A setting that can be set at the user or project level @@ -300,8 +301,9 @@ export function createSettings() { * The default unit to use in modeling dimensions */ defaultUnit: new Setting({ - defaultValue: 'mm', - description: 'The default unit to use in modeling dimensions', + defaultValue: DEFAULT_DEFAULT_LENGTH_UNIT, + description: + 'Set the default length unit setting value to give any new files.', validate: (v) => baseUnitsUnion.includes(v), commandConfig: { inputType: 'options', diff --git a/src/lib/settings/settingsTypes.ts b/src/lib/settings/settingsTypes.ts index 5dc4c1eca..bbf17ec4a 100644 --- a/src/lib/settings/settingsTypes.ts +++ b/src/lib/settings/settingsTypes.ts @@ -145,7 +145,7 @@ export type SaveSettingsPayload = RecursiveSettingsPayloads /** * Annotation names for default units are defined on rust side in - * src/wasm-lib/kcl/src/execution/annotations.rs + * rust/kcl-lib/src/execution/annotations.rs */ export interface KclSettingsAnnotation { defaultLengthUnit?: UnitLength_type diff --git a/src/lib/utils.ts b/src/lib/utils.ts index f41c77756..94ec96d5d 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -4,6 +4,7 @@ import { v4 } from 'uuid' import { isDesktop } from './isDesktop' import { AnyMachineSnapshot } from 'xstate' import { AsyncFn } from './types' +import { Binary as BSONBinary } from 'bson' export const uuidv4 = v4 @@ -406,3 +407,65 @@ export function isClockwise(points: [number, number][]): boolean { // If sum is positive, the points are in clockwise order return sum > 0 } + +/** + * Converts a binary buffer to a UUID string. + * + * @param buffer - The binary buffer containing the UUID bytes. + * @returns A string representation of the UUID in the format 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'. + */ +export function binaryToUuid( + binaryData: Buffer | Uint8Array | BSONBinary | string +): string { + if (typeof binaryData === 'string') { + return binaryData + } + + let buffer: Uint8Array + + // Handle MongoDB BSON Binary object + if ( + binaryData && + '_bsontype' in binaryData && + binaryData._bsontype === 'Binary' + ) { + // Extract the buffer from the BSON Binary object + buffer = binaryData.buffer + } + // Handle case where buffer property exists (some MongoDB drivers structure) + else if (binaryData && binaryData.buffer instanceof Uint8Array) { + buffer = binaryData.buffer + } + // Handle direct Buffer or Uint8Array + else if (binaryData instanceof Uint8Array || Buffer.isBuffer(binaryData)) { + buffer = binaryData + } else { + console.error( + 'Invalid input type: expected MongoDB BSON Binary, Buffer, or Uint8Array' + ) + return '' + } + + // Ensure we have exactly 16 bytes (128 bits) for a UUID + if (buffer.length !== 16) { + // For debugging + console.log('Buffer length:', buffer.length) + console.log('Buffer content:', Array.from(buffer)) + console.error('UUID must be exactly 16 bytes') + return '' + } + + // Convert each byte to a hex string and pad with zeros if needed + const hexValues = Array.from(buffer).map((byte) => + byte.toString(16).padStart(2, '0') + ) + + // Format into UUID structure (8-4-4-4-12 characters) + return [ + hexValues.slice(0, 4).join(''), + hexValues.slice(4, 6).join(''), + hexValues.slice(6, 8).join(''), + hexValues.slice(8, 10).join(''), + hexValues.slice(10, 16).join(''), + ].join('-') +} diff --git a/src/lib/wasm_lib_wrapper.ts b/src/lib/wasm_lib_wrapper.ts index 6b972e01b..8dbddd847 100644 --- a/src/lib/wasm_lib_wrapper.ts +++ b/src/lib/wasm_lib_wrapper.ts @@ -22,6 +22,7 @@ import { base64_decode as Base64Decode, kcl_settings as KclSettings, change_kcl_settings as ChangeKclSettings, + is_kcl_empty_or_only_settings as IsKclEmptyOrOnlySettings, get_kcl_version as GetKclVersion, serialize_configuration as SerializeConfiguration, serialize_project_configuration as SerializeProjectConfiguration, @@ -93,6 +94,11 @@ export const kcl_settings: typeof KclSettings = (...args) => { export const change_kcl_settings: typeof ChangeKclSettings = (...args) => { return getModule().change_kcl_settings(...args) } +export const is_kcl_empty_or_only_settings: typeof IsKclEmptyOrOnlySettings = ( + ...args +) => { + return getModule().is_kcl_empty_or_only_settings(...args) +} export const get_kcl_version: typeof GetKclVersion = () => { return getModule().get_kcl_version() } diff --git a/src/machines/featureTreeMachine.ts b/src/machines/featureTreeMachine.ts index c69cd3f71..b436a2a38 100644 --- a/src/machines/featureTreeMachine.ts +++ b/src/machines/featureTreeMachine.ts @@ -5,7 +5,7 @@ import { enterEditFlow, EnterEditFlowProps, } from 'lib/operations' -import { engineCommandManager, kclManager } from 'lib/singletons' +import { kclManager } from 'lib/singletons' import { err } from 'lib/trap' import toast from 'react-hot-toast' import { Operation } from '@rust/kcl-lib/bindings/Operation' @@ -275,7 +275,7 @@ export const featureTreeMachine = setup({ const artifact = context.targetSourceRange ? getArtifactFromRange( context.targetSourceRange, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) ?? undefined : undefined return { @@ -329,7 +329,7 @@ export const featureTreeMachine = setup({ const artifact = context.targetSourceRange ? getArtifactFromRange( context.targetSourceRange, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) ?? undefined : undefined return { @@ -383,7 +383,7 @@ export const featureTreeMachine = setup({ const artifact = context.targetSourceRange ? getArtifactFromRange( context.targetSourceRange, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) ?? undefined : undefined return { diff --git a/src/machines/fileMachine.ts b/src/machines/fileMachine.ts index e067d85dc..f628ed643 100644 --- a/src/machines/fileMachine.ts +++ b/src/machines/fileMachine.ts @@ -126,7 +126,7 @@ export const fileMachine = setup({ makeDir: boolean selectedDirectory: FileEntry targetPathToClone?: string - content: string + content?: string shouldSetToRename: boolean } }) => Promise.resolve({ message: '', path: '' }) @@ -152,7 +152,7 @@ export const fileMachine = setup({ name: string makeDir: boolean selectedDirectory: FileEntry - content: string + content?: string } }) => Promise.resolve({ path: '' }) ), @@ -238,7 +238,7 @@ export const fileMachine = setup({ makeDir: event.data.makeDir, selectedDirectory: context.selectedDirectory, targetPathToClone: event.data.targetPathToClone, - content: event.data.content ?? '', + content: event.data.content, shouldSetToRename: event.data.shouldSetToRename ?? false, } }, @@ -417,7 +417,7 @@ export const fileMachine = setup({ name: event.data.name, makeDir: event.data.makeDir, selectedDirectory: context.selectedDirectory, - content: event.data.content ?? '', + content: event.data.content, } }, onDone: 'Reading files', diff --git a/src/machines/modelingMachine.ts b/src/machines/modelingMachine.ts index 89df9db32..f9681abc4 100644 --- a/src/machines/modelingMachine.ts +++ b/src/machines/modelingMachine.ts @@ -766,7 +766,7 @@ export const modelingMachine = setup({ axisOrEdge, axis, edge, - engineCommandManager.artifactGraph, + kclManager.artifactGraph, selection.graphSelections[0]?.artifact ) if (trap(revolveSketchRes)) return @@ -1123,9 +1123,7 @@ export const modelingMachine = setup({ }), 're-eval nodePaths': assign(({ context: { sketchDetails } }) => { if (!sketchDetails) return {} - const planeArtifact = [ - ...engineCommandManager.artifactGraph.values(), - ].find( + const planeArtifact = [...kclManager.artifactGraph.values()].find( (artifact) => artifact.type === 'plane' && stringifyPathToNode(artifact.codeRef.pathToNode) === @@ -1134,7 +1132,7 @@ export const modelingMachine = setup({ if (planeArtifact?.type !== 'plane') return {} const newPaths = getPathsFromPlaneArtifact( planeArtifact, - engineCommandManager.artifactGraph, + kclManager.artifactGraph, kclManager.ast ) return { @@ -1794,7 +1792,7 @@ export const modelingMachine = setup({ node: ast, pathToNode, artifact: selection.graphSelections[0].artifact, - artifactGraph: engineCommandManager.artifactGraph, + artifactGraph: kclManager.artifactGraph, distance: 'variableName' in distance ? distance.variableIdentifierAst @@ -1987,7 +1985,7 @@ export const modelingMachine = setup({ const extrudeLookupResult = getPathToExtrudeForSegmentSelection( clonedAstForGetExtrude, cylinder.graphSelections[0], - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(extrudeLookupResult)) { return extrudeLookupResult @@ -2249,7 +2247,7 @@ export const modelingMachine = setup({ const extrudeLookupResult = getPathToExtrudeForSegmentSelection( clonedAstForGetExtrude, graphSelection, - engineCommandManager.artifactGraph + kclManager.artifactGraph ) if (err(extrudeLookupResult)) { return new Error( diff --git a/src/routes/Onboarding/Introduction.tsx b/src/routes/Onboarding/Introduction.tsx index b4a9e052e..c3103d12c 100644 --- a/src/routes/Onboarding/Introduction.tsx +++ b/src/routes/Onboarding/Introduction.tsx @@ -14,6 +14,7 @@ import { useFileContext } from 'hooks/useFileContext' import { useLspContext } from 'components/LspProvider' import { reportRejection } from 'lib/trap' import { useSettings } from 'machines/appMachine' +import { isKclEmptyOrOnlySettings } from 'lang/wasm' /** * Show either a welcome screen or a warning screen @@ -21,7 +22,7 @@ import { useSettings } from 'machines/appMachine' */ export default function OnboardingIntroduction() { const [shouldShowWarning, setShouldShowWarning] = useState( - codeManager.code !== '' && codeManager.code !== bracket + !isKclEmptyOrOnlySettings(codeManager.code) && codeManager.code !== bracket ) return shouldShowWarning ? ( diff --git a/src/routes/SignIn.tsx b/src/routes/SignIn.tsx index 50088f929..3b3710f6e 100644 --- a/src/routes/SignIn.tsx +++ b/src/routes/SignIn.tsx @@ -104,21 +104,11 @@ const SignIn = () => {

- Thank you for using our hardware design application. It is built - on a novel CAD engine and crafted to help you create parametric, - version-controlled, and accurate parts ready for manufacturing. -

-

- As alpha software, Zoo Modeling App is still in heavy development. - We encourage feedback and feature requests that align with{' '} - - our roadmap to v1.0 - - . + Thank you for using our CAD application. It is built on a novel + geometry engine and crafted to help you create robust parametric + designs. It represents your models as code, making it easy to + collaborate with ML tools like Zoo Text-To-CAD to design parts and + libraries fast.

{isDesktop() ? (
@@ -206,7 +196,7 @@ const SignIn = () => {
-

Built in the open

+

Built in the open

Open-source and open discussions. Check our public code base and join our Discord. @@ -215,23 +205,26 @@ const SignIn = () => { Read our source code Join our community

-

Ready for the future

+

Ready for the future

Modern software ideas being brought together to create a familiar modeling experience with new superpowers. @@ -240,8 +233,11 @@ const SignIn = () => { Parametric design with KCL @@ -250,15 +246,18 @@ const SignIn = () => { AI-unlocked CAD

-

+

Built on the first infrastructure for hardware design

@@ -270,16 +269,19 @@ const SignIn = () => { KittyCAD Design API ML-ephant Machine Learning API diff --git a/yarn.lock b/yarn.lock index d94de67f3..102b37a20 100644 --- a/yarn.lock +++ b/yarn.lock @@ -47,21 +47,21 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.8.tgz#821c1d35641c355284d4a870b8a4a7b0c141e367" integrity sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ== -"@babel/core@^7.21.4", "@babel/core@^7.24.5": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.2.tgz#ed8eec275118d7613e77a352894cd12ded8eba77" - integrity sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA== +"@babel/core@^7.21.4", "@babel/core@^7.26.0": + version "7.26.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.10.tgz#5c876f83c8c4dcb233ee4b670c0606f2ac3000f9" + integrity sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.25.0" - "@babel/helper-compilation-targets" "^7.25.2" - "@babel/helper-module-transforms" "^7.25.2" - "@babel/helpers" "^7.25.0" - "@babel/parser" "^7.25.0" - "@babel/template" "^7.25.0" - "@babel/traverse" "^7.25.2" - "@babel/types" "^7.25.2" + "@babel/code-frame" "^7.26.2" + "@babel/generator" "^7.26.10" + "@babel/helper-compilation-targets" "^7.26.5" + "@babel/helper-module-transforms" "^7.26.0" + "@babel/helpers" "^7.26.10" + "@babel/parser" "^7.26.10" + "@babel/template" "^7.26.9" + "@babel/traverse" "^7.26.10" + "@babel/types" "^7.26.10" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" @@ -89,6 +89,17 @@ "@jridgewell/trace-mapping" "^0.3.25" jsesc "^3.0.2" +"@babel/generator@^7.27.0": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.27.0.tgz#764382b5392e5b9aff93cadb190d0745866cbc2c" + integrity sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw== + dependencies: + "@babel/parser" "^7.27.0" + "@babel/types" "^7.27.0" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^3.0.2" + "@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz#5373c7bc8366b12a033b4be1ac13a206c6656aab" @@ -103,7 +114,7 @@ dependencies: "@babel/types" "^7.25.9" -"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.25.2", "@babel/helper-compilation-targets@^7.25.9", "@babel/helper-compilation-targets@^7.26.5": +"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.25.9", "@babel/helper-compilation-targets@^7.26.5": version "7.26.5" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz#75d92bb8d8d51301c0d49e52a65c9a7fe94514d8" integrity sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA== @@ -196,14 +207,6 @@ "@babel/traverse" "^7.25.9" "@babel/types" "^7.25.9" -"@babel/helper-module-imports@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" - integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== - dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" - "@babel/helper-module-imports@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715" @@ -212,16 +215,6 @@ "@babel/traverse" "^7.25.9" "@babel/types" "^7.25.9" -"@babel/helper-module-transforms@^7.25.2": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz#ee713c29768100f2776edf04d4eb23b8d27a66e6" - integrity sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ== - dependencies: - "@babel/helper-module-imports" "^7.24.7" - "@babel/helper-simple-access" "^7.24.7" - "@babel/helper-validator-identifier" "^7.24.7" - "@babel/traverse" "^7.25.2" - "@babel/helper-module-transforms@^7.25.9", "@babel/helper-module-transforms@^7.26.0": version "7.26.0" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz#8ce54ec9d592695e58d84cd884b7b5c6a2fdeeae" @@ -245,7 +238,7 @@ dependencies: "@babel/types" "^7.25.9" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.25.9", "@babel/helper-plugin-utils@^7.26.5": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.25.9", "@babel/helper-plugin-utils@^7.26.5": version "7.26.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz#18580d00c9934117ad719392c4f6585c9333cc35" integrity sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg== @@ -277,14 +270,6 @@ "@babel/helper-optimise-call-expression" "^7.25.9" "@babel/traverse" "^7.26.5" -"@babel/helper-simple-access@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz#bcade8da3aec8ed16b9c4953b74e506b51b5edb3" - integrity sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg== - dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" - "@babel/helper-skip-transparent-expression-wrappers@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz#5f8fa83b69ed5c27adc56044f8be2b3ea96669d9" @@ -335,13 +320,13 @@ "@babel/traverse" "^7.25.9" "@babel/types" "^7.25.9" -"@babel/helpers@^7.25.0": - version "7.26.10" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.10.tgz#6baea3cd62ec2d0c1068778d63cb1314f6637384" - integrity sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g== +"@babel/helpers@^7.26.10": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.27.0.tgz#53d156098defa8243eab0f32fa17589075a1b808" + integrity sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg== dependencies: - "@babel/template" "^7.26.9" - "@babel/types" "^7.26.10" + "@babel/template" "^7.27.0" + "@babel/types" "^7.27.0" "@babel/highlight@^7.24.7": version "7.24.7" @@ -367,6 +352,13 @@ dependencies: "@babel/types" "^7.26.10" +"@babel/parser@^7.27.0": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.27.0.tgz#3d7d6ee268e41d2600091cbd4e145ffee85a44ec" + integrity sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg== + dependencies: + "@babel/types" "^7.27.0" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz#cc2e53ebf0a0340777fff5ed521943e253b4d8fe" @@ -747,19 +739,19 @@ dependencies: "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-react-jsx-self@^7.24.5": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz#66bff0248ea0b549972e733516ffad577477bdab" - integrity sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw== +"@babel/plugin-transform-react-jsx-self@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz#c0b6cae9c1b73967f7f9eb2fca9536ba2fad2858" + integrity sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-react-jsx-source@^7.24.1": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz#1198aab2548ad19582013815c938d3ebd8291ee3" - integrity sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ== +"@babel/plugin-transform-react-jsx-source@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz#4c6b8daa520b5f155b5fb55547d7c9fa91417503" + integrity sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" "@babel/plugin-transform-regenerator@^7.25.9": version "7.25.9" @@ -965,7 +957,16 @@ "@babel/parser" "^7.26.9" "@babel/types" "^7.26.9" -"@babel/traverse@^7.21.4", "@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.2": +"@babel/template@^7.27.0": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.0.tgz#b253e5406cc1df1c57dcd18f11760c2dbf40c0b4" + integrity sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA== + dependencies: + "@babel/code-frame" "^7.26.2" + "@babel/parser" "^7.27.0" + "@babel/types" "^7.27.0" + +"@babel/traverse@^7.21.4", "@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0": version "7.25.3" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.3.tgz#f1b901951c83eda2f3e29450ce92743783373490" integrity sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ== @@ -991,6 +992,19 @@ debug "^4.3.1" globals "^11.1.0" +"@babel/traverse@^7.26.10": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.27.0.tgz#11d7e644779e166c0442f9a07274d02cd91d4a70" + integrity sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA== + dependencies: + "@babel/code-frame" "^7.26.2" + "@babel/generator" "^7.27.0" + "@babel/parser" "^7.27.0" + "@babel/template" "^7.27.0" + "@babel/types" "^7.27.0" + debug "^4.3.1" + globals "^11.1.0" + "@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.21.4", "@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.25.0", "@babel/types@^7.25.2", "@babel/types@^7.4.4": version "7.25.2" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.2.tgz#55fb231f7dc958cd69ea141a4c2997e819646125" @@ -1008,6 +1022,14 @@ "@babel/helper-string-parser" "^7.25.9" "@babel/helper-validator-identifier" "^7.25.9" +"@babel/types@^7.27.0": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.0.tgz#ef9acb6b06c3173f6632d993ecb6d4ae470b4559" + integrity sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg== + dependencies: + "@babel/helper-string-parser" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@codemirror/autocomplete@^6.0.0", "@codemirror/autocomplete@^6.18.6": version "6.18.6" resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz#de26e864a1ec8192a1b241eb86addbb612964ddb" @@ -1018,10 +1040,10 @@ "@codemirror/view" "^6.17.0" "@lezer/common" "^1.0.0" -"@codemirror/commands@^6.0.0", "@codemirror/commands@^6.8.0": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-6.8.0.tgz#92f200b66f852939bd6ebb90d48c2d9e9c813d64" - integrity sha512-q8VPEFaEP4ikSlt6ZxjB3zW72+7osfAYW9i8Zu943uqbKuz6utc1+F170hyLUCUltXORjQXRyYQNfkckzA/bPQ== +"@codemirror/commands@^6.0.0", "@codemirror/commands@^6.8.1": + version "6.8.1" + resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-6.8.1.tgz#639f5559d2f33f2582a2429c58cb0c1b925c7a30" + integrity sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw== dependencies: "@codemirror/language" "^6.0.0" "@codemirror/state" "^6.4.0" @@ -1040,10 +1062,10 @@ "@lezer/lr" "^1.0.0" style-mod "^4.0.0" -"@codemirror/lint@^6.0.0", "@codemirror/lint@^6.8.4": - version "6.8.4" - resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-6.8.4.tgz#7d8aa5d1a6dec89ffcc23ad45ddca2e12e90982d" - integrity sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A== +"@codemirror/lint@^6.0.0", "@codemirror/lint@^6.8.5": + version "6.8.5" + resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-6.8.5.tgz#9edaa808e764e28e07665b015951934c8ec3a418" + integrity sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA== dependencies: "@codemirror/state" "^6.0.0" "@codemirror/view" "^6.35.0" @@ -1058,10 +1080,10 @@ "@codemirror/view" "^6.0.0" crelt "^1.0.5" -"@codemirror/state@^6.0.0", "@codemirror/state@^6.2.1", "@codemirror/state@^6.4.0", "@codemirror/state@^6.4.1", "@codemirror/state@^6.5.0": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.5.0.tgz#e98dde85620618651543152fe1c2483300a0ccc9" - integrity sha512-MwBHVK60IiIHDcoMet78lxt6iw5gJOGSbNbOIVBHWVXIH4/Nq1+GQgLLGgI1KlnN86WDXsPudVaqYHKBIx7Eyw== +"@codemirror/state@^6.0.0", "@codemirror/state@^6.2.1", "@codemirror/state@^6.4.0", "@codemirror/state@^6.5.0", "@codemirror/state@^6.5.2": + version "6.5.2" + resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.5.2.tgz#8eca3a64212a83367dc85475b7d78d5c9b7076c6" + integrity sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA== dependencies: "@marijn/find-cluster-break" "^1.0.0" @@ -1091,23 +1113,23 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@csstools/color-helpers@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@csstools/color-helpers/-/color-helpers-5.0.1.tgz#829f1c76f5800b79c51c709e2f36821b728e0e10" - integrity sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA== +"@csstools/color-helpers@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@csstools/color-helpers/-/color-helpers-5.0.2.tgz#82592c9a7c2b83c293d9161894e2a6471feb97b8" + integrity sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA== -"@csstools/css-calc@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@csstools/css-calc/-/css-calc-2.1.1.tgz#a7dbc66627f5cf458d42aed14bda0d3860562383" - integrity sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag== +"@csstools/css-calc@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@csstools/css-calc/-/css-calc-2.1.2.tgz#bffd55f002dab119b76d4023f95cd943e6c8c11e" + integrity sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw== -"@csstools/css-color-parser@^3.0.7": - version "3.0.7" - resolved "https://registry.yarnpkg.com/@csstools/css-color-parser/-/css-color-parser-3.0.7.tgz#442d61d58e54ad258d52c309a787fceb33906484" - integrity sha512-nkMp2mTICw32uE5NN+EsJ4f5N+IGFeCFu4bGpiKgb2Pq/7J/MpyLBeQ5ry4KKtRFZaYs6sTmcMYrSRIyj5DFKA== +"@csstools/css-color-parser@^3.0.8": + version "3.0.8" + resolved "https://registry.yarnpkg.com/@csstools/css-color-parser/-/css-color-parser-3.0.8.tgz#5fe9322920851450bf5e065c2b0e731b9e165394" + integrity sha512-pdwotQjCCnRPuNi06jFuP68cykU1f3ZWExLe/8MQ1LOs8Xq+fTkYgd+2V8mWUWMrOn9iS2HftPVaMZDaXzGbhQ== dependencies: - "@csstools/color-helpers" "^5.0.1" - "@csstools/css-calc" "^2.1.1" + "@csstools/color-helpers" "^5.0.2" + "@csstools/css-calc" "^2.1.2" "@csstools/css-parser-algorithms@^3.0.4": version "3.0.4" @@ -1119,12 +1141,12 @@ resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz#a5502c8539265fecbd873c1e395a890339f119c2" integrity sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw== -"@csstools/postcss-oklab-function@^4.0.7": - version "4.0.7" - resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.7.tgz#33b3322dfb27b0b5eb83a7ad36e67f08bc4e66cd" - integrity sha512-I6WFQIbEKG2IO3vhaMGZDkucbCaUSXMxvHNzDdnfsTCF5tc0UlV3Oe2AhamatQoKFjBi75dSEMrgWq3+RegsOQ== +"@csstools/postcss-oklab-function@^4.0.8": + version "4.0.8" + resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.8.tgz#9d723e0db69703f3df549ebedfd605f849217fff" + integrity sha512-+5aPsNWgxohXoYNS1f+Ys0x3Qnfehgygv3qrPyv+Y25G0yX54/WlVB+IXprqBLOXHM1gsVF+QQSjlArhygna0Q== dependencies: - "@csstools/css-color-parser" "^3.0.7" + "@csstools/css-color-parser" "^3.0.8" "@csstools/css-parser-algorithms" "^3.0.4" "@csstools/css-tokenizer" "^3.0.3" "@csstools/postcss-progressive-custom-properties" "^4.0.0" @@ -1737,10 +1759,10 @@ "@tanstack/react-virtual" "^3.0.0-beta.60" client-only "^0.0.1" -"@headlessui/tailwindcss@^0.2.0": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@headlessui/tailwindcss/-/tailwindcss-0.2.1.tgz#1becc201f69358a40e08bd676acc234b2cabe6e4" - integrity sha512-2+5+NZ+RzMyrVeCZOxdbvkUSssSxGvcUxphkIfSVLpRiKsj+/63T2TOL9dBYMXVfj/CGr6hMxSRInzXv6YY7sA== +"@headlessui/tailwindcss@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@headlessui/tailwindcss/-/tailwindcss-0.2.2.tgz#8ebde73fabca72d48636ea56ae790209dc5f0d49" + integrity sha512-xNe42KjdyA4kfUKLLPGzME9zkH7Q3rOZ5huFihWNWOQFxnItxPB3/67yBI8/qBfY8nwBRx5GHn4VprsoluVMGw== "@humanwhocodes/config-array@^0.11.14": version "0.11.14" @@ -1844,10 +1866,10 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@kittycad/lib@2.0.21": - version "2.0.21" - resolved "https://registry.yarnpkg.com/@kittycad/lib/-/lib-2.0.21.tgz#b5ccb03367f4478896e5ef14221a8512d15ea4d4" - integrity sha512-JK2lAJm22GEVKX1Q57M2Pbnqzt8vmaXHec/9MDGIodnzWB36QEEs4VVVTIlJNbjoYoa+au5feakjTXUiuLu2cg== +"@kittycad/lib@2.0.23": + version "2.0.23" + resolved "https://registry.yarnpkg.com/@kittycad/lib/-/lib-2.0.23.tgz#0d215d458b35f6d207eeb90443889fa77b21b913" + integrity sha512-5T7+gHB21RX5bE7ILp3TnLzp0rA7CP1BucNctHynANG/sXV44tD7U8YEcQsi+/ZmMkvrxmZ/3r/UQjgzhQUh7w== dependencies: openapi-types "^12.0.0" ts-node "^10.9.1" @@ -1958,12 +1980,12 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== -"@playwright/test@^1.51.0": - version "1.51.0" - resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.51.0.tgz#8d5c8400b465a0bfdbcf993e390ceecb903ea6d2" - integrity sha512-dJ0dMbZeHhI+wb77+ljx/FeC8VBP6j/rj9OAojO08JI80wTZy6vRk9KvHKiDCUh4iMpEiseMgqRBIeW+eKX6RA== +"@playwright/test@^1.51.1": + version "1.51.1" + resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.51.1.tgz#75357d513221a7be0baad75f01e966baf9c41a2e" + integrity sha512-nM+kEaTSAoVlXmMPH10017vn3FSiFqr/bh4fKg9vmAdMfd9SDqRZNvPSiAHADc/itWak+qPvMPZQOPwCBW7k7Q== dependencies: - playwright "1.51.0" + playwright "1.51.1" "@react-hook/latest@^1.0.2": version "1.0.3" @@ -2340,10 +2362,10 @@ dependencies: "@types/ms" "*" -"@types/diff@^7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/@types/diff/-/diff-7.0.1.tgz#acc505eb2e8337ca400503283a6ab44a59906d9f" - integrity sha512-R/BHQFripuhW6XPXy05hIvXJQdQ4540KnTvEFHSLjXfHYM41liOLKgIJEyYYiQe796xpaMHfe4Uj/p7Uvng2vA== +"@types/diff@^7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/diff/-/diff-7.0.2.tgz#d638edebf3c97aa4962b6f1164a7921ab3de9f83" + integrity sha512-JSWRMozjFKsGlEjiiKajUjIJVKuKdE3oVy2DNtK+fUo8q82nhFZ2CPQwicAIkXrofahDXrWJ7mjelvZphMS98Q== "@types/electron@^1.6.10": version "1.6.10" @@ -2446,10 +2468,10 @@ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== -"@types/node@*", "@types/node@^22.13.9": - version "22.13.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.9.tgz#5d9a8f7a975a5bd3ef267352deb96fb13ec02eca" - integrity sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw== +"@types/node@*", "@types/node@^22.13.14": + version "22.13.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.14.tgz#70d84ec91013dcd2ba2de35532a5a14c2b4cc912" + integrity sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w== dependencies: undici-types "~6.20.0" @@ -2570,10 +2592,10 @@ resolved "https://registry.yarnpkg.com/@types/wicg-file-system-access/-/wicg-file-system-access-2023.10.5.tgz#14b3c25eb4d914b5734795bdea71da229f918b9d" integrity sha512-e9kZO9kCdLqT2h9Tw38oGv9UNzBBWaR1MzuAavxPcsV/7FJ3tWbU6RI3uB+yKIDPGLkGVbplS52ub0AcRLvrhA== -"@types/ws@^8.5.13": - version "8.5.13" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.13.tgz#6414c280875e2691d0d1e080b05addbf5cb91e20" - integrity sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA== +"@types/ws@^8.18.0": + version "8.18.0" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5" + integrity sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw== dependencies: "@types/node" "*" @@ -2703,14 +2725,14 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== -"@vitejs/plugin-react@^4.3.0": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz#d0be6594051ded8957df555ff07a991fb618b48e" - integrity sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg== +"@vitejs/plugin-react@^4.3.4": + version "4.3.4" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz#c64be10b54c4640135a5b28a2432330e88ad7c20" + integrity sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug== dependencies: - "@babel/core" "^7.24.5" - "@babel/plugin-transform-react-jsx-self" "^7.24.5" - "@babel/plugin-transform-react-jsx-source" "^7.24.1" + "@babel/core" "^7.26.0" + "@babel/plugin-transform-react-jsx-self" "^7.25.9" + "@babel/plugin-transform-react-jsx-source" "^7.25.9" "@types/babel__core" "^7.20.5" react-refresh "^0.14.2" @@ -2954,10 +2976,10 @@ app-builder-bin@5.0.0-alpha.12: resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz#2daf82f8badc698e0adcc95ba36af4ff0650dc80" integrity sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w== -app-builder-lib@26.0.7: - version "26.0.7" - resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-26.0.7.tgz#c930a624c8184b39c1974b27505f84eaf89d17b7" - integrity sha512-Sa6qGtt2l9of+KEA2fxdRBNLcWld74xgaP+U3Zr3A0R529Z2jPfUTmLi0dDY3jwRF6uOrsQAEkN+JWWvw5WpPw== +app-builder-lib@26.0.12: + version "26.0.12" + resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-26.0.12.tgz#2e33df936e0f78d4266b058ece90308ea981eefb" + integrity sha512-+/CEPH1fVKf6HowBUs6LcAIoRcjeqgvAeoSE+cl7Y7LndyQ9ViGPYibNk7wmhMHzNgHIuIbw4nWADPO+4mjgWw== dependencies: "@develar/schema-utils" "~2.6.5" "@electron/asar" "3.2.18" @@ -2969,7 +2991,7 @@ app-builder-lib@26.0.7: "@malept/flatpak-bundler" "^0.4.0" "@types/fs-extra" "9.0.13" async-exit-hook "^2.0.1" - builder-util "26.0.7" + builder-util "26.0.11" builder-util-runtime "9.3.1" chromium-pickle-js "^0.2.0" config-file-ts "0.2.8-rc1" @@ -2977,7 +2999,7 @@ app-builder-lib@26.0.7: dotenv "^16.4.5" dotenv-expand "^11.0.6" ejs "^3.1.8" - electron-publish "26.0.7" + electron-publish "26.0.11" fs-extra "^10.1.0" hosted-git-info "^4.1.0" is-ci "^3.0.0" @@ -2986,6 +3008,7 @@ app-builder-lib@26.0.7: json5 "^2.2.3" lazy-val "^1.0.5" minimatch "^10.0.0" + plist "3.1.0" resedit "^1.7.0" semver "^7.3.8" tar "^6.1.12" @@ -3198,16 +3221,16 @@ author-regex@^1.0.0: resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450" integrity sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g== -autoprefixer@^10.4.19: - version "10.4.19" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.19.tgz#ad25a856e82ee9d7898c59583c1afeb3fa65f89f" - integrity sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew== +autoprefixer@^10.4.21: + version "10.4.21" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.21.tgz#77189468e7a8ad1d9a37fbc08efc9f480cf0a95d" + integrity sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ== dependencies: - browserslist "^4.23.0" - caniuse-lite "^1.0.30001599" + browserslist "^4.24.4" + caniuse-lite "^1.0.30001702" fraction.js "^4.3.7" normalize-range "^0.1.2" - picocolors "^1.0.0" + picocolors "^1.1.1" postcss-value-parser "^4.2.0" available-typed-arrays@^1.0.7: @@ -3350,16 +3373,6 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.23.0: - version "4.23.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.2.tgz#244fe803641f1c19c28c48c4b6ec9736eb3d32ed" - integrity sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA== - dependencies: - caniuse-lite "^1.0.30001640" - electron-to-chromium "^1.4.820" - node-releases "^2.0.14" - update-browserslist-db "^1.1.0" - browserslist@^4.24.0, browserslist@^4.24.4: version "4.24.4" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.4.tgz#c6b2865a3f08bcb860a0e827389003b9fe686e4b" @@ -3401,10 +3414,10 @@ builder-util-runtime@9.3.1: debug "^4.3.4" sax "^1.2.4" -builder-util@26.0.7: - version "26.0.7" - resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-26.0.7.tgz#ca420095038d30bd60c4bb1bc3c6879334b0f6cd" - integrity sha512-rZL8wTMtpAM8CZO4l6eIM36oie95LP7de4nEp7ZhQ94JsL7kKT4orPwp6weRzxldXPzNyalUPkhCxJcFDanFIg== +builder-util@26.0.11: + version "26.0.11" + resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-26.0.11.tgz#ad85b92c93f2b976b973e1d87337e0c6813fcb8f" + integrity sha512-xNjXfsldUEe153h1DraD0XvDOpqGR0L5eKFkdReB7eFW5HqysDZFfly4rckda6y9dF39N3pkPlOblcfHKGw+uA== dependencies: "7zip-bin" "~5.2.0" "@types/debug" "^4.1.6" @@ -3523,15 +3536,10 @@ camelcase-css@^2.0.1: resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== -caniuse-lite@^1.0.30001599, caniuse-lite@^1.0.30001640: - version "1.0.30001646" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001646.tgz#d472f2882259ba032dd73ee069ff01bfd059b25d" - integrity sha512-dRg00gudiBDDTmUhClSdv3hqRfpbOnU28IpI1T6PBTLWa+kOj0681C8uML3PifYfREuBrVjDGhL3adYpBT6spw== - -caniuse-lite@^1.0.30001688: - version "1.0.30001705" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001705.tgz#dc3510bcdef261444ca944b7be9c8d0bb7fafeef" - integrity sha512-S0uyMMiYvA7CxNgomYBwwwPUnWzFD83f3B1ce5jHUfHTH//QL6hHsreI8RVC5606R4ssqravelYO5TU6t8sEyg== +caniuse-lite@^1.0.30001688, caniuse-lite@^1.0.30001702: + version "1.0.30001707" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz#c5e104d199e6f4355a898fcd995a066c7eb9bf41" + integrity sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw== chai@^4.3.10: version "4.5.0" @@ -3593,10 +3601,10 @@ chokidar@^3.5.3, chokidar@^3.6.0: optionalDependencies: fsevents "~2.3.2" -chokidar@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.1.tgz#4a6dff66798fb0f72a94f616abbd7e1a19f31d41" - integrity sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA== +chokidar@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30" + integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA== dependencies: readdirp "^4.0.1" @@ -4124,13 +4132,13 @@ dlv@^1.1.3: resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== -dmg-builder@26.0.7: - version "26.0.7" - resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-26.0.7.tgz#f1a2d7dcfd7cfdc143cabdaf78e9f94df9ce98a3" - integrity sha512-fsMjG/TmwcC7HzjSNi+3mlEUgo0RrWwq44VB9XKcGtTPPfqfSi3JvhWCCsAWzElZ0OtSO/DnK/TNgSqyaG/Ajw== +dmg-builder@26.0.12: + version "26.0.12" + resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-26.0.12.tgz#6996ad0bab80a861c9a7b33ee9734d4f60566b46" + integrity sha512-59CAAjAhTaIMCN8y9kD573vDkxbs1uhDcrFLHSgutYdPcGOU35Rf95725snvzEOy4BFB7+eLJ8djCNPmGwG67w== dependencies: - app-builder-lib "26.0.7" - builder-util "26.0.7" + app-builder-lib "26.0.12" + builder-util "26.0.11" builder-util-runtime "9.3.1" fs-extra "^10.1.0" iconv-lite "^0.6.2" @@ -4221,29 +4229,29 @@ ejs@^3.1.8: dependencies: jake "^10.8.5" -electron-builder@^26.0.6: - version "26.0.7" - resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-26.0.7.tgz#4f6724f41735b919514cd1b7462be7eb2d37078a" - integrity sha512-nVSaWw3dMLGGLrI/7WSifYzNGNseIpvmFwBRwi2E8tOUkcqN+em+3qYeRq8k/AYHRDcrmj6UCJJT6rBo+bikfw== +electron-builder@^26.0.12: + version "26.0.12" + resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-26.0.12.tgz#797af2e70efdd96c9ea5d8a8164b8728c90d65ff" + integrity sha512-cD1kz5g2sgPTMFHjLxfMjUK5JABq3//J4jPswi93tOPFz6btzXYtK5NrDt717NRbukCUDOrrvmYVOWERlqoiXA== dependencies: - app-builder-lib "26.0.7" - builder-util "26.0.7" + app-builder-lib "26.0.12" + builder-util "26.0.11" builder-util-runtime "9.3.1" chalk "^4.1.2" - dmg-builder "26.0.7" + dmg-builder "26.0.12" fs-extra "^10.1.0" is-ci "^3.0.0" lazy-val "^1.0.5" simple-update-notifier "2.0.0" yargs "^17.6.2" -electron-publish@26.0.7: - version "26.0.7" - resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-26.0.7.tgz#b16cd31122233c228c4459cc7ab8dc25c67b6cb3" - integrity sha512-zSCBtAXnLi1QhCDEomIEu22mjKgsf17VYW3fMyZ4Y9Q7s+Ftu9dqbTMaM/e/FBCn9VthnG7C/zPCr1yKpkI+dg== +electron-publish@26.0.11: + version "26.0.11" + resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-26.0.11.tgz#92c9329a101af2836d9d228c82966eca1eee9a7b" + integrity sha512-a8QRH0rAPIWH9WyyS5LbNvW9Ark6qe63/LqDB7vu2JXYpi0Gma5Q60Dh4tmTqhOBQt0xsrzD8qE7C+D7j+B24A== dependencies: "@types/fs-extra" "^9.0.11" - builder-util "26.0.7" + builder-util "26.0.11" builder-util-runtime "9.3.1" chalk "^4.1.2" form-data "^4.0.0" @@ -4251,20 +4259,15 @@ electron-publish@26.0.7: lazy-val "^1.0.5" mime "^2.5.2" -electron-to-chromium@^1.4.820: - version "1.5.4" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.4.tgz#cd477c830dd6fca41fbd5465c1ff6ce08ac22343" - integrity sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA== - electron-to-chromium@^1.5.73: version "1.5.119" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.119.tgz#4e105e419209b33e1c44b4d1b5fc6fb27fac0209" integrity sha512-Ku4NMzUjz3e3Vweh7PhApPrZSS4fyiCIbcIrG9eKrriYVLmbMepETR/v6SU7xPm98QTqMSYiCwfO89QNjXLkbQ== -electron-updater@^6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.6.0.tgz#0fa8c08f301cb95065284c61b27023c19c7f37f8" - integrity sha512-+aa4P73EU94yYetJOmf2+22ZCrQ3MA4C5HWqFbV1XdSSv2B82lzEg/IZyQw+H5ziUn8V7jrU+AP4zJPdxD74fg== +electron-updater@^6.6.2: + version "6.6.2" + resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.6.2.tgz#3e65e044f1a99b00d61e200e24de8e709c69ce99" + integrity sha512-Cr4GDOkbAUqRHP5/oeOmH/L2Bn6+FQPxVLZtPbcmKZC63a1F3uu5EefYOssgZXG3u/zBlubbJ5PJdITdMVggbw== dependencies: builder-util-runtime "9.3.1" fs-extra "^10.1.0" @@ -4577,7 +4580,7 @@ esbuild@^0.21.3: "@esbuild/win32-ia32" "0.21.5" "@esbuild/win32-x64" "0.21.5" -escalade@^3.1.1, escalade@^3.1.2: +escalade@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== @@ -6994,11 +6997,6 @@ node-fetch@^3.3.2: fetch-blob "^3.1.4" formdata-polyfill "^4.0.10" -node-releases@^2.0.14: - version "2.0.18" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" - integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== - node-releases@^2.0.19: version "2.0.19" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" @@ -7419,7 +7417,7 @@ pend@~1.2.0: resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== -picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.1: +picocolors@^1.0.0, picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== @@ -7455,21 +7453,21 @@ pkg-types@^1.0.3, pkg-types@^1.1.1: mlly "^1.7.1" pathe "^1.1.2" -playwright-core@1.51.0: - version "1.51.0" - resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.51.0.tgz#bb23ea6bb6298242d088ae5e966ffcf8dc9827e8" - integrity sha512-x47yPE3Zwhlil7wlNU/iktF7t2r/URR3VLbH6EknJd/04Qc/PSJ0EY3CMXipmglLG+zyRxW6HNo2EGbKLHPWMg== +playwright-core@1.51.1: + version "1.51.1" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.51.1.tgz#d57f0393e02416f32a47cf82b27533656a8acce1" + integrity sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw== -playwright@1.51.0: - version "1.51.0" - resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.51.0.tgz#9ba154497ba62bc6dc199c58ee19295eb35a4707" - integrity sha512-442pTfGM0xxfCYxuBa/Pu6B2OqxqqaYq39JS8QDMGThUvIOCd6s0ANDog3uwA0cHavVlnTQzGCN7Id2YekDSXA== +playwright@1.51.1: + version "1.51.1" + resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.51.1.tgz#ae1467ee318083968ad28d6990db59f47a55390f" + integrity sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw== dependencies: - playwright-core "1.51.0" + playwright-core "1.51.1" optionalDependencies: fsevents "2.3.2" -plist@^3.0.0, plist@^3.0.4, plist@^3.0.5, plist@^3.1.0: +plist@3.1.0, plist@^3.0.0, plist@^3.0.4, plist@^3.0.5, plist@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/plist/-/plist-3.1.0.tgz#797a516a93e62f5bde55e0b9cc9c967f860893c9" integrity sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ== @@ -9260,14 +9258,6 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -update-browserslist-db@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" - integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== - dependencies: - escalade "^3.1.2" - picocolors "^1.0.1" - update-browserslist-db@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" @@ -9686,10 +9676,10 @@ ws@^7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== -ws@^8.17.0: - version "8.18.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" - integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== +ws@^8.18.1: + version "8.18.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" + integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== xmlbuilder@>=11.0.1, xmlbuilder@^15.1.1: version "15.1.1"