Compare commits

...

20 Commits

Author SHA1 Message Date
117e696430 Merge branch 'nrc-uom-cmds' into franknoirot/tweak-test-nrc-uom-cmds 2025-04-22 14:19:09 -04:00
c18a2223f3 Make useDemoCode use updateModelingState like everyone else 2025-04-22 13:18:22 -04:00
c5492a7937 Tweak test connection step on failing test 2025-04-22 09:52:01 -04:00
19a3c255c3 Convert all lengths to mm for engine calls
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-22 16:04:15 +12:00
f93979c648 Convert all lengths to mm for engine calls
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-22 12:15:28 +12:00
6288ab5f2f Turn on uom checks
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-22 11:12:20 +12:00
e4e18dfd4b Coerce the result of a function call to the function's return type (#6309)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-22 11:00:53 +12:00
30ee547ce4 More consistency in 'Create project' and 'Share part via Zoo link' buttons and commands (#6378)
Polish: More consistency in 'Create project' and 'Share part via Zoo link' buttons and commands
2025-04-21 15:08:51 -04:00
f8ca6ad746 BREAKING: Change polygon to keyword args (#6385)
* Change polygon to keyword args

* Update docs

* Update generated output

* Update docs to mention the default for inscribed

* Appease clippy

* Remove tag parameter

* Update docs since removing tag

* Remove inscribed from autocomplete snippet since the default is true
2025-04-21 18:29:32 +00:00
7a90d029e1 Update onboarding interactive numbers test to use editor fixture, take 2 (#6399)
Update onboarding interactive numbers test to use editor fixture

Trying to bring it down from the leaderboard of failed tests.

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-04-21 14:34:20 +00:00
2900858171 Bump the minor group across 1 directory with 8 updates (#6411)
Bumps the minor group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@csstools/postcss-oklab-function](https://github.com/csstools/postcss-plugins/tree/HEAD/plugins/postcss-oklab-function) | `4.0.8` | `4.0.9` |
| [@playwright/test](https://github.com/microsoft/playwright) | `1.51.1` | `1.52.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.14.0` | `22.14.1` |
| [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) | `4.3.4` | `4.4.1` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.29.1` | `8.30.1` |
| [rollup](https://github.com/rollup/rollup) | `4.39.0` | `4.40.0` |



Updates `@csstools/postcss-oklab-function` from 4.0.8 to 4.0.9
- [Changelog](https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-oklab-function/CHANGELOG.md)
- [Commits](https://github.com/csstools/postcss-plugins/commits/HEAD/plugins/postcss-oklab-function)

Updates `@playwright/test` from 1.51.1 to 1.52.0
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.51.1...v1.52.0)

Updates `@types/node` from 22.14.0 to 22.14.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@vitejs/plugin-react` from 4.3.4 to 4.4.1
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@4.4.1/packages/plugin-react)

Updates `typescript-eslint` from 8.29.1 to 8.30.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.30.1/packages/typescript-eslint)

Updates `rollup` from 4.39.0 to 4.40.0
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.39.0...v4.40.0)

Updates `@typescript-eslint/eslint-plugin` from 8.29.1 to 8.30.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.30.1/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.29.1 to 8.30.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.30.1/packages/parser)

---
updated-dependencies:
- dependency-name: "@csstools/postcss-oklab-function"
  dependency-version: 4.0.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor
- dependency-name: "@playwright/test"
  dependency-version: 1.52.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor
- dependency-name: "@types/node"
  dependency-version: 22.14.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor
- dependency-name: "@vitejs/plugin-react"
  dependency-version: 4.4.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor
- dependency-name: typescript-eslint
  dependency-version: 8.30.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor
- dependency-name: rollup
  dependency-version: 4.40.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.30.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.30.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-21 12:42:14 +00:00
0dee219e46 Check for local name clash with existing variables in Insert flow (#6375)
Check for local name alias clashes with extisting var in Insert flow
Fixes #6230
2025-04-21 10:35:43 +00:00
790613e708 KCL: Convert bezierCurve to use keyword args (#6381) 2025-04-20 20:10:27 -05:00
0a35722595 Silence snapshot failures for now (#6403) 2025-04-19 10:59:53 +00:00
f30fc376ee Allow deletion of only item in AST (#6335)
* Update test to check for deletion of only operation

* Allow updateEditorWithAstAndWriteToFile to clear AST

* Update src/lang/codeManager.ts

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>

* Weave `isDeleting` through to `deleteSelectionPromise`

* fmt

---------

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2025-04-19 05:27:23 -04:00
8c1a95833d clean up sketch mode cmd (#6397) 2025-04-18 21:15:19 -04:00
4f1ba1be01 Fix error message whitelist to use updated message (#6404) 2025-04-18 23:27:34 +00:00
90acc00369 Kwargs migration: arc/arcTo (#6334) 2025-04-18 17:40:44 -05:00
e4fe8a4440 Fix CSG commands to be included in the artifact graph (#6391)
* Fix CSG commands to be included in the artifact graph

* Update output
2025-04-18 22:35:17 +00:00
fbc3251c3f Disable all macOS testing for now (#6395) 2025-04-18 21:37:33 +00:00
495 changed files with 64623 additions and 34743 deletions

View File

@ -225,7 +225,7 @@ jobs:
uses: nick-fields/retry@v3.0.2
with:
shell: bash
command: npm run test:snapshots
command: npm run test:snapshots || true
timeout_minutes: 5
max_attempts: 5
env:
@ -285,7 +285,8 @@ jobs:
# TODO: enable namespace-profile-windows-latest once available
os:
- "runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64"
- namespace-profile-macos-6-cores
# TODO: renable this when macoOS runner seem more stable
# - namespace-profile-macos-6-cores
- windows-latest-8-cores
shardIndex: [1, 2, 3, 4]
shardTotal: [4]

View File

@ -5,6 +5,6 @@ command = "vscode-eslint-language-server"
[[language]]
name = "typescript"
auto-format = true
formatter = { command = "node_modules/.bin/prettier", args = ["--parser", "typescript"] }
language-servers = [ { name = "eslint", only-features = [ "diagnostics" ] }, "typescript-language-server" ]
formatter = { command = "./node_modules/@biomejs/biome/bin/biome", args = ["format", "--write", "--stdin-file-path=foo.ts"] }
# language-servers = [ { name = "eslint", only-features = [ "diagnostics" ] }, "typescript-language-server" ]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -10,8 +10,10 @@ Draw a smooth, continuous, curved line segment from the current origin to the de
```js
bezierCurve(
data: BezierData,
sketch: Sketch,
control1: [number],
control2: [number],
end: [number],
tag?: TagDeclarator,
): Sketch
```
@ -21,9 +23,11 @@ bezierCurve(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `data` | [`BezierData`](/docs/kcl/types/BezierData) | Data to draw a bezier curve. | Yes |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | Which sketch should this path be added to? | Yes |
| `control1` | [`[number]`](/docs/kcl/types/number) | First control point for the cubic | Yes |
| `control2` | [`[number]`](/docs/kcl/types/number) | Second control point for the cubic | Yes |
| `end` | [`[number]`](/docs/kcl/types/number) | How far away (along the X and Y axes) should this line go? | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
### Returns
@ -36,11 +40,7 @@ bezierCurve(
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [0, 10])
|> bezierCurve({
to = [10, 10],
control1 = [5, 0],
control2 = [5, 10]
}, %)
|> bezierCurve(control1 = [5, 0], control2 = [5, 10], end = [10, 10])
|> line(endAbsolute = [10, 0])
|> close()

View File

@ -42,18 +42,10 @@ extrude(
example = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [10, 0])
|> arc({
angleStart = 120,
angleEnd = 0,
radius = 5
}, %)
|> arc(angleStart = 120, angleEnd = 0, radius = 5)
|> line(end = [5, 0])
|> line(end = [0, 10])
|> bezierCurve({
control1 = [-10, 0],
control2 = [2, 10],
to = [-5, 10]
}, %)
|> bezierCurve(control1 = [-10, 0], control2 = [2, 10], end = [-5, 10])
|> line(end = [-5, -2])
|> close()
|> extrude(length = 10)
@ -64,18 +56,10 @@ example = startSketchOn(XZ)
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([-10, 0], %)
|> arc({
angleStart = 120,
angleEnd = -60,
radius = 5
}, %)
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|> line(end = [10, 0])
|> line(end = [5, 0])
|> bezierCurve({
control1 = [-3, 0],
control2 = [2, 10],
to = [-5, 10]
}, %)
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|> line(end = [-4, 10])
|> line(end = [-5, -2])
|> close()
@ -88,18 +72,10 @@ example = extrude(exampleSketch, length = 10)
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([-10, 0], %)
|> arc({
angleStart = 120,
angleEnd = -60,
radius = 5
}, %)
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|> line(end = [10, 0])
|> line(end = [5, 0])
|> bezierCurve({
control1 = [-3, 0],
control2 = [2, 10],
to = [-5, 10]
}, %)
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|> line(end = [-4, 10])
|> line(end = [-5, -2])
|> close()
@ -112,18 +88,10 @@ example = extrude(exampleSketch, length = 20, symmetric = true)
```js
exampleSketch = startSketchOn(XZ)
|> startProfileAt([-10, 0], %)
|> arc({
angleStart = 120,
angleEnd = -60,
radius = 5
}, %)
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|> line(end = [10, 0])
|> line(end = [5, 0])
|> bezierCurve({
control1 = [-3, 0],
control2 = [2, 10],
to = [-5, 10]
}, %)
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|> line(end = [-4, 10])
|> line(end = [-5, -2])
|> close()

View File

@ -4,8 +4,12 @@ excerpt: "Converts a number from centimeters to the current default unit."
layout: manual
---
**WARNING:** This function is deprecated.
Converts a number from centimeters to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42cm`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in centimeters.
For example, if the current file uses inches, `fromCm(1)` will return `0.393701`. If the current file uses millimeters, `fromCm(1)` will return `10`. If the current file uses centimeters, `fromCm(1)` will return `1`.

View File

@ -4,8 +4,12 @@ excerpt: "Converts a number from feet to the current default unit."
layout: manual
---
**WARNING:** This function is deprecated.
Converts a number from feet to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42ft`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in feet.
For example, if the current file uses inches, `fromFt(1)` will return `12`. If the current file uses millimeters, `fromFt(1)` will return `304.8`. If the current file uses feet, `fromFt(1)` will return `1`.

View File

@ -4,8 +4,12 @@ excerpt: "Converts a number from inches to the current default unit."
layout: manual
---
**WARNING:** This function is deprecated.
Converts a number from inches to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42inch`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in inches.
For example, if the current file uses inches, `fromInches(1)` will return `1`. If the current file uses millimeters, `fromInches(1)` will return `25.4`.

View File

@ -4,8 +4,12 @@ excerpt: "Converts a number from meters to the current default unit."
layout: manual
---
**WARNING:** This function is deprecated.
Converts a number from meters to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42m`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in meters.
For example, if the current file uses inches, `fromM(1)` will return `39.3701`. If the current file uses millimeters, `fromM(1)` will return `1000`. If the current file uses meters, `fromM(1)` will return `1`.

View File

@ -4,8 +4,12 @@ excerpt: "Converts a number from mm to the current default unit."
layout: manual
---
**WARNING:** This function is deprecated.
Converts a number from mm to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42mm`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in millimeters.
For example, if the current file uses inches, `fromMm(1)` will return `1/25.4`. If the current file uses millimeters, `fromMm(1)` will return `1`.

View File

@ -4,8 +4,12 @@ excerpt: "Converts a number from yards to the current default unit."
layout: manual
---
**WARNING:** This function is deprecated.
Converts a number from yards to the current default unit.
*DEPRECATED* prefer using explicit numeric suffixes (e.g., `42yd`) or the `to...` conversion functions.
No matter what units the current file uses, this function will always return a number equivalent to the input in yards.
For example, if the current file uses inches, `fromYd(1)` will return `36`. If the current file uses millimeters, `fromYd(1)` will return `914.4`. If the current file uses yards, `fromYd(1)` will return `1`.

View File

@ -22,18 +22,8 @@ layout: manual
* [`string`](kcl/types/string)
* [`tag`](kcl/types/tag)
* **std**
* [`Axis2d`](kcl/types/Axis2d)
* [`Axis3d`](kcl/types/Axis3d)
* [`END`](kcl/consts/std-END)
* [`Edge`](kcl/types/Edge)
* [`Face`](kcl/types/Face)
* [`Helix`](kcl/types/Helix)
* [`Plane`](kcl/types/Plane)
* [`Point2d`](kcl/types/Point2d)
* [`Point3d`](kcl/types/Point3d)
* [`START`](kcl/consts/std-START)
* [`Sketch`](kcl/types/Sketch)
* [`Solid`](kcl/types/Solid)
* [`X`](kcl/consts/std-X)
* [`XY`](kcl/consts/std-XY)
* [`XZ`](kcl/consts/std-XZ)
@ -48,7 +38,6 @@ layout: manual
* [`angledLineThatIntersects`](kcl/angledLineThatIntersects)
* [`appearance`](kcl/appearance)
* [`arc`](kcl/arc)
* [`arcTo`](kcl/arcTo)
* [`asin`](kcl/asin)
* [`assert`](kcl/assert)
* [`assertEqual`](kcl/assertEqual)
@ -66,12 +55,6 @@ layout: manual
* [`extrude`](kcl/extrude)
* [`fillet`](kcl/fillet)
* [`floor`](kcl/floor)
* [`fromCm`](kcl/fromCm)
* [`fromFt`](kcl/fromFt)
* [`fromInches`](kcl/fromInches)
* [`fromM`](kcl/fromM)
* [`fromMm`](kcl/fromMm)
* [`fromYd`](kcl/fromYd)
* [`getCommonEdge`](kcl/getCommonEdge)
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
* [`getOppositeEdge`](kcl/getOppositeEdge)
@ -131,8 +114,14 @@ layout: manual
* [`sweep`](kcl/sweep)
* [`tangentToEnd`](kcl/tangentToEnd)
* [`tangentialArc`](kcl/tangentialArc)
* [`toDegrees`](kcl/toDegrees)
* [`toRadians`](kcl/toRadians)
* [`toCentimeters`](kcl/std-toCentimeters)
* [`toDegrees`](kcl/std-toDegrees)
* [`toFeet`](kcl/std-toFeet)
* [`toInches`](kcl/std-toInches)
* [`toMeters`](kcl/std-toMeters)
* [`toMillimeters`](kcl/std-toMillimeters)
* [`toRadians`](kcl/std-toRadians)
* [`toYards`](kcl/std-toYards)
* [`translate`](kcl/translate)
* [`union`](kcl/union)
* [`xLine`](kcl/xLine)
@ -153,3 +142,14 @@ layout: manual
* [`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)
* **std::types**
* [`Axis2d`](kcl/types/Axis2d)
* [`Axis3d`](kcl/types/Axis3d)
* [`Edge`](kcl/types/Edge)
* [`Face`](kcl/types/Face)
* [`Helix`](kcl/types/Helix)
* [`Plane`](kcl/types/Plane)
* [`Point2d`](kcl/types/Point2d)
* [`Point3d`](kcl/types/Point3d)
* [`Sketch`](kcl/types/Sketch)
* [`Solid`](kcl/types/Solid)

View File

@ -174,7 +174,7 @@ t = 0.005 // taper factor [0-1)
// Defines how to modify each layer of the vase.
// Each replica is shifted up the Z axis, and has a smoothly-varying radius
fn transform(replicaId) {
scale = r * abs(1 - (t * replicaId)) * (5 + cos(replicaId / 8))
scale = r * abs(1 - (t * replicaId)) * (5 + cos(replicaId / 8: number(rad)))
return {
translate = [0, 0, replicaId * 10],
scale = [scale, scale, 0]
@ -205,12 +205,12 @@ fn transform(i) {
}
startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> polygon({
|> polygon(
radius = 10,
numSides = 4,
center = [0, 0],
inscribed = false
}, %)
inscribed = false,
)
|> extrude(length = 4)
|> patternTransform(instances = 3, transform = transform)
```

View File

@ -10,9 +10,11 @@ Create a regular polygon with the specified number of sides that is either inscr
```js
polygon(
data: PolygonData,
sketchSurfaceOrGroup: SketchOrSurface,
tag?: TagDeclarator,
radius: number,
numSides: u64,
center: [number],
inscribed?: bool,
): Sketch
```
@ -21,9 +23,11 @@ polygon(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `data` | [`PolygonData`](/docs/kcl/types/PolygonData) | Data for drawing a polygon | Yes |
| `sketchSurfaceOrGroup` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | A sketch surface or a sketch. | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
| `sketchSurfaceOrGroup` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | Plane or surface to sketch on | Yes |
| `radius` | [`number`](/docs/kcl/types/number) | The radius of the polygon | Yes |
| `numSides` | `u64` | The number of sides in the polygon | Yes |
| `center` | [`[number]`](/docs/kcl/types/number) | The center point of the polygon | Yes |
| `inscribed` | [`bool`](/docs/kcl/types/bool) | Whether the polygon is inscribed (true, the default) or circumscribed (false) about a circle with the specified radius | No |
### Returns
@ -35,12 +39,12 @@ polygon(
```js
// Create a regular hexagon inscribed in a circle of radius 10
hex = startSketchOn(XY)
|> polygon({
|> polygon(
radius = 10,
numSides = 6,
center = [0, 0],
inscribed = true
}, %)
inscribed = true,
)
example = extrude(hex, length = 5)
```
@ -50,12 +54,12 @@ example = extrude(hex, length = 5)
```js
// Create a square circumscribed around a circle of radius 5
square = startSketchOn(XY)
|> polygon({
|> polygon(
radius = 5.0,
numSides = 4,
center = [10, 10],
inscribed = false
}, %)
inscribed = false,
)
example = extrude(square, length = 5)
```

View File

@ -26,7 +26,7 @@ helix(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `revolutions` | `number(_)` | Number of revolutions. | Yes |
| `angleStart` | `number(Angle)` | Start angle (in degrees). | Yes |
| `angleStart` | `number(Angle)` | Start angle. | Yes |
| `ccw` | [`bool`](/docs/kcl/types/bool) | Is the helix rotation counter clockwise? The default is `false`. | No |
| `radius` | `number(Length)` | Radius of the helix. | No |
| `axis` | `Axis3d | Edge` | Axis to use for the helix. | No |

View File

@ -31,7 +31,7 @@ exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(
angle = 30,
length = 3 / cos(toRadians(30)),
length = 3 / cos(30deg),
)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -11,7 +11,7 @@ cartesian (x/y/z grid) coordinates.
```js
polar(
angle: number(Angle),
angle: number(rad),
length: number(Length),
): Point2d
```
@ -21,7 +21,7 @@ polar(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `angle` | `number(Angle)` | | Yes |
| `angle` | `number(rad)` | | Yes |
| `length` | `number(Length)` | | Yes |
### Returns

View File

@ -31,7 +31,7 @@ exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(
angle = 50,
length = 15 / sin(toRadians(135)),
length = 15 / sin(135deg),
)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -31,7 +31,7 @@ exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine(
angle = 50,
length = 50 * tan(1/2),
length = 50 * tan((1/2): number(rad)),
)
|> yLine(endAbsolute = 0)
|> close()

View File

@ -0,0 +1,27 @@
---
title: "std::toCentimeters"
excerpt: "Convert a number to centimeters from its current units."
layout: manual
---
Convert a number to centimeters from its current units.
```js
toCentimeters(@num: number(cm)): number(cm)
```
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `num` | `number(cm)` | | Yes |
### Returns
`number(cm)`

44
docs/kcl/std-toDegrees.md Normal file

File diff suppressed because one or more lines are too long

27
docs/kcl/std-toFeet.md Normal file
View File

@ -0,0 +1,27 @@
---
title: "std::toFeet"
excerpt: "Convert a number to feet from its current units."
layout: manual
---
Convert a number to feet from its current units.
```js
toFeet(@num: number(ft)): number(ft)
```
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `num` | `number(ft)` | | Yes |
### Returns
`number(ft)`

27
docs/kcl/std-toInches.md Normal file
View File

@ -0,0 +1,27 @@
---
title: "std::toInches"
excerpt: "Convert a number to inches from its current units."
layout: manual
---
Convert a number to inches from its current units.
```js
toInches(@num: number(in)): number(in)
```
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `num` | `number(in)` | | Yes |
### Returns
`number(in)`

27
docs/kcl/std-toMeters.md Normal file
View File

@ -0,0 +1,27 @@
---
title: "std::toMeters"
excerpt: "Convert a number to meters from its current units."
layout: manual
---
Convert a number to meters from its current units.
```js
toMeters(@num: number(m)): number(m)
```
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `num` | `number(m)` | | Yes |
### Returns
`number(m)`

View File

@ -0,0 +1,27 @@
---
title: "std::toMillimeters"
excerpt: "Convert a number to millimeters from its current units."
layout: manual
---
Convert a number to millimeters from its current units.
```js
toMillimeters(@num: number(mm)): number(mm)
```
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `num` | `number(mm)` | | Yes |
### Returns
`number(mm)`

44
docs/kcl/std-toRadians.md Normal file

File diff suppressed because one or more lines are too long

27
docs/kcl/std-toYards.md Normal file
View File

@ -0,0 +1,27 @@
---
title: "std::toYards"
excerpt: "Converts a number to yards from its current units."
layout: manual
---
Converts a number to yards from its current units.
```js
toYards(@num: number(yd)): number(yd)
```
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `num` | `number(yd)` | | Yes |
### Returns
`number(yd)`

File diff suppressed because it is too large Load Diff

View File

@ -73,7 +73,7 @@ rectangleExtrude = extrude(rectangleSketch, length = 10)
```js
bottom = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> arcTo({ end = [10, 10], interior = [5, 1] }, %, $arc1)
|> arc(endAbsolute = [10, 10], interiorAbsolute = [5, 1], tag = $arc1)
|> angledLine(angle = tangentToEnd(arc1), length = 20)
|> close()
```

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
---
title: "std::Axis2d"
title: "std::types::Axis2d"
excerpt: "An infinite line in 2d space."
layout: manual
---

View File

@ -1,5 +1,5 @@
---
title: "std::Axis3d"
title: "std::types::Axis3d"
excerpt: "An infinite line in 3d space."
layout: manual
---

View File

@ -1,5 +1,5 @@
---
title: "std::Edge"
title: "std::types::Edge"
excerpt: "The edge of a solid."
layout: manual
---

View File

@ -1,5 +1,5 @@
---
title: "std::Face"
title: "std::types::Face"
excerpt: "A face."
layout: manual
---

View File

@ -1,5 +1,5 @@
---
title: "std::Helix"
title: "std::types::Helix"
excerpt: "A helix."
layout: manual
---

View File

@ -141,8 +141,8 @@ A base path.
|----------|------|-------------|----------|
| `type` |enum: `ArcThreePoint`| | No |
| `p1` |`[number, number]`| Point 1 of the arc (base on the end of previous segment) | No |
| `p2` |`[number, number]`| Point 2 of the arc (interior kwarg) | No |
| `p3` |`[number, number]`| Point 3 of the arc (end kwarg) | No |
| `p2` |`[number, number]`| Point 2 of the arc (interiorAbsolute kwarg) | No |
| `p3` |`[number, number]`| Point 3 of the arc (endAbsolute kwarg) | No |
| `from` |`[number, number]`| The from point. | No |
| `to` |`[number, number]`| The to point. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |

View File

@ -1,5 +1,5 @@
---
title: "std::Plane"
title: "std::types::Plane"
excerpt: "A plane."
layout: manual
---

View File

@ -1,5 +1,5 @@
---
title: "std::Point2d"
title: "std::types::Point2d"
excerpt: "A point in two dimensional space."
layout: manual
---

View File

@ -1,5 +1,5 @@
---
title: "std::Point3d"
title: "std::types::Point3d"
excerpt: "A point in three dimensional space."
layout: manual
---

File diff suppressed because one or more lines are too long

View File

@ -31,7 +31,6 @@ A sketch type.
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's X axis be? | No |
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's Y axis be? | No |
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |
----

File diff suppressed because one or more lines are too long

View File

@ -12,7 +12,7 @@ The syntax for declaring a tag is `$myTag` you would use it in the following
way:
```js
startSketchOn('XZ')
startSketchOn(XZ)
|> startProfileAt(origin, %)
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|> angledLine(
@ -46,7 +46,7 @@ However if the code was written like this:
```js
fn rect(origin) {
return startSketchOn('XZ')
return startSketchOn(XZ)
|> startProfileAt(origin, %)
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|> angledLine(
@ -75,7 +75,7 @@ For example the following code works.
```js
fn rect(origin) {
return startSketchOn('XZ')
return startSketchOn(XZ)
|> startProfileAt(origin, %)
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|> angledLine(

View File

@ -430,5 +430,17 @@ profile003 = startProfileAt([0, -4.93], sketch001)
await editor.expectEditor.not.toContain('sketch001 =')
await editor.expectEditor.not.toContain('profile002 = ')
})
await test.step(`Delete the remaining plane via feature tree`, async () => {
const operationButton = await toolbar.getFeatureTreeOperation(
'Offset Plane',
0
)
await operationButton.click({ button: 'left' })
await page.keyboard.press('Delete')
// Verify the plane code is gone, and https://github.com/KittyCAD/modeling-app/issues/5988 is fixed.
await editor.expectEditor.not.toContain('plane001 =')
})
})
})

View File

@ -63,6 +63,18 @@ export const isErrorWhitelisted = (exception: Error) => {
'e2e/playwright/can-create-sketches-on-all-planes-and-their-back-sides.spec.ts XY',
project: 'Google Chrome',
},
{
name: 'fE',
message:
'engine: Failed to wait for promise from send modeling command: JsValue("no connection to send on")',
stack: `fE: engine: Failed to wait for promise from send modeling command: JsValue("no connection to send on")
at ET (file:///home/runner/_work/modeling-app/modeling-app/.vite/renderer/main_window/assets/index-BvtRFNLF.js:49875:12)
at WGe.clearSceneAndBustCache (file:///home/runner/_work/modeling-app/modeling-app/.vite/renderer/main_window/assets/index-BvtRFNLF.js:91886:19)
at async a.onEngineConnectionOpened (file:///home/runner/_work/modeling-app/modeling-app/.vite/renderer/main_window/assets/index-BvtRFNLF.js:91483:9)`,
foundInSpec:
'e2e/playwright/testing-constraints.spec.ts is frequent but could be any spec',
project: 'Google Chrome',
},
{
name: 'RangeError',
message: 'Position 160 is out of range for changeset of length 0',

View File

@ -21,8 +21,9 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
if (!app || !app.applicationMenu) {
return false
}
const newProject =
app.applicationMenu.getMenuItemById('File.New project')
const newProject = app.applicationMenu.getMenuItemById(
'File.Create project'
)
if (!newProject) return false
newProject.click()
return true
@ -484,8 +485,9 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const newProject =
app.applicationMenu.getMenuItemById('File.New project')
const newProject = app.applicationMenu.getMenuItemById(
'File.Create project'
)
if (!newProject) fail()
newProject.click()
})
@ -608,7 +610,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
const expected = 'Export'
expect(actual).toBe(expected)
})
test('Modeling.File.Share current part (via Zoo link)', async ({
test('Modeling.File.Share part via Zoo link', async ({
tronApp,
cmdBar,
page,
@ -629,10 +631,10 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
throw new Error('app or app.applicationMenu is missing')
}
const openProject = app.applicationMenu.getMenuItemById(
'File.Share current part (via Zoo link)'
'File.Share part via Zoo link'
)
if (!openProject) {
throw new Error('File.Share current part (via Zoo link)')
throw new Error('File.Share part via Zoo link')
}
openProject.click()
})

View File

@ -63,7 +63,7 @@ test.describe('Onboarding tests', () => {
{
tag: '@electron',
},
async ({ page, tronApp }) => {
async ({ page, tronApp, scene }) => {
if (!tronApp) {
fail()
}
@ -72,7 +72,6 @@ test.describe('Onboarding tests', () => {
onboarding_status: '',
},
})
const u = await getUtils(page)
const viewportSize = { width: 1200, height: 500 }
await page.setBodyDimensions(viewportSize)
@ -80,7 +79,7 @@ test.describe('Onboarding tests', () => {
await test.step(`Create a project and open to the onboarding`, async () => {
await createProject({ name: 'project-link', page })
await test.step(`Ensure the engine connection works by testing the sketch button`, async () => {
await u.waitForPageLoad()
await scene.connectionEstablished()
})
})
@ -107,12 +106,10 @@ test.describe('Onboarding tests', () => {
)
test('Code resets after confirmation', async ({
context,
page,
homePage,
tronApp,
scene,
cmdBar,
}) => {
if (!tronApp) {
fail()
@ -276,6 +273,8 @@ test.describe('Onboarding tests', () => {
page,
homePage,
tronApp,
editor,
toolbar,
}) => {
if (!tronApp) {
fail()
@ -289,7 +288,6 @@ test.describe('Onboarding tests', () => {
},
})
const u = await getUtils(page)
const badCode = `// This is bad code we shouldn't see`
await page.setBodyDimensions({ width: 1200, height: 1080 })
@ -299,18 +297,19 @@ test.describe('Onboarding tests', () => {
.poll(() => page.url())
.toContain(onboardingPaths.PARAMETRIC_MODELING)
const bracketNoNewLines = bracket.replace(/\n/g, '')
// Check the code got reset on load
await expect(page.locator('#code-pane')).toBeVisible()
await expect(u.codeLocator).toHaveText(bracketNoNewLines, {
await toolbar.openPane('code')
await editor.expectEditor.toContain(bracket, {
shouldNormalise: true,
timeout: 10_000,
})
// Mess with the code again
await u.codeLocator.selectText()
await u.codeLocator.fill(badCode)
await expect(u.codeLocator).toHaveText(badCode)
await editor.replaceCode('', badCode)
await editor.expectEditor.toContain(badCode, {
shouldNormalise: true,
timeout: 10_000,
})
// Click to the next step
await page.locator('[data-testid="onboarding-next"]').hover()
@ -320,7 +319,10 @@ test.describe('Onboarding tests', () => {
})
// Check that the code has been reset
await expect(u.codeLocator).toHaveText(bracketNoNewLines)
await editor.expectEditor.toContain(bracket, {
shouldNormalise: true,
timeout: 10_000,
})
})
// (lee) The two avatar tests are weird because even on main, we don't have

View File

@ -143,28 +143,45 @@ test.describe('Point-and-click assemblies tests', () => {
await scene.settled(cmdBar)
})
await test.step('Insert a second time and expect error', async () => {
// TODO: revisit once we have clone with #6209
await insertPartIntoAssembly(
'bracket.kcl',
'bracket',
toolbar,
cmdBar,
page
)
await test.step('Insert a second time with the same name and expect error', async () => {
await toolbar.insertButton.click()
await cmdBar.selectOption({ name: 'bracket.kcl' }).click()
await cmdBar.expectState({
stage: 'arguments',
currentArgKey: 'localName',
currentArgValue: '',
headerArguments: { Path: 'bracket.kcl', LocalName: '' },
highlightedHeaderArg: 'localName',
commandName: 'Insert',
})
await page.keyboard.insertText('bracket')
await cmdBar.progressCmdBar()
await expect(
page.getByText('This variable name is already in use')
).toBeVisible()
})
await test.step('Insert a second time with a different name and expect error', async () => {
await page.keyboard.insertText('2')
await cmdBar.progressCmdBar()
await cmdBar.expectState({
stage: 'review',
headerArguments: { Path: 'bracket.kcl', LocalName: 'bracket2' },
commandName: 'Insert',
})
await cmdBar.progressCmdBar()
await editor.expectEditor.toContain(
`
import "cylinder.kcl" as cylinder
import "bracket.kcl" as bracket
import "bracket.kcl" as bracket
import "bracket.kcl" as bracket2
cylinder
bracket
bracket
bracket2
`,
{ shouldNormalise: true }
)
await scene.settled(cmdBar)
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
// TODO: update once we have clone() with #6209
})
}
)
@ -261,7 +278,7 @@ test.describe('Point-and-click assemblies tests', () => {
highlightedHeaderArg: 'x',
commandName: 'Translate',
})
await page.keyboard.insertText('5')
await page.keyboard.insertText('100')
await cmdBar.progressCmdBar()
await page.keyboard.insertText('0.1')
await cmdBar.progressCmdBar()
@ -270,7 +287,7 @@ test.describe('Point-and-click assemblies tests', () => {
await cmdBar.expectState({
stage: 'review',
headerArguments: {
X: '5',
X: '100',
Y: '0.1',
Z: '0.2',
},
@ -282,7 +299,7 @@ test.describe('Point-and-click assemblies tests', () => {
await editor.expectEditor.toContain(
`
bracket
|> translate(x = 5, y = 0.1, z = 0.2)
|> translate(x = 100, y = 0.1, z = 0.2)
`,
{ shouldNormalise: true }
)
@ -331,7 +348,7 @@ test.describe('Point-and-click assemblies tests', () => {
await editor.expectEditor.toContain(
`
bracket
|> translate(x = 5, y = 0.1, z = 0.2)
|> translate(x = 100, y = 0.1, z = 0.2)
|> rotate(roll = 0.1, pitch = 0.2, yaw = 0.3)
`,
{ shouldNormalise: true }

View File

@ -45,11 +45,7 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
screwHole = startSketchOn(XY)
${startProfileAt1}
|> arc({
radius = screwRadius,
angleStart = 0,
angleEnd = 360
}, %)
|> arc(angleStart = 0, angleEnd = 360, radius = screwRadius)
part001 = startSketchOn(XY)
${startProfileAt2}
@ -66,11 +62,7 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
|> tangentialArc(endAbsolute = [width / 2, 0])
|> xLine(length = -width / 4 + wireRadius)
|> yLine(length = wireOffset)
|> arc({
radius = wireRadius,
angleStart = 0,
angleEnd = 180
}, %)
|> arc(angleStart = 0, angleEnd = 180, radius = wireRadius)
|> yLine(length = -wireOffset)
|> xLine(length = -width / 4)
|> close()
@ -214,15 +206,8 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
|> startProfileAt([4.61, -14.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArc(endAbsolute = [24.95, -5.38])
|> arcTo({
interior = [20.18, -1.7],
end = [11.82, -1.16]
}, %)
|> arc({
radius = 5.92,
angleStart = -89.36,
angleEnd = 135.81
}, %)
|> arc(interiorAbsolute = [20.18, -1.7], endAbsolute = [11.82, -1.16])
|> arc(angleStart = -89.36, angleEnd = 135.81, radius = 5.92)
|> close()`
)
})
@ -264,15 +249,8 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
|> startProfileAt([4.61, -14.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArc(endAbsolute = [24.95, -5.38])
|> arcTo({
interior = [20.18, -1.7],
end = [11.82, -1.16]
}, %)
|> arc({
radius = 5.92,
angleStart = -89.36,
angleEnd = 135.81
}, %)
|> arc(interiorAbsolute = [20.18, -1.7], endAbsolute = [11.82, -1.16])
|> arc(angleStart = -89.36, angleEnd = 135.81, radius = 5.92)
|> close()
`)
} else {
@ -338,7 +316,7 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
}
// drag arcTo interior handle (three point arc)
// drag arcTo interiorAbsolute handle (three point arc)
const arcToHandle = await u.getBoundingBox('[data-overlay-index="2"]')
await page.mouse.move(arcToHandle.x, arcToHandle.y - 5)
await page.mouse.down()
@ -410,15 +388,8 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
|> startProfileAt([6.44, -12.07], %)
|> line(end = [14.72, 1.97])
|> tangentialArc(endAbsolute = [26.92, -3.32])
|> arcTo({
interior = [18.11, -3.73],
end = [9.77, -3.19]
}, %)
|> arc({
radius = 3.75,
angleStart = -58.29,
angleEnd = 161.17
}, %)
|> arc(interiorAbsolute = [18.11, -3.73], endAbsolute = [9.77, -3.19])
|> arc(angleStart = -58.29, angleEnd = 161.17, radius = 3.75)
|> close()
`)
}
@ -948,7 +919,9 @@ profile001 = startProfileAt([${roundOff(scale * 69.6)}, ${roundOff(
await page.mouse.move(pointA[0] - 12, pointA[1] + 12, { steps: 10 })
const pointNotQuiteA = [pointA[0] - 7, pointA[1] + 7]
await page.mouse.move(pointNotQuiteA[0], pointNotQuiteA[1], { steps: 10 })
await page.mouse.move(pointNotQuiteA[0], pointNotQuiteA[1], {
steps: 10,
})
await page.mouse.click(pointNotQuiteA[0], pointNotQuiteA[1], {
delay: 200,
@ -1500,12 +1473,12 @@ profile002 = startProfileAt([117.2, 56.08], sketch001)
await circle3Point1()
await page.waitForTimeout(200)
await circle3Point2()
await editor.expectEditor.toContain('arcTo({')
await editor.expectEditor.toContain('arc(')
})
await test.step('equip line tool and verify three-point-arc code is removed after second click', async () => {
await toolbar.lineBtn.click()
await editor.expectEditor.not.toContain('arcTo({')
await editor.expectEditor.not.toContain('arc(')
})
const [cornerRectPoint1] = scene.makeMouseHelpers(600, 300)
@ -1542,9 +1515,9 @@ profile002 = startProfileAt([117.2, 56.08], sketch001)
await continueProfile2Clk()
await page.waitForTimeout(200)
await circle3Point1()
await editor.expectEditor.toContain('arcTo({')
await editor.expectEditor.toContain('arc(')
await toolbar.lineBtn.click()
await editor.expectEditor.not.toContain('arcTo({')
await editor.expectEditor.not.toContain('arc(')
await editor.expectEditor.toContain('profile002')
})
}
@ -1841,7 +1814,9 @@ profile003 = startProfileAt([206.63, -56.73], sketch001)
await page.waitForTimeout(300)
// Verify the three-point arc was created correctly
await editor.expectEditor.toContain(`|> arcTo(`)
await editor.expectEditor.toContain(`arc(`)
await editor.expectEditor.toContain(`interiorAbsolute`)
await editor.expectEditor.toContain(`endAbsolute`)
// Switch back to line tool to continue
await toolbar.lineBtn.click()
@ -2061,10 +2036,7 @@ profile003 = startProfileAt([206.63, -56.73], sketch001)
// Verify the first three-point arc was created correctly
await editor.expectEditor.toContain(
`profile011 = startProfileAt([13.56, -9.97], sketch001)
|> arcTo({
interior = [15.19, -6.51],
end = [19.33, -11.19]
}, %)`,
|> arc(interiorAbsolute = [15.19, -6.51], endAbsolute = [19.33, -11.19])`,
{ shouldNormalise: true }
)
@ -2081,14 +2053,8 @@ profile003 = startProfileAt([206.63, -56.73], sketch001)
// Verify the second three-point arc was created correctly
await editor.expectEditor.toContain(
` |> arcTo({
interior = [19.8, 1.7],
end = [21.7, 2.92]
}, %)
|> arcTo({
interior = [27.47, 1.42],
end = [27.57, 1.52]
}, %)`,
` |> arc(interiorAbsolute = [19.8, 1.7], endAbsolute = [21.7, 2.92])
|> arc(interiorAbsolute = [27.47, 1.42], endAbsolute = [27.57, 1.52])`,
{ shouldNormalise: true }
)
})
@ -2863,33 +2829,29 @@ test.describe(`Click based selection don't brick the app when clicked out of ran
`sketch001 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> line(end = [3.14, 3.14])
|> arcTo({
end = [4, 2],
interior = [1, 2]
}, %)
`
|> arc(
interiorAbsolute = [1, 2],
endAbsolute = [4, 2]
)`
)
})
await homePage.goToModelingScene()
await scene.settled(cmdBar)
const formattedArc = `arc(interiorAbsolute = [1, 2], endAbsolute = [4, 2])`
await test.step(`format the code`, async () => {
// doesn't contain condensed version
await editor.expectEditor.not.toContain(
`arcTo({ end = [4, 2], interior = [1, 2] }, %)`
)
await editor.expectEditor.not.toContain(formattedArc)
// click the code to enter sketch mode
await page.getByText(`arcTo`).click()
await page.getByText(`arc`).click()
// Format the code.
await page.locator('#code-pane button:first-child').click()
await page.locator('button:has-text("Format code")').click()
})
await test.step(`Ensure the code reformatted`, async () => {
await editor.expectEditor.toContain(
`arcTo({ end = [4, 2], interior = [1, 2] }, %)`
)
await editor.expectEditor.toContain(formattedArc)
})
const [arcClick, arcHover] = scene.makeMouseHelpers(699, 337)
@ -2900,7 +2862,7 @@ test.describe(`Click based selection don't brick the app when clicked out of ran
await editor.expectState({
activeLines: ['sketch001=startSketchOn(XZ)'],
diagnostics: [],
highlightedCode: 'arcTo({end = [4, 2], interior = [1, 2]}, %)',
highlightedCode: 'arc(interiorAbsolute = [1, 2], endAbsolute = [4, 2])',
})
})
@ -2922,7 +2884,7 @@ test.describe(`Click based selection don't brick the app when clicked out of ran
await editor.expectState({
activeLines: [],
diagnostics: [],
highlightedCode: 'arcTo({end = [4, 2], interior = [1, 2]}, %)',
highlightedCode: 'arc(interiorAbsolute = [1, 2], endAbsolute = [4, 2])',
})
})
})
@ -3036,10 +2998,7 @@ profile001 = startProfileAt([0, 0], sketch001)
|> line(end = [191.39, 191.39])
|> tangentialArc(endAbsolute = [287.08, 95.69], tag = $seg01)
|> angledLine(angle = tangentToEnd(seg01), length = 135.34)
|> arcTo({
interior = [191.39, -95.69],
end = [287.08, -95.69]
}, %, $seg02)
|> arc(interiorAbsolute = [191.39, -95.69], endAbsolute = [287.08, -95.69], tag = $seg02)
|> angledLine(angle = tangentToEnd(seg02) + turns::HALF_TURN, length = 270.67)
`.replaceAll('\n', '')
)

View File

@ -49,7 +49,6 @@ test(
'exports of each format should work',
{ tag: ['@snapshot', '@skipWin', '@skipMacos'] },
async ({ page, context, scene, cmdBar, tronApp }) => {
test.fixme(orRunWhenFullSuiteEnabled())
if (!tronApp) {
fail()
}
@ -377,8 +376,6 @@ test.describe(
'extrude on default planes should be stable',
{ tag: '@snapshot' },
() => {
test.fixme(orRunWhenFullSuiteEnabled())
test('XY', async ({ page, context, cmdBar, scene }) => {
await extrudeDefaultPlane(context, page, cmdBar, scene, 'XY')
})
@ -409,7 +406,6 @@ test(
'Draft segments should look right',
{ tag: '@snapshot' },
async ({ page, scene, toolbar }) => {
test.fixme(orRunWhenFullSuiteEnabled())
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
const PUR = 400 / 37.5 //pixeltoUnitRatio
@ -534,8 +530,6 @@ test(
'Draft rectangles should look right',
{ tag: '@snapshot' },
async ({ page, context, cmdBar, scene }) => {
test.fixme(orRunWhenFullSuiteEnabled())
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
const PUR = 400 / 37.5 //pixeltoUnitRatio
@ -581,7 +575,6 @@ test(
'Draft circle should look right',
{ tag: '@snapshot' },
async ({ page, context, cmdBar, scene }) => {
test.fixme(orRunWhenFullSuiteEnabled())
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
const PUR = 400 / 37.5 //pixeltoUnitRatio
@ -628,8 +621,6 @@ test.describe(
'Client side scene scale should match engine scale',
{ tag: '@snapshot' },
() => {
test.fixme(orRunWhenFullSuiteEnabled())
test('Inch scale', async ({ page, cmdBar, scene }) => {
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
@ -805,8 +796,6 @@ test(
'Sketch on face with none z-up',
{ tag: '@snapshot' },
async ({ page, context, cmdBar, scene }) => {
test.fixme(orRunWhenFullSuiteEnabled())
const u = await getUtils(page)
await context.addInitScript(async (KCL_DEFAULT_LENGTH) => {
localStorage.setItem(
@ -865,8 +854,6 @@ test(
'Zoom to fit on load - solid 2d',
{ tag: '@snapshot' },
async ({ page, context, cmdBar, scene }) => {
test.fixme(orRunWhenFullSuiteEnabled())
const u = await getUtils(page)
await context.addInitScript(async () => {
localStorage.setItem(
@ -903,8 +890,6 @@ test(
'Zoom to fit on load - solid 3d',
{ tag: '@snapshot' },
async ({ page, context, cmdBar, scene }) => {
test.fixme(orRunWhenFullSuiteEnabled())
const u = await getUtils(page)
await context.addInitScript(async () => {
localStorage.setItem(
@ -944,7 +929,6 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
cmdBar,
scene,
}) => {
test.fixme(orRunWhenFullSuiteEnabled())
const u = await getUtils(page)
const stream = page.getByTestId('stream')
@ -1004,7 +988,6 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
})
test('Grid turned off', async ({ page, cmdBar, scene }) => {
test.fixme(orRunWhenFullSuiteEnabled())
const u = await getUtils(page)
const stream = page.getByTestId('stream')
@ -1026,7 +1009,6 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
})
test('Grid turned on', async ({ page, context, cmdBar, scene }) => {
test.fixme(orRunWhenFullSuiteEnabled())
await context.addInitScript(
async ({ settingsKey, settings }) => {
localStorage.setItem(settingsKey, settings)
@ -1136,7 +1118,6 @@ test('theme persists', async ({ page, context }) => {
test.describe('code color goober', { tag: '@snapshot' }, () => {
test('code color goober', async ({ page, context, scene, cmdBar }) => {
test.fixme(orRunWhenFullSuiteEnabled())
const u = await getUtils(page)
await context.addInitScript(async () => {
localStorage.setItem(
@ -1154,11 +1135,7 @@ sweepPath = startSketchOn(XZ)
sweepSketch = startSketchOn(XY)
|> startProfileAt([2, 0], %)
|> arc({
angleEnd = 360,
angleStart = 0,
radius = 2
}, %)
|> arc(angleStart = 0, angleEnd = 360, radius = 2)
|> sweep(path = sweepPath)
|> appearance(
color = "#bb00ff",
@ -1203,11 +1180,7 @@ sweepPath = startSketchOn(XZ)
sweepSketch = startSketchOn(XY)
|> startProfileAt([2, 0], %)
|> arc({
angleEnd = 360,
angleStart = 0,
radius = 2
}, %)
|> arc(angleStart = 0, angleEnd = 360, radius = 2)
|> sweep(path = sweepPath)
|> appearance(
color = "#bb00ff",

View File

@ -785,16 +785,12 @@ test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
sketch001 = startSketchOn(XZ)
profile001 = startProfileAt([56.37, 120.33], sketch001)
|> line(end = [162.86, 106.48])
|> arcTo({
interior = [360.16, 231.76],
end = [391.48, 131.54]
}, %)
|> arc(
interiorAbsolute = [360.16, 231.76],
endAbsolute = [391.48, 131.54],
)
|> yLine(-131.54, %)
|> arc({
radius = 126.46,
angleStart = 33.53,
angleEnd = -141.07
}, %)
|> arc(angleStart = 33.53, angleEnd = -141.07, radius = 126.46)
`
)
localStorage.setItem('disableAxis', 'true')
@ -820,43 +816,25 @@ profile001 = startProfileAt([56.37, 120.33], sketch001)
const arcTo = await u.getBoundingBox('[data-overlay-index="1"]')
let ang = await u.getAngle('[data-overlay-index="1"]')
console.log('arcTo interior x')
console.log('arcTo interiorAbsolute x')
await clickUnconstrained({
hoverPos: { x: arcTo.x, y: arcTo.y },
constraintType: 'xAbsolute',
expectBeforeUnconstrained: `arcTo({
interior = [360.16, 231.76],
end = [391.48, 131.54]
}, %)`,
expectAfterUnconstrained: `arcTo({
interior = [360.16, 231.76],
end = [391.48, 131.54]
}, %)`,
expectFinal: `arcTo({
interior = [xAbs001, 231.76],
end = [391.48, 131.54]
}, %)`,
expectBeforeUnconstrained: `arc(interiorAbsolute = [360.16, 231.76], endAbsolute = [391.48, 131.54])`,
expectAfterUnconstrained: `arc(interiorAbsolute = [360.16, 231.76], endAbsolute = [391.48, 131.54])`,
expectFinal: `arc(interiorAbsolute = [xAbs001, 231.76], endAbsolute = [391.48, 131.54])`,
ang: ang,
steps: 6,
locator: '[data-overlay-toolbar-index="1"]',
})
console.log('arcTo interior y')
console.log('arcTo interiorAbsolute y')
await clickUnconstrained({
hoverPos: { x: arcTo.x, y: arcTo.y },
constraintType: 'yAbsolute',
expectBeforeUnconstrained: `arcTo({
interior = [xAbs001, 231.76],
end = [391.48, 131.54]
}, %)`,
expectAfterUnconstrained: `arcTo({
interior = [xAbs001, yAbs001],
end = [391.48, 131.54]
}, %)`,
expectFinal: `arcTo({
interior = [xAbs001, 231.76],
end = [391.48, 131.54]
}, %)`,
expectBeforeUnconstrained: `arc(interiorAbsolute = [xAbs001, 231.76], endAbsolute = [391.48, 131.54])`,
expectAfterUnconstrained: `arc(interiorAbsolute = [xAbs001, yAbs001], endAbsolute = [391.48, 131.54])`,
expectFinal: `arc(interiorAbsolute = [xAbs001, 231.76], endAbsolute = [391.48, 131.54])`,
ang: ang,
steps: 10,
locator: '[data-overlay-toolbar-index="1"]',
@ -866,18 +844,9 @@ profile001 = startProfileAt([56.37, 120.33], sketch001)
await clickConstrained({
hoverPos: { x: arcTo.x, y: arcTo.y },
constraintType: 'xAbsolute',
expectBeforeUnconstrained: `arcTo({
interior = [xAbs001, 231.76],
end = [391.48, 131.54]
}, %)`,
expectAfterUnconstrained: `arcTo({
interior = [xAbs001, 231.76],
end = [391.48, 131.54]
}, %)`,
expectFinal: `arcTo({
interior = [xAbs001, 231.76],
end = [xAbs002, 131.54]
}, %)`,
expectBeforeUnconstrained: `arc(interiorAbsolute = [xAbs001, 231.76], endAbsolute = [391.48, 131.54])`,
expectAfterUnconstrained: `arc(interiorAbsolute = [xAbs001, 231.76], endAbsolute = [391.48, 131.54])`,
expectFinal: `arc(interiorAbsolute = [xAbs001, 231.76], endAbsolute = [xAbs002, 131.54])`,
ang: ang + 180,
steps: 6,
locator: '[data-overlay-toolbar-index="1"]',
@ -887,18 +856,9 @@ profile001 = startProfileAt([56.37, 120.33], sketch001)
await clickUnconstrained({
hoverPos: { x: arcTo.x, y: arcTo.y },
constraintType: 'yAbsolute',
expectBeforeUnconstrained: `arcTo({
interior = [xAbs001, 231.76],
end = [xAbs002, 131.54]
}, %)`,
expectAfterUnconstrained: `arcTo({
interior = [xAbs001, 231.76],
end = [xAbs002, yAbs002]
}, %)`,
expectFinal: `arcTo({
interior = [xAbs001, 231.76],
end = [xAbs002, 131.54]
}, %)`,
expectBeforeUnconstrained: `arc(interiorAbsolute = [xAbs001, 231.76], endAbsolute = [xAbs002, 131.54])`,
expectAfterUnconstrained: `arc(interiorAbsolute = [xAbs001, 231.76], endAbsolute = [xAbs002, yAbs002])`,
expectFinal: `arc(interiorAbsolute = [xAbs001, 231.76], endAbsolute = [xAbs002, 131.54])`,
ang: ang + 180,
steps: 10,
locator: '[data-overlay-toolbar-index="1"]',
@ -1045,15 +1005,8 @@ part001 = startSketchOn(XZ)
|> angledLine(angle = 89, endAbsoluteY = 9.14 + 0)
|> angledLineThatIntersects(angle = 4.14, intersectTag = a, offset = 9)
|> tangentialArc(endAbsolute = [3.14 + 13, 1.14])
|> arcTo({
interior = [16.25, 5.12],
end = [21.61, 4.15]
}, %)
|> arc({
radius = 9.03,
angleStart = 40.27,
angleEnd = -38.05
}, %)
|> arc(interiorAbsolute = [16.25, 5.12], endAbsolute = [21.61, 4.15])
|> arc(angleStart = 40.27, angleEnd = -38.05, radius = 9.03)
`
)
@ -1087,11 +1040,7 @@ part001 = startSketchOn(XZ)
await deleteSegmentSequence({
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
codeToBeDeleted: `arc({
radius = 9.03,
angleStart = 40.27,
angleEnd = -38.05
}, %)`,
codeToBeDeleted: `arc(angleStart = 40.27, angleEnd = -38.05, radius = 9.03)`,
stdLibFnName: 'arc',
ang: ang + 180,
steps: 6,
@ -1101,11 +1050,8 @@ part001 = startSketchOn(XZ)
ang = await u.getAngle('[data-overlay-index="13"]')
await deleteSegmentSequence({
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
codeToBeDeleted: `arcTo({
interior = [16.25, 5.12],
end = [21.61, 4.15]
}, %)`,
stdLibFnName: 'arcTo',
codeToBeDeleted: `arc(interiorAbsolute = [16.25, 5.12], endAbsolute = [21.61, 4.15])`,
stdLibFnName: 'arc',
ang: ang,
steps: 6,
locator: '[data-overlay-toolbar-index="13"]',

352
package-lock.json generated
View File

@ -22,7 +22,7 @@
"@codemirror/search": "^6.5.10",
"@codemirror/state": "^6.5.2",
"@codemirror/theme-one-dark": "^6.1.2",
"@csstools/postcss-oklab-function": "^4.0.8",
"@csstools/postcss-oklab-function": "^4.0.9",
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2",
"@fortawesome/free-solid-svg-icons": "^6.7.2",
@ -85,7 +85,7 @@
"@iarna/toml": "^2.2.5",
"@lezer/generator": "^1.7.3",
"@nabla/vite-plugin-eslint": "^2.0.5",
"@playwright/test": "^1.51.1",
"@playwright/test": "^1.52.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^15.0.2",
"@types/diff": "^7.0.2",
@ -93,7 +93,7 @@
"@types/isomorphic-fetch": "^0.0.39",
"@types/minimist": "^1.2.5",
"@types/mocha": "^10.0.10",
"@types/node": "^22.14.0",
"@types/node": "^22.14.1",
"@types/pixelmatch": "^5.2.6",
"@types/pngjs": "^6.0.4",
"@types/react": "^18.3.4",
@ -104,7 +104,7 @@
"@types/uuid": "^9.0.8",
"@types/wicg-file-system-access": "^2023.10.6",
"@types/ws": "^8.18.1",
"@vitejs/plugin-react": "^4.3.4",
"@vitejs/plugin-react": "^4.4.1",
"@vitest/web-worker": "^1.5.0",
"@xstate/cli": "^0.5.17",
"autoprefixer": "^10.4.21",
@ -135,7 +135,7 @@
"tailwindcss": "^3.4.17",
"ts-node": "^10.0.0",
"typescript": "^5.8.3",
"typescript-eslint": "^8.29.0",
"typescript-eslint": "^8.30.1",
"vite": "^5.4.18",
"vite-plugin-package-version": "^1.1.0",
"vite-plugin-top-level-await": "^1.5.0",
@ -2222,9 +2222,9 @@
}
},
"node_modules/@csstools/css-calc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.2.tgz",
"integrity": "sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw==",
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.3.tgz",
"integrity": "sha512-XBG3talrhid44BY1x3MHzUx/aTG8+x/Zi57M4aTKK9RFB4aLlF3TTSzfzn8nWVHWL3FgAXAxmupmDd6VWww+pw==",
"funding": [
{
"type": "github",
@ -2245,9 +2245,9 @@
}
},
"node_modules/@csstools/css-color-parser": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.8.tgz",
"integrity": "sha512-pdwotQjCCnRPuNi06jFuP68cykU1f3ZWExLe/8MQ1LOs8Xq+fTkYgd+2V8mWUWMrOn9iS2HftPVaMZDaXzGbhQ==",
"version": "3.0.9",
"resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.9.tgz",
"integrity": "sha512-wILs5Zk7BU86UArYBJTPy/FMPPKVKHMj1ycCEyf3VUptol0JNRLFU/BZsJ4aiIHJEbSLiizzRrw8Pc1uAEDrXw==",
"funding": [
{
"type": "github",
@ -2261,7 +2261,7 @@
"license": "MIT",
"dependencies": {
"@csstools/color-helpers": "^5.0.2",
"@csstools/css-calc": "^2.1.2"
"@csstools/css-calc": "^2.1.3"
},
"engines": {
"node": ">=18"
@ -2313,9 +2313,9 @@
}
},
"node_modules/@csstools/postcss-oklab-function": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.8.tgz",
"integrity": "sha512-+5aPsNWgxohXoYNS1f+Ys0x3Qnfehgygv3qrPyv+Y25G0yX54/WlVB+IXprqBLOXHM1gsVF+QQSjlArhygna0Q==",
"version": "4.0.9",
"resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.9.tgz",
"integrity": "sha512-UHrnujimwtdDw8BYDcWJtBXuJ13uc/BjAddPdfMc/RsWxhg8gG8UbvTF0tnMtHrZ4i7lwy85fPEzK1AiykMyRA==",
"funding": [
{
"type": "github",
@ -2328,10 +2328,10 @@
],
"license": "MIT-0",
"dependencies": {
"@csstools/css-color-parser": "^3.0.8",
"@csstools/css-color-parser": "^3.0.9",
"@csstools/css-parser-algorithms": "^3.0.4",
"@csstools/css-tokenizer": "^3.0.3",
"@csstools/postcss-progressive-custom-properties": "^4.0.0",
"@csstools/postcss-progressive-custom-properties": "^4.0.1",
"@csstools/utilities": "^2.0.0"
},
"engines": {
@ -2342,9 +2342,9 @@
}
},
"node_modules/@csstools/postcss-progressive-custom-properties": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.0.0.tgz",
"integrity": "sha512-XQPtROaQjomnvLUSy/bALTR5VCtTVUFwYs1SblvYgLSeTo2a/bMNwUwo2piXw5rTv/FEYiy5yPSXBqg9OKUx7Q==",
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.0.1.tgz",
"integrity": "sha512-Ofz81HaY8mmbP8/Qr3PZlUzjsyV5WuxWmvtYn+jhYGvvjFazTmN9R2io5W5znY1tyk2CA9uM0IPWyY4ygDytCw==",
"funding": [
{
"type": "github",
@ -4286,13 +4286,13 @@
}
},
"node_modules/@playwright/test": {
"version": "1.51.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.51.1.tgz",
"integrity": "sha512-nM+kEaTSAoVlXmMPH10017vn3FSiFqr/bh4fKg9vmAdMfd9SDqRZNvPSiAHADc/itWak+qPvMPZQOPwCBW7k7Q==",
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.52.0.tgz",
"integrity": "sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright": "1.51.1"
"playwright": "1.52.0"
},
"bin": {
"playwright": "cli.js"
@ -4526,9 +4526,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.39.0.tgz",
"integrity": "sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.0.tgz",
"integrity": "sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==",
"cpu": [
"arm"
],
@ -4540,9 +4540,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.39.0.tgz",
"integrity": "sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.0.tgz",
"integrity": "sha512-PPA6aEEsTPRz+/4xxAmaoWDqh67N7wFbgFUJGMnanCFs0TV99M0M8QhhaSCks+n6EbQoFvLQgYOGXxlMGQe/6w==",
"cpu": [
"arm64"
],
@ -4554,9 +4554,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.39.0.tgz",
"integrity": "sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.0.tgz",
"integrity": "sha512-GwYOcOakYHdfnjjKwqpTGgn5a6cUX7+Ra2HeNj/GdXvO2VJOOXCiYYlRFU4CubFM67EhbmzLOmACKEfvp3J1kQ==",
"cpu": [
"arm64"
],
@ -4568,9 +4568,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.39.0.tgz",
"integrity": "sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.0.tgz",
"integrity": "sha512-CoLEGJ+2eheqD9KBSxmma6ld01czS52Iw0e2qMZNpPDlf7Z9mj8xmMemxEucinev4LgHalDPczMyxzbq+Q+EtA==",
"cpu": [
"x64"
],
@ -4582,9 +4582,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.39.0.tgz",
"integrity": "sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.0.tgz",
"integrity": "sha512-r7yGiS4HN/kibvESzmrOB/PxKMhPTlz+FcGvoUIKYoTyGd5toHp48g1uZy1o1xQvybwwpqpe010JrcGG2s5nkg==",
"cpu": [
"arm64"
],
@ -4596,9 +4596,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.39.0.tgz",
"integrity": "sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.0.tgz",
"integrity": "sha512-mVDxzlf0oLzV3oZOr0SMJ0lSDd3xC4CmnWJ8Val8isp9jRGl5Dq//LLDSPFrasS7pSm6m5xAcKaw3sHXhBjoRw==",
"cpu": [
"x64"
],
@ -4610,9 +4610,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.39.0.tgz",
"integrity": "sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.0.tgz",
"integrity": "sha512-y/qUMOpJxBMy8xCXD++jeu8t7kzjlOCkoxxajL58G62PJGBZVl/Gwpm7JK9+YvlB701rcQTzjUZ1JgUoPTnoQA==",
"cpu": [
"arm"
],
@ -4624,9 +4624,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.39.0.tgz",
"integrity": "sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.0.tgz",
"integrity": "sha512-GoCsPibtVdJFPv/BOIvBKO/XmwZLwaNWdyD8TKlXuqp0veo2sHE+A/vpMQ5iSArRUz/uaoj4h5S6Pn0+PdhRjg==",
"cpu": [
"arm"
],
@ -4638,9 +4638,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.39.0.tgz",
"integrity": "sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.0.tgz",
"integrity": "sha512-L5ZLphTjjAD9leJzSLI7rr8fNqJMlGDKlazW2tX4IUF9P7R5TMQPElpH82Q7eNIDQnQlAyiNVfRPfP2vM5Avvg==",
"cpu": [
"arm64"
],
@ -4652,9 +4652,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.39.0.tgz",
"integrity": "sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.0.tgz",
"integrity": "sha512-ATZvCRGCDtv1Y4gpDIXsS+wfFeFuLwVxyUBSLawjgXK2tRE6fnsQEkE4csQQYWlBlsFztRzCnBvWVfcae/1qxQ==",
"cpu": [
"arm64"
],
@ -4666,9 +4666,9 @@
]
},
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.39.0.tgz",
"integrity": "sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.0.tgz",
"integrity": "sha512-wG9e2XtIhd++QugU5MD9i7OnpaVb08ji3P1y/hNbxrQ3sYEelKJOq1UJ5dXczeo6Hj2rfDEL5GdtkMSVLa/AOg==",
"cpu": [
"loong64"
],
@ -4680,9 +4680,9 @@
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.39.0.tgz",
"integrity": "sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.0.tgz",
"integrity": "sha512-vgXfWmj0f3jAUvC7TZSU/m/cOE558ILWDzS7jBhiCAFpY2WEBn5jqgbqvmzlMjtp8KlLcBlXVD2mkTSEQE6Ixw==",
"cpu": [
"ppc64"
],
@ -4694,9 +4694,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.39.0.tgz",
"integrity": "sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.0.tgz",
"integrity": "sha512-uJkYTugqtPZBS3Z136arevt/FsKTF/J9dEMTX/cwR7lsAW4bShzI2R0pJVw+hcBTWF4dxVckYh72Hk3/hWNKvA==",
"cpu": [
"riscv64"
],
@ -4708,9 +4708,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.39.0.tgz",
"integrity": "sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.0.tgz",
"integrity": "sha512-rKmSj6EXQRnhSkE22+WvrqOqRtk733x3p5sWpZilhmjnkHkpeCgWsFFo0dGnUGeA+OZjRl3+VYq+HyCOEuwcxQ==",
"cpu": [
"riscv64"
],
@ -4722,9 +4722,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.39.0.tgz",
"integrity": "sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.0.tgz",
"integrity": "sha512-SpnYlAfKPOoVsQqmTFJ0usx0z84bzGOS9anAC0AZ3rdSo3snecihbhFTlJZ8XMwzqAcodjFU4+/SM311dqE5Sw==",
"cpu": [
"s390x"
],
@ -4736,9 +4736,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.39.0.tgz",
"integrity": "sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.0.tgz",
"integrity": "sha512-RcDGMtqF9EFN8i2RYN2W+64CdHruJ5rPqrlYw+cgM3uOVPSsnAQps7cpjXe9be/yDp8UC7VLoCoKC8J3Kn2FkQ==",
"cpu": [
"x64"
],
@ -4750,9 +4750,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.39.0.tgz",
"integrity": "sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.0.tgz",
"integrity": "sha512-HZvjpiUmSNx5zFgwtQAV1GaGazT2RWvqeDi0hV+AtC8unqqDSsaFjPxfsO6qPtKRRg25SisACWnJ37Yio8ttaw==",
"cpu": [
"x64"
],
@ -4764,9 +4764,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.39.0.tgz",
"integrity": "sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.0.tgz",
"integrity": "sha512-UtZQQI5k/b8d7d3i9AZmA/t+Q4tk3hOC0tMOMSq2GlMYOfxbesxG4mJSeDp0EHs30N9bsfwUvs3zF4v/RzOeTQ==",
"cpu": [
"arm64"
],
@ -4778,9 +4778,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.39.0.tgz",
"integrity": "sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.0.tgz",
"integrity": "sha512-+m03kvI2f5syIqHXCZLPVYplP8pQch9JHyXKZ3AGMKlg8dCyr2PKHjwRLiW53LTrN/Nc3EqHOKxUxzoSPdKddA==",
"cpu": [
"ia32"
],
@ -4792,9 +4792,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.39.0.tgz",
"integrity": "sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.0.tgz",
"integrity": "sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ==",
"cpu": [
"x64"
],
@ -5518,9 +5518,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.14.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz",
"integrity": "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==",
"version": "22.14.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz",
"integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -5728,17 +5728,17 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.29.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.1.tgz",
"integrity": "sha512-ba0rr4Wfvg23vERs3eB+P3lfj2E+2g3lhWcCVukUuhtcdUx5lSIFZlGFEBHKr+3zizDa/TvZTptdNHVZWAkSBg==",
"version": "8.30.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.30.1.tgz",
"integrity": "sha512-v+VWphxMjn+1t48/jO4t950D6KR8JaJuNXzi33Ve6P8sEmPr5k6CEXjdGwT6+LodVnEa91EQCtwjWNUCPweo+Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.29.1",
"@typescript-eslint/type-utils": "8.29.1",
"@typescript-eslint/utils": "8.29.1",
"@typescript-eslint/visitor-keys": "8.29.1",
"@typescript-eslint/scope-manager": "8.30.1",
"@typescript-eslint/type-utils": "8.30.1",
"@typescript-eslint/utils": "8.30.1",
"@typescript-eslint/visitor-keys": "8.30.1",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
@ -5758,16 +5758,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.29.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.1.tgz",
"integrity": "sha512-zczrHVEqEaTwh12gWBIJWj8nx+ayDcCJs06yoNMY0kwjMWDM6+kppljY+BxWI06d2Ja+h4+WdufDcwMnnMEWmg==",
"version": "8.30.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.30.1.tgz",
"integrity": "sha512-H+vqmWwT5xoNrXqWs/fesmssOW70gxFlgcMlYcBaWNPIEWDgLa4W9nkSPmhuOgLnXq9QYgkZ31fhDyLhleCsAg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/scope-manager": "8.29.1",
"@typescript-eslint/types": "8.29.1",
"@typescript-eslint/typescript-estree": "8.29.1",
"@typescript-eslint/visitor-keys": "8.29.1",
"@typescript-eslint/scope-manager": "8.30.1",
"@typescript-eslint/types": "8.30.1",
"@typescript-eslint/typescript-estree": "8.30.1",
"@typescript-eslint/visitor-keys": "8.30.1",
"debug": "^4.3.4"
},
"engines": {
@ -5783,14 +5783,14 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.29.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.1.tgz",
"integrity": "sha512-2nggXGX5F3YrsGN08pw4XpMLO1Rgtnn4AzTegC2MDesv6q3QaTU5yU7IbS1tf1IwCR0Hv/1EFygLn9ms6LIpDA==",
"version": "8.30.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.30.1.tgz",
"integrity": "sha512-+C0B6ChFXZkuaNDl73FJxRYT0G7ufVPOSQkqkpM/U198wUwUFOtgo1k/QzFh1KjpBitaK7R1tgjVz6o9HmsRPg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.29.1",
"@typescript-eslint/visitor-keys": "8.29.1"
"@typescript-eslint/types": "8.30.1",
"@typescript-eslint/visitor-keys": "8.30.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -5801,14 +5801,14 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.29.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.29.1.tgz",
"integrity": "sha512-DkDUSDwZVCYN71xA4wzySqqcZsHKic53A4BLqmrWFFpOpNSoxX233lwGu/2135ymTCR04PoKiEEEvN1gFYg4Tw==",
"version": "8.30.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.30.1.tgz",
"integrity": "sha512-64uBF76bfQiJyHgZISC7vcNz3adqQKIccVoKubyQcOnNcdJBvYOILV1v22Qhsw3tw3VQu5ll8ND6hycgAR5fEA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/typescript-estree": "8.29.1",
"@typescript-eslint/utils": "8.29.1",
"@typescript-eslint/typescript-estree": "8.30.1",
"@typescript-eslint/utils": "8.30.1",
"debug": "^4.3.4",
"ts-api-utils": "^2.0.1"
},
@ -5825,9 +5825,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.29.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.1.tgz",
"integrity": "sha512-VT7T1PuJF1hpYC3AGm2rCgJBjHL3nc+A/bhOp9sGMKfi5v0WufsX/sHCFBfNTx2F+zA6qBc/PD0/kLRLjdt8mQ==",
"version": "8.30.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.30.1.tgz",
"integrity": "sha512-81KawPfkuulyWo5QdyG/LOKbspyyiW+p4vpn4bYO7DM/hZImlVnFwrpCTnmNMOt8CvLRr5ojI9nU1Ekpw4RcEw==",
"dev": true,
"license": "MIT",
"engines": {
@ -5839,14 +5839,14 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.29.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.1.tgz",
"integrity": "sha512-l1enRoSaUkQxOQnbi0KPUtqeZkSiFlqrx9/3ns2rEDhGKfTa+88RmXqedC1zmVTOWrLc2e6DEJrTA51C9iLH5g==",
"version": "8.30.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.30.1.tgz",
"integrity": "sha512-kQQnxymiUy9tTb1F2uep9W6aBiYODgq5EMSk6Nxh4Z+BDUoYUSa029ISs5zTzKBFnexQEh71KqwjKnRz58lusQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.29.1",
"@typescript-eslint/visitor-keys": "8.29.1",
"@typescript-eslint/types": "8.30.1",
"@typescript-eslint/visitor-keys": "8.30.1",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@ -5905,16 +5905,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "8.29.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.29.1.tgz",
"integrity": "sha512-QAkFEbytSaB8wnmB+DflhUPz6CLbFWE2SnSCrRMEa+KnXIzDYbpsn++1HGvnfAsUY44doDXmvRkO5shlM/3UfA==",
"version": "8.30.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.30.1.tgz",
"integrity": "sha512-T/8q4R9En2tcEsWPQgB5BQ0XJVOtfARcUvOa8yJP3fh9M/mXraLxZrkCfGb6ChrO/V3W+Xbd04RacUEqk1CFEQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@typescript-eslint/scope-manager": "8.29.1",
"@typescript-eslint/types": "8.29.1",
"@typescript-eslint/typescript-estree": "8.29.1"
"@typescript-eslint/scope-manager": "8.30.1",
"@typescript-eslint/types": "8.30.1",
"@typescript-eslint/typescript-estree": "8.30.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -5929,13 +5929,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.29.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.1.tgz",
"integrity": "sha512-RGLh5CRaUEf02viP5c1Vh1cMGffQscyHe7HPAzGpfmfflFg1wUz2rYxd+OZqwpeypYvZ8UxSxuIpF++fmOzEcg==",
"version": "8.30.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.30.1.tgz",
"integrity": "sha512-aEhgas7aJ6vZnNFC7K4/vMGDGyOiqWcYZPpIWrTKuTAlsvDNKy2GFDqh9smL+iq069ZvR0YzEeq0B8NJlLzjFA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.29.1",
"@typescript-eslint/types": "8.30.1",
"eslint-visitor-keys": "^4.2.0"
},
"engines": {
@ -5967,17 +5967,17 @@
"license": "ISC"
},
"node_modules/@vitejs/plugin-react": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz",
"integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==",
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.4.1.tgz",
"integrity": "sha512-IpEm5ZmeXAP/osiBXVVP5KjFMzbWOonMs0NaQQl+xYnUAcq4oHUBsF2+p4MgKWG4YMmFYJU8A6sxRPuowllm6w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/core": "^7.26.0",
"@babel/core": "^7.26.10",
"@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"
"react-refresh": "^0.17.0"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
@ -16361,13 +16361,13 @@
"license": "MIT"
},
"node_modules/playwright": {
"version": "1.51.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.51.1.tgz",
"integrity": "sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==",
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.52.0.tgz",
"integrity": "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright-core": "1.51.1"
"playwright-core": "1.52.0"
},
"bin": {
"playwright": "cli.js"
@ -16380,9 +16380,9 @@
}
},
"node_modules/playwright-core": {
"version": "1.51.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.51.1.tgz",
"integrity": "sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==",
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.52.0.tgz",
"integrity": "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@ -17089,9 +17089,9 @@
}
},
"node_modules/react-refresh": {
"version": "0.14.2",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
"integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
"integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
"dev": true,
"license": "MIT",
"engines": {
@ -17661,9 +17661,9 @@
}
},
"node_modules/rollup": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.39.0.tgz",
"integrity": "sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==",
"version": "4.40.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.0.tgz",
"integrity": "sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -17677,26 +17677,26 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.39.0",
"@rollup/rollup-android-arm64": "4.39.0",
"@rollup/rollup-darwin-arm64": "4.39.0",
"@rollup/rollup-darwin-x64": "4.39.0",
"@rollup/rollup-freebsd-arm64": "4.39.0",
"@rollup/rollup-freebsd-x64": "4.39.0",
"@rollup/rollup-linux-arm-gnueabihf": "4.39.0",
"@rollup/rollup-linux-arm-musleabihf": "4.39.0",
"@rollup/rollup-linux-arm64-gnu": "4.39.0",
"@rollup/rollup-linux-arm64-musl": "4.39.0",
"@rollup/rollup-linux-loongarch64-gnu": "4.39.0",
"@rollup/rollup-linux-powerpc64le-gnu": "4.39.0",
"@rollup/rollup-linux-riscv64-gnu": "4.39.0",
"@rollup/rollup-linux-riscv64-musl": "4.39.0",
"@rollup/rollup-linux-s390x-gnu": "4.39.0",
"@rollup/rollup-linux-x64-gnu": "4.39.0",
"@rollup/rollup-linux-x64-musl": "4.39.0",
"@rollup/rollup-win32-arm64-msvc": "4.39.0",
"@rollup/rollup-win32-ia32-msvc": "4.39.0",
"@rollup/rollup-win32-x64-msvc": "4.39.0",
"@rollup/rollup-android-arm-eabi": "4.40.0",
"@rollup/rollup-android-arm64": "4.40.0",
"@rollup/rollup-darwin-arm64": "4.40.0",
"@rollup/rollup-darwin-x64": "4.40.0",
"@rollup/rollup-freebsd-arm64": "4.40.0",
"@rollup/rollup-freebsd-x64": "4.40.0",
"@rollup/rollup-linux-arm-gnueabihf": "4.40.0",
"@rollup/rollup-linux-arm-musleabihf": "4.40.0",
"@rollup/rollup-linux-arm64-gnu": "4.40.0",
"@rollup/rollup-linux-arm64-musl": "4.40.0",
"@rollup/rollup-linux-loongarch64-gnu": "4.40.0",
"@rollup/rollup-linux-powerpc64le-gnu": "4.40.0",
"@rollup/rollup-linux-riscv64-gnu": "4.40.0",
"@rollup/rollup-linux-riscv64-musl": "4.40.0",
"@rollup/rollup-linux-s390x-gnu": "4.40.0",
"@rollup/rollup-linux-x64-gnu": "4.40.0",
"@rollup/rollup-linux-x64-musl": "4.40.0",
"@rollup/rollup-win32-arm64-msvc": "4.40.0",
"@rollup/rollup-win32-ia32-msvc": "4.40.0",
"@rollup/rollup-win32-x64-msvc": "4.40.0",
"fsevents": "~2.3.2"
}
},
@ -19723,15 +19723,15 @@
}
},
"node_modules/typescript-eslint": {
"version": "8.29.1",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.29.1.tgz",
"integrity": "sha512-f8cDkvndhbQMPcysk6CUSGBWV+g1utqdn71P5YKwMumVMOG/5k7cHq0KyG4O52nB0oKS4aN2Tp5+wB4APJGC+w==",
"version": "8.30.1",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.30.1.tgz",
"integrity": "sha512-D7lC0kcehVH7Mb26MRQi64LMyRJsj3dToJxM1+JVTl53DQSV5/7oUGWQLcKl1C1KnoVHxMMU2FNQMffr7F3Row==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "8.29.1",
"@typescript-eslint/parser": "8.29.1",
"@typescript-eslint/utils": "8.29.1"
"@typescript-eslint/eslint-plugin": "8.30.1",
"@typescript-eslint/parser": "8.30.1",
"@typescript-eslint/utils": "8.30.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -21205,7 +21205,7 @@
"devDependencies": {
"@lezer/generator": "^1.7.3",
"@rollup/plugin-typescript": "^12.1.2",
"rollup": "^4.29.1",
"rollup": "^4.40.0",
"rollup-plugin-dts": "^6.1.1",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.1.1"
@ -21504,7 +21504,7 @@
"vscode-uri": "^3.1.0"
},
"devDependencies": {
"@types/node": "^22.14.0",
"@types/node": "^22.14.1",
"ts-node": "^10.9.2"
}
},
@ -21518,7 +21518,7 @@
"@tsconfig/strictest": "^2.0.5",
"@types/glob": "^8.1.0",
"@types/mocha": "^10.0.10",
"@types/node": "^22.13.10",
"@types/node": "^22.14.1",
"@types/vscode": "^1.97.0",
"@typescript-eslint/eslint-plugin": "^8.27.0",
"@typescript-eslint/parser": "^8.27.0",

View File

@ -24,7 +24,7 @@
"@codemirror/search": "^6.5.10",
"@codemirror/state": "^6.5.2",
"@codemirror/theme-one-dark": "^6.1.2",
"@csstools/postcss-oklab-function": "^4.0.8",
"@csstools/postcss-oklab-function": "^4.0.9",
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2",
"@fortawesome/free-solid-svg-icons": "^6.7.2",
@ -167,7 +167,7 @@
"@iarna/toml": "^2.2.5",
"@lezer/generator": "^1.7.3",
"@nabla/vite-plugin-eslint": "^2.0.5",
"@playwright/test": "^1.51.1",
"@playwright/test": "^1.52.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^15.0.2",
"@types/diff": "^7.0.2",
@ -175,7 +175,7 @@
"@types/isomorphic-fetch": "^0.0.39",
"@types/minimist": "^1.2.5",
"@types/mocha": "^10.0.10",
"@types/node": "^22.14.0",
"@types/node": "^22.14.1",
"@types/pixelmatch": "^5.2.6",
"@types/pngjs": "^6.0.4",
"@types/react": "^18.3.4",
@ -186,7 +186,7 @@
"@types/uuid": "^9.0.8",
"@types/wicg-file-system-access": "^2023.10.6",
"@types/ws": "^8.18.1",
"@vitejs/plugin-react": "^4.3.4",
"@vitejs/plugin-react": "^4.4.1",
"@vitest/web-worker": "^1.5.0",
"@xstate/cli": "^0.5.17",
"autoprefixer": "^10.4.21",
@ -217,7 +217,7 @@
"tailwindcss": "^3.4.17",
"ts-node": "^10.0.0",
"typescript": "^5.8.3",
"typescript-eslint": "^8.29.0",
"typescript-eslint": "^8.30.1",
"vite": "^5.4.18",
"vite-plugin-package-version": "^1.1.0",
"vite-plugin-top-level-await": "^1.5.0",

View File

@ -27,7 +27,7 @@
"devDependencies": {
"@lezer/generator": "^1.7.3",
"@rollup/plugin-typescript": "^12.1.2",
"rollup": "^4.29.1",
"rollup": "^4.40.0",
"rollup-plugin-dts": "^6.1.1",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.1.1"

View File

@ -29,7 +29,7 @@
"vscode-uri": "^3.1.0"
},
"devDependencies": {
"@types/node": "^22.14.0",
"@types/node": "^22.14.1",
"ts-node": "^10.9.2"
}
}

View File

@ -12,22 +12,10 @@ fn rail8020(originStart, railHeight, railLength) {
originStart[0],
0.1 * railHeight + originStart[1]
], %)
|> arc({
angleStart = 180,
angleEnd = 270,
radius = 0.1 * railHeight
}, %)
|> arc({
angleStart = 180,
angleEnd = 0,
radius = 0.072 / 4 * railHeight
}, %)
|> arc(angleStart = 180, angleEnd = 270, radius = 0.1 * railHeight)
|> arc(angleStart = 180, angleEnd = 0, radius = 0.072 / 4 * railHeight)
|> xLine(length = 0.1 * railHeight)
|> arc({
angleStart = 180,
angleEnd = 0,
radius = 0.072 / 4 * railHeight
}, %)
|> arc(angleStart = 180, angleEnd = 0, radius = 0.072 / 4 * railHeight)
|> xLine(length = 0.06 * railHeight, tag = $edge1)
|> yLine(length = 0.087 * railHeight, tag = $edge2)
|> xLine(length = -0.183 * railHeight, tag = $edge3)
@ -37,35 +25,15 @@ fn rail8020(originStart, railHeight, railLength) {
|> xLine(length = -0.183 * railHeight, tag = $edge7)
|> yLine(length = -0.087 * railHeight, tag = $edge8)
|> xLine(length = 0.06 * railHeight)
|> arc({
angleStart = 180,
angleEnd = 0,
radius = 0.072 / 4 * railHeight
}, %)
|> arc(angleStart = 180, angleEnd = 0, radius = 0.072 / 4 * railHeight)
|> xLine(length = 0.1 * railHeight)
|> arc({
angleStart = 180,
angleEnd = 0,
radius = 0.072 / 4 * railHeight
}, %)
|> arc({
angleStart = -90,
angleEnd = 0,
radius = 0.1 * railHeight
}, %)
|> arc(angleStart = 180, angleEnd = 0, radius = 0.072 / 4 * railHeight)
|> arc(angleStart = -90, angleEnd = 0, radius = 0.1 * railHeight)
// Sketch side 2 of profile
|> arc({
angleStart = 270,
angleEnd = 90,
radius = 0.072 / 4 * railHeight
}, %)
|> arc(angleStart = 270, angleEnd = 90, radius = 0.072 / 4 * railHeight)
|> yLine(length = 0.1 * railHeight)
|> arc({
angleStart = 270,
angleEnd = 90,
radius = 0.072 / 4 * railHeight
}, %)
|> arc(angleStart = 270, angleEnd = 90, radius = 0.072 / 4 * railHeight)
|> yLine(length = 0.06 * railHeight, tag = $edge9)
|> xLine(length = -0.087 * railHeight, tag = $edge10)
|> yLine(length = -0.183 * railHeight, tag = $edge11) // edge11
@ -75,35 +43,15 @@ fn rail8020(originStart, railHeight, railLength) {
|> yLine(length = -0.183 * railHeight, tag = $edge15) // 15
|> xLine(length = 0.087 * railHeight, tag = $edge16)
|> yLine(length = 0.06 * railHeight)
|> arc({
angleStart = 270,
angleEnd = 90,
radius = 0.072 / 4 * railHeight
}, %)
|> arc(angleStart = 270, angleEnd = 90, radius = 0.072 / 4 * railHeight)
|> yLine(length = 0.1 * railHeight)
|> arc({
angleStart = 270,
angleEnd = 90,
radius = 0.072 / 4 * railHeight
}, %)
|> arc(angleStart = 270, angleEnd = 90, radius = 0.072 / 4 * railHeight)
// Sketch side 3 of profile
|> arc({
angleStart = 0,
angleEnd = 90,
radius = 0.1 * railHeight
}, %)
|> arc({
angleStart = 0,
angleEnd = -180,
radius = 0.072 / 4 * railHeight
}, %)
|> arc(angleStart = 0, angleEnd = 90, radius = 0.1 * railHeight)
|> arc(angleStart = 0, angleEnd = -180, radius = 0.072 / 4 * railHeight)
|> xLine(length = -0.1 * railHeight)
|> arc({
angleStart = 0,
angleEnd = -180,
radius = 0.072 / 4 * railHeight
}, %)
|> arc(angleStart = 0, angleEnd = -180, radius = 0.072 / 4 * railHeight)
|> xLine(length = -0.06 * railHeight, tag = $edge17)
|> yLine(length = -0.087 * railHeight, tag = $edge18)
|> xLine(length = 0.183 * railHeight, tag = $edge19)
@ -113,35 +61,15 @@ fn rail8020(originStart, railHeight, railLength) {
|> xLine(length = 0.183 * railHeight, tag = $edge23)
|> yLine(length = 0.087 * railHeight, tag = $edge24)
|> xLine(length = -0.06 * railHeight)
|> arc({
angleStart = 0,
angleEnd = -180,
radius = 0.072 / 4 * railHeight
}, %)
|> arc(angleStart = 0, angleEnd = -180, radius = 0.072 / 4 * railHeight)
|> xLine(length = -0.1 * railHeight)
|> arc({
angleStart = 0,
angleEnd = -180,
radius = 0.072 / 4 * railHeight
}, %)
|> arc({
angleStart = 90,
angleEnd = 180,
radius = 0.1 * railHeight
}, %)
|> arc(angleStart = 0, angleEnd = -180, radius = 0.072 / 4 * railHeight)
|> arc(angleStart = 90, angleEnd = 180, radius = 0.1 * railHeight)
// Sketch side 4 of profile
|> arc({
angleStart = 90,
angleEnd = -90,
radius = 0.072 / 4 * railHeight
}, %)
|> arc(angleStart = 90, angleEnd = -90, radius = 0.072 / 4 * railHeight)
|> yLine(length = -0.1 * railHeight)
|> arc({
angleStart = 90,
angleEnd = -90,
radius = 0.072 / 4 * railHeight
}, %)
|> arc(angleStart = 90, angleEnd = -90, radius = 0.072 / 4 * railHeight)
|> yLine(length = -0.06 * railHeight, tag = $edge25)
|> xLine(length = 0.087 * railHeight, tag = $edge26)
|> yLine(length = 0.183 * railHeight, tag = $edge27)
@ -151,17 +79,9 @@ fn rail8020(originStart, railHeight, railLength) {
|> yLine(length = 0.183 * railHeight, tag = $edge31)
|> xLine(length = -0.087 * railHeight, tag = $edge32)
|> yLine(length = -0.06 * railHeight)
|> arc({
angleStart = 90,
angleEnd = -90,
radius = 0.072 / 4 * railHeight
}, %)
|> arc(angleStart = 90, angleEnd = -90, radius = 0.072 / 4 * railHeight)
|> yLine(length = -0.1 * railHeight)
|> arc({
angleStart = 90,
angleEnd = -90,
radius = 0.072 / 4 * railHeight
}, %)
|> arc(angleStart = 90, angleEnd = -90, radius = 0.072 / 4 * railHeight)
|> close()
// Sketch center hole of profile

View File

@ -39,38 +39,34 @@ fn fanBlade(offsetHeight, startAngle) {
15 * cos(toRadians(startAngle)),
15 * sin(toRadians(startAngle))
], %)
|> arc({
angleStart = startAngle,
angleEnd = startAngle + 14,
radius = 15
}, %)
|> arcTo({
end = [
|> arc(angleStart = startAngle, angleEnd = startAngle + 14, radius = 15)
|> arc(
endAbsolute = [
fanSize * 22 / 50 * cos(toRadians(startAngle - 20)),
fanSize * 22 / 50 * sin(toRadians(startAngle - 20))
],
interior = [
interiorAbsolute = [
fanSize * 11 / 50 * cos(toRadians(startAngle + 3)),
fanSize * 11 / 50 * sin(toRadians(startAngle + 3))
]
}, %)
|> arcTo({
end = [
],
)
|> arc(
endAbsolute = [
fanSize * 22 / 50 * cos(toRadians(startAngle - 24)),
fanSize * 22 / 50 * sin(toRadians(startAngle - 24))
],
interior = [
interiorAbsolute = [
fanSize * 22 / 50 * cos(toRadians(startAngle - 22)),
fanSize * 22 / 50 * sin(toRadians(startAngle - 22))
]
}, %)
|> arcTo({
end = [profileStartX(%), profileStartY(%)],
interior = [
],
)
|> arc(
endAbsolute = [profileStartX(%), profileStartY(%)],
interiorAbsolute = [
fanSize * 11 / 50 * cos(toRadians(startAngle - 5)),
fanSize * 11 / 50 * sin(toRadians(startAngle - 5))
]
}, %)
],
)
|> close()
return fanBlade
}

View File

@ -27,11 +27,7 @@ insideWall = extrude(insideWallSketch, length = overallThickness)
// Create the sketch of one of the balls
ballsSketch = startSketchOn(XY)
|> startProfileAt([shaftDia / 2 + wallThickness, 0.001], %)
|> arc({
angleEnd = 0,
angleStart = 180,
radius = sphereDia / 2
}, %)
|> arc(angleStart = 180, angleEnd = 0, radius = sphereDia / 2)
|> close()
// Revolve the ball to make a sphere and pattern around the inside wall
@ -50,11 +46,7 @@ chainSketch = startSketchOn(XY)
shaftDia / 2 + wallThickness + sphereDia / 2 - (chainWidth / 2),
0.125 * sin(toRadians(60))
], %)
|> arc({
angleEnd = 60,
angleStart = 120,
radius = sphereDia / 2
}, %)
|> arc(angleStart = 120, angleEnd = 60, radius = sphereDia / 2)
|> line(end = [0, chainThickness])
|> line(end = [-chainWidth, 0])
|> close()

View File

@ -46,12 +46,12 @@ export fn divider(plane) {
fn connectorSketch(plane, start) {
sketch001 = startSketchOn(plane)
|> startProfileAt(start, %)
|> polygon({
|> polygon(
radius = 1.2,
numSides = 6,
center = profileStart(%),
inscribed = false
}, %)
inscribed = false,
)
return sketch001
}
@ -107,11 +107,7 @@ fn armRestPath(plane) {
sketch005 = startSketchOn(plane)
|> startProfileAt([20, 33], %)
|> xLine(length = -20)
|> arc({
angleStart = 90,
angleEnd = 180,
radius = 10
}, %)
|> arc(angleStart = 90, angleEnd = 180, radius = 10)
return sketch005
}

View File

@ -16,10 +16,7 @@ wallThickness = 4
bottleBody = startSketchOn(XY)
|> startProfileAt([-bottleLength / 2, 0], %)
|> yLine(length = bottleWidth / 3)
|> arcTo({
end = [bottleLength / 2, bottleWidth / 3],
interior = [0, bottleWidth / 2]
}, %)
|> arc(endAbsolute = [bottleLength / 2, bottleWidth / 3], interiorAbsolute = [0, bottleWidth / 2])
|> yLine(endAbsolute = 0)
|> mirror2d(axis = X)
|> close()

View File

@ -46,11 +46,7 @@ lugHoles = startSketchOn(lugBase, face = END)
wheelCenterInner = startSketchOn(XY)
|> startProfileAt([(lugSpacing - 1.5) / 2, 0], %)
|> yLine(length = -wheelWidth / 10 - (wheelWidth / 20))
|> bezierCurve({
to = [-0.4, 0.3],
control1 = [-0.3, 0],
control2 = [0, 0.3]
}, %)
|> bezierCurve(control1 = [-0.3, 0], control2 = [0, 0.3], end = [-0.4, 0.3])
|> yLine(endAbsolute = 0)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
@ -60,11 +56,7 @@ wheelCenterInner = startSketchOn(XY)
wheelCenterOuter = startSketchOn(XY)
|> startProfileAt([(lugSpacing + 1.5) / 2, 0], %)
|> yLine(length = -wheelWidth / 10 - (wheelWidth / 20))
|> bezierCurve({
to = [0.4, -0.1],
control1 = [0.3, 0],
control2 = [0.2, -0.3]
}, %)
|> bezierCurve(control1 = [0.3, 0], control2 = [0.2, -0.3], end = [0.4, -0.1])
|> yLine(endAbsolute = -wheelWidth / 20)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
@ -84,11 +76,7 @@ fn spoke(spokeGap, spokeAngle, spokeThickness) {
// Spoke cross sections
spokeProfile = startSketchOn(plane001)
|> startProfileAt([(lugSpacing + 2) / 2, -0.7], %)
|> bezierCurve({
to = [
(wheelDiameter - lugSpacing - 2.9) / 2,
offset
],
|> bezierCurve(
control1 = [
(wheelDiameter - lugSpacing - 2.9) / 3.5,
offset / 7
@ -96,14 +84,14 @@ fn spoke(spokeGap, spokeAngle, spokeThickness) {
control2 = [
(wheelDiameter - lugSpacing - 2.9) / 4,
offset / 1.5
]
}, %)
|> yLine(length = -wheelWidth / 15)
|> bezierCurve({
to = [
-(wheelDiameter - lugSpacing - 2.9) / 2,
-offset
],
end = [
(wheelDiameter - lugSpacing - 2.9) / 2,
offset
],
)
|> yLine(length = -wheelWidth / 15)
|> bezierCurve(
control1 = [
-(wheelDiameter - lugSpacing - 2.9) / 5,
-offset / 7
@ -111,8 +99,12 @@ fn spoke(spokeGap, spokeAngle, spokeThickness) {
control2 = [
-(wheelDiameter - lugSpacing - 2.9) / 5,
-offset / 1.5
]
}, %)
],
end = [
-(wheelDiameter - lugSpacing - 2.9) / 2,
-offset
],
)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()

View File

@ -14,11 +14,7 @@ fn cycloidalGear(gearPitch, gearHeight, holeDiameter, helixAngle) {
gearPitch * 1.55 * cos(toRadians(helixAngleP)) + gearPitch * sin(toRadians(-helixAngleP)),
gearPitch * 1.55 * sin(toRadians(helixAngleP)) + gearPitch * cos(toRadians(-helixAngleP))
], %)
|> arc({
angleStart = 90 + helixAngleP,
angleEnd = -90 + helixAngleP,
radius = gearPitch
}, %)
|> arc(angleStart = 90 + helixAngleP, angleEnd = -90 + helixAngleP, radius = gearPitch)
|> tangentialArc(radius = gearPitch * 1.67, angle = 60)
|> tangentialArc(radius = gearPitch, angle = -180)
|> tangentialArc(radius = gearPitch * 1.67, angle = 60)

View File

@ -38,20 +38,20 @@ plane = {
// Create a regular pentagon inscribed in a circle of radius pentR
bottomFace = startSketchOn(XY)
|> polygon({
|> polygon(
radius = pentR,
numSides = 5,
center = [0, 0],
inscribed = true
}, %)
inscribed = true,
)
bottomSideFace = startSketchOn(plane)
|> polygon({
|> polygon(
radius = pentR,
numSides = 5,
center = [0, 0],
inscribed = true
}, %)
inscribed = true,
)
// Extrude the faces in each plane
bottom = extrude(bottomFace, length = wallThickness)

View File

@ -51,11 +51,7 @@ flipperProfile = startProfileAt([-flipperLength, -32.0], flipperSketch)
|> line(end = [flipperLength, 2.0])
|> yLine(length = 60.0, tag = $backEdge)
|> line(end = [-flipperLength, 2.0])
|> arc({
angleEnd = 196.912390,
angleStart = 163.087610,
radius = 110.0
}, %)
|> arc(angleStart = 163.087610, angleEnd = 196.912390, radius = 110.0)
|> close()
// Create a profile of the middle
@ -126,29 +122,13 @@ gripSketch = startSketchOn(handlePlane)
// Create a profile of the grip
gripProfile = startProfileAt([-26.806746, -10.0], gripSketch)
|> xLine(length = gripWidth - (2 * gripFilletRadius))
|> arc({
angleStart = -90.0,
angleEnd = 0.0,
radius = gripFilletRadius
}, %)
|> arc(angleStart = -90.0, angleEnd = 0.0, radius = gripFilletRadius)
|> yLine(length = gripHeight - (2 * gripFilletRadius))
|> arc({
angleStart = 0.0,
angleEnd = 90.0,
radius = gripFilletRadius
}, %)
|> arc(angleStart = 0.0, angleEnd = 90.0, radius = gripFilletRadius)
|> xLine(length = -(gripWidth - (2 * gripFilletRadius)))
|> arc({
angleStart = 90.0,
angleEnd = 180.0,
radius = gripFilletRadius
}, %)
|> arc(angleStart = 90.0, angleEnd = 180.0, radius = gripFilletRadius)
|> yLine(length = -(gripHeight - (2 * gripFilletRadius)), tag = $gripEdgeTop)
|> arc({
angleStart = 180.0,
angleEnd = 270.0,
radius = gripFilletRadius
}, %)
|> arc(angleStart = 180.0, angleEnd = 270.0, radius = gripFilletRadius)
|> close()
// Extrude the grip profile to create the grip

View File

@ -32,43 +32,19 @@ sketch002 = startSketchOn(plane001)
|> startProfileAt([carafeDiameter / 2, 5.7], %)
|> xLine(length = 0.1)
|> yLine(length = -5.2, tag = $edge1)
|> arc({
angleStart = 180,
angleEnd = 205,
radius = 0.3
}, %)
|> arc(angleStart = 180, angleEnd = 205, radius = 0.3)
|> angledLine(angle = -60, length = 0.6, tag = $edge2)
|> arc({
angleStart = 30,
angleEnd = -120,
radius = 0.6
}, %)
|> arc(angleStart = 30, angleEnd = -120, radius = 0.6)
|> angledLine(angle = 150, endAbsoluteY = -0.2, tag = $edge3)
|> arc({
angleStart = 60,
angleEnd = 90,
radius = 0.5
}, %)
|> arc(angleStart = 60, angleEnd = 90, radius = 0.5)
|> xLine(endAbsolute = 0.1, tag = $edgeLen)
|> yLine(length = 0.1)
|> xLine(length = segLen(edgeLen) + 0.035, tag = $edge4)
|> arc({
angleStart = 90,
angleEnd = 60,
radius = 0.6
}, %)
|> arc(angleStart = 90, angleEnd = 60, radius = 0.6)
|> angledLine(angle = 150, length = -segLen(edge3) + 0.035, tag = $edge5)
|> arc({
angleStart = -120,
angleEnd = 30,
radius = 0.5
}, %)
|> arc(angleStart = -120, angleEnd = 30, radius = 0.5)
|> angledLine(angle = -60, length = -segLen(edge2) + 0.035, tag = $edge6)
|> arc({
angleStart = 205,
angleEnd = 180,
radius = 0.6
}, %)
|> arc(angleStart = 205, angleEnd = 180, radius = 0.6)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> extrude(length = 0.75)
@ -89,11 +65,7 @@ extrude001 = extrude(sketch003, length = 0.050)
sketch004 = startSketchOn(extrude001, face = END)
|> startProfileAt([0.3, 0.17], %)
|> yLine(length = 1.2)
|> arc({
angleStart = 90,
angleEnd = -30,
radius = 1.2
}, %)
|> arc(angleStart = 90, angleEnd = -30, radius = 1.2)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> patternCircular2d(
@ -177,11 +149,7 @@ sketch011 = startSketchOn(XZ)
|> xLine(length = 0.3)
|> yLine(length = 0.4)
|> line(end = [-0.02, 0.02])
|> bezierCurve({
to = [-carafeDiameter / 2 - 0.1, 1],
control1 = [-0.3, 0],
control2 = [carafeDiameter / 10, 1]
}, %)
|> bezierCurve(control1 = [-0.3, 0], control2 = [carafeDiameter / 10, 1], end = [-carafeDiameter / 2 - 0.1, 1])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
|> revolve(axis = Y)

View File

@ -33,11 +33,11 @@ invas = map(angles, fn(a) {
// Map the involute curve
xs = map([0..cmo], fn(i) {
return rs[i] * cos(invas[i])
return rs[i] * cos(invas[i]: number(rad))
})
ys = map([0..cmo], fn(i) {
return rs[i] * sin(invas[i])
return rs[i] * sin(invas[i]: number(rad))
})
// Extrude the gear body
@ -63,11 +63,7 @@ fn rightInvolute(i, sg) {
start = startSketchOn(XY)
|> startProfileAt([xs[101], ys[101]], %)
teeth = reduce([0..100], start, leftInvolute)
|> arc({
angleStart = 0,
angleEnd = toothAngle,
radius = baseDiameter / 2
}, %)
|> arc(angleStart = 0, angleEnd = toothAngle, radius = baseDiameter / 2)
|> reduce([1..101], %, rightInvolute)
|> close()
|> extrude(length = gearHeight)
@ -95,15 +91,7 @@ keyWay = startSketchOn(body, face = END)
|> xLine(length = keywayDepth)
|> yLine(length = -keywayWidth)
|> xLine(length = -keywayDepth)
|> arc({
angleEnd = 180,
angleStart = -1 * toDegrees(startAngle) + 360,
radius = holeRadius
}, %)
|> arc({
angleEnd = toDegrees(startAngle),
angleStart = 180,
radius = holeRadius
}, %)
|> arc(angleStart = -1 * toDegrees(startAngle) + 360, angleEnd = 180, radius = holeRadius)
|> arc(angleStart = 180, angleEnd = toDegrees(startAngle), radius = holeRadius)
|> close()
|> extrude(length = -gearHeight)

View File

@ -91,35 +91,19 @@ fn magnetCenterCutout(plane) {
2 * magOuterDiam
], %)
|> xLine(length = 2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2))
|> arc({
angleStart = 90.0,
angleEnd = 0.0,
radius = magOuterDiam / 2
}, %)
|> arc(angleStart = 90.0, angleEnd = 0.0, radius = magOuterDiam / 2)
|> yLine(length = -(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2)))
|> xLine(length = binLength - (4 * magOuterDiam))
|> yLine(length = 2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2))
|> arc({
angleStart = 180.0,
angleEnd = 90.0,
radius = magOuterDiam / 2
}, %)
|> arc(angleStart = 180.0, angleEnd = 90.0, radius = magOuterDiam / 2)
|> xLine(length = 2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2))
|> yLine(length = binLength - (4 * magOuterDiam))
|> xLine(length = -(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2)))
|> arc({
angleStart = 270.0,
angleEnd = 180.0,
radius = magOuterDiam / 2
}, %)
|> arc(angleStart = 270.0, angleEnd = 180.0, radius = magOuterDiam / 2)
|> yLine(length = 2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2))
|> xLine(length = -(binLength - (4 * magOuterDiam)), tag = $line012)
|> yLine(length = -(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2)))
|> arc({
angleStart = 360.0,
angleEnd = 270.0,
radius = magOuterDiam / 2
}, %)
|> arc(angleStart = 360.0, angleEnd = 270.0, radius = magOuterDiam / 2)
|> xLine(length = -(2 * magOuterDiam - (firstStep + thirdStep) - (magOuterDiam / 2)))
|> yLine(length = -(binLength - (4 * magOuterDiam)))
|> close()

View File

@ -179,11 +179,12 @@ fn lipFace(plane) {
|> startProfileAt([0, 0], %)
// |> yLine(length = lipHeight, tag = $line100)
|> line(end = [0.0, 5.792893], tag = $line000)
|> arc({
|> arc(
angleStart = 180.0,
angleEnd = 45.0,
radius = 0.500000
}, %, $arc000)
radius = 0.500000,
tag = $arc000,
)
// |> angledLine(angle = -45, lengthY = lipStep5 )
|> line(end = [1.046447, -1.046447], tag = $line001)
|> yLine(length = -lipStep4)

View File

@ -66,11 +66,7 @@ plane001 = {
fn keyFn(originStart, keyWidth, keyHeight, repeats, color) {
sketch002 = startSketchOn(plane001)
profile002 = startProfileAt([originStart[0], originStart[1]], sketch002)
|> arc({
angleStart = 180,
angleEnd = 270,
radius = 0.1
}, %)
|> arc(angleStart = 180, angleEnd = 270, radius = 0.1)
|> angledLine(angle = 0, length = keyWidth - .2, tag = $rectangleSegmentA001)
|> tangentialArc(radius = 0.1, angle = 90)
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = keyHeight - .2, tag = $rectangleSegmentB001)
@ -167,17 +163,9 @@ fn o(origin, scale, depth) {
.788 * scale + origin[0],
.921 * scale + origin[1]
], %)
|> arc({
angleStart = 47.15 + 6,
angleEnd = 47.15 - 6 + 180,
radius = .525 * scale
}, %)
|> arc(angleStart = 47.15 + 6, angleEnd = 47.15 - 6 + 180, radius = .525 * scale)
|> angledLine(angle = 47.15, length = .24 * scale)
|> arc({
angleStart = 47.15 - 11 + 180,
angleEnd = 47.15 + 11,
radius = .288 * scale
}, %)
|> arc(angleStart = 47.15 - 11 + 180, angleEnd = 47.15 + 11, radius = .288 * scale)
|> close()
|> extrude(length = -depth)
|> appearance(color = baseColor)
@ -187,17 +175,9 @@ fn o(origin, scale, depth) {
.16 * scale + origin[0],
.079 * scale + origin[1]
], %)
|> arc({
angleStart = 47.15 + 6 - 180,
angleEnd = 47.15 - 6,
radius = .525 * scale
}, %)
|> arc(angleStart = 47.15 + 6 - 180, angleEnd = 47.15 - 6, radius = .525 * scale)
|> angledLine(angle = 47.15, length = -.24 * scale)
|> arc({
angleStart = 47.15 - 11,
angleEnd = 47.15 + 11 - 180,
radius = .288 * scale
}, %)
|> arc(angleStart = 47.15 - 11, angleEnd = 47.15 + 11 - 180, radius = .288 * scale)
|> close()
|> extrude(length = -depth)
|> appearance(color = baseColor)

View File

@ -58,18 +58,15 @@ fn mirrorFn(plane, offsetX, offsetY, altitude, radius, tiefe, gestellR, gestellD
archBody = startProfileAt([offsetX - gestellR, altitude], armPlane)
|> xLine(length = gestellD)
|> arcTo({
interior = [offsetX, altitude - gestellR],
end = [offsetX + gestellR, altitude]
}, %)
|> arc(interiorAbsolute = [offsetX, altitude - gestellR], endAbsolute = [offsetX + gestellR, altitude])
|> xLine(length = gestellD)
|> arcTo({
interior = [
|> arc(
interiorAbsolute = [
offsetX,
altitude - gestellR - gestellD
],
end = [profileStartX(%), profileStartY(%)]
}, %)
endAbsolute = [profileStartX(%), profileStartY(%)],
)
|> close()
|> extrude(length = tiefe)
return armBody

View File

@ -11,17 +11,9 @@ sketch011 = startSketchOn(plane003)
1.75 - (axisJ2ArmWidth / 2 * sin(toRadians(axisJ2))),
8 + axisJ2ArmWidth / 2 * cos(toRadians(axisJ2))
], %)
|> arc({
angleStart = 90 + axisJ2,
angleEnd = 270 + axisJ2,
radius = axisJ2ArmWidth / 2
}, %)
|> arc(angleStart = 90 + axisJ2, angleEnd = 270 + axisJ2, radius = axisJ2ArmWidth / 2)
|> angledLine(angle = axisJ2, length = axisJ2ArmLength)
|> arc({
angleStart = -90 + axisJ2,
angleEnd = 90 + axisJ2,
radius = axisJ2ArmWidth / 2
}, %)
|> arc(angleStart = -90 + axisJ2, angleEnd = 90 + axisJ2, radius = axisJ2ArmWidth / 2)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude011 = extrude(sketch011, length = -axisJ2ArmThickness)

View File

@ -11,17 +11,9 @@ sketch017 = startSketchOn(plane002)
1.75 + axisJ2ArmLength * cos(toRadians(axisJ2)) - (axisJ3CArmWidth / 2 * sin(toRadians(axisJ3C))),
8 + axisJ2ArmLength * sin(toRadians(axisJ2)) + axisJ3CArmWidth / 2 * cos(toRadians(axisJ3C))
], %)
|> arc({
angleStart = 90 + axisJ3C,
angleEnd = 270 + axisJ3C,
radius = axisJ3CArmWidth / 2
}, %)
|> arc(angleStart = 90 + axisJ3C, angleEnd = 270 + axisJ3C, radius = axisJ3CArmWidth / 2)
|> angledLine(angle = axisJ3C, length = axisJ3CArmLength)
|> arc({
angleStart = 270 + axisJ3C,
angleEnd = 90 + axisJ3C,
radius = axisJ3CArmWidth / 2
}, %)
|> arc(angleStart = 270 + axisJ3C, angleEnd = 90 + axisJ3C, radius = axisJ3CArmWidth / 2)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01)
|> close()
extrude017 = extrude(sketch017, length = axisJ3CArmThickness)
@ -97,11 +89,7 @@ sketch023 = startSketchOn(extrude022, face = START)
8 + axisJ2ArmLength * sin(toRadians(axisJ2)) + axisJ3CArmLength * sin(toRadians(axisJ3C))
], %)
|> angledLine(angle = axisJ3C + axisJ4 / 2, length = grabberLength / 4)
|> arc({
angleStart = 150 + axisJ3C + axisJ4 / 2,
angleEnd = 30 + axisJ3C + axisJ4 / 2,
radius = grabberLength / 3
}, %)
|> arc(angleStart = 150 + axisJ3C + axisJ4 / 2, angleEnd = 30 + axisJ3C + axisJ4 / 2, radius = grabberLength / 3)
|> angledLine(angle = axisJ3C + axisJ4 / 2, length = grabberLength / 6)
|> angledLine(angle = axisJ3C + axisJ4 / 2 + 132, length = grabberLength / 3.5)
|> angledLine(angle = axisJ3C + axisJ4 / 2 + 160, length = grabberLength / 3.5)
@ -118,11 +106,7 @@ sketch024 = startSketchOn(extrude022, face = START)
8 + axisJ2ArmLength * sin(toRadians(axisJ2)) + axisJ3CArmLength * sin(toRadians(axisJ3C))
], %)
|> angledLine(angle = axisJ3C - (axisJ4 / 2), length = grabberLength / 4)
|> arc({
angleStart = 210 + axisJ3C - (axisJ4 / 2),
angleEnd = 330 + axisJ3C - (axisJ4 / 2),
radius = grabberLength / 3
}, %)
|> arc(angleStart = 210 + axisJ3C - (axisJ4 / 2), angleEnd = 330 + axisJ3C - (axisJ4 / 2), radius = grabberLength / 3)
|> angledLine(angle = axisJ3C - (axisJ4 / 2), length = grabberLength / 6)
|> angledLine(angle = axisJ3C - (axisJ4 / 2) - 132, length = grabberLength / 3.5)
|> angledLine(angle = axisJ3C - (axisJ4 / 2) - 160, length = grabberLength / 3.5)

View File

@ -15,11 +15,7 @@ extrude005 = extrude(sketch005, length = 1.5 - 0.1)
sketch006 = startSketchOn(plane002)
|> startProfileAt([3.5, baseHeight], %)
|> angledLine(angle = 60, length = 1.75)
|> arc({
angleStart = -30,
angleEnd = -30 + 180,
radius = 3
}, %)
|> arc(angleStart = -30, angleEnd = -30 + 180, radius = 3)
|> angledLine(angle = 60, endAbsoluteY = baseHeight)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()

View File

@ -21,14 +21,15 @@ distanceToInsideEdge = slateWidthHalf + templateThickness + templateGap
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, depth + templateGap], %)
|> xLine(length = slateWidthHalf - radius, tag = $seg01)
|> arc({
angleEnd = 0,
|> arc(
angleStart = 90,
radius = 10 + templateGap
}, %, $seg09)
angleEnd = 0,
radius = 10 + templateGap,
tag = $seg09,
)
|> yLine(endAbsolute = -templateThickness, tag = $seg03)
|> xLine(length = templateThickness, tag = $seg07)
|> yLine(endAbsolute = (segEndY(seg01) + templateThickness) / 2 - templateThickness, tag = $seg02)
|> yLine(endAbsolute = (segEndY(seg01) + templateThickness) / 2_ - templateThickness, tag = $seg02)
|> xLine(endAbsolute = segEndX(seg03) + minClampingDistance, tag = $seg06)
|> yLine(length = templateThickness * 2, tag = $seg08)
|> xLine(endAbsolute = segEndX(seg02) + 0, tag = $seg05)
@ -42,11 +43,7 @@ sketch001 = startSketchOn(XZ)
|> yLine(length = -segLen(seg02))
|> xLine(length = segLen(seg07))
|> yLine(length = segLen(seg03))
|> arc({
angleEnd = 90,
angleStart = 180,
radius = 10 + templateGap
}, %)
|> arc(angleStart = 180, angleEnd = 90, radius = 10 + templateGap)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()

View File

@ -22,11 +22,7 @@ length002 = depth + minClampingDistance
sketch001 = startSketchOn(XZ)
|> startProfileAt([0, depth - templateGap], %)
|> xLine(length = length001, tag = $seg01)
|> arc({
angleEnd = 0,
angleStart = 90,
radius = radius - templateGap
}, %)
|> arc(angleStart = 90, angleEnd = 0, radius = radius - templateGap)
|> yLine(endAbsolute = -templateGap * 2 - (templateDiameter / 2), tag = $seg05)
|> xLine(endAbsolute = slateWidthHalf + templateThickness, tag = $seg04)
|> yLine(length = -length002, tag = $seg03)
@ -36,11 +32,7 @@ sketch001 = startSketchOn(XZ)
|> yLine(length = segLen(seg03))
|> xLine(length = segLen(seg04))
|> yLine(length = segLen(seg05))
|> arc({
angleEnd = 90,
angleStart = 180,
radius = radius - templateGap
}, %)
|> arc(angleStart = 180, angleEnd = 90, radius = radius - templateGap)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()

View File

@ -12,11 +12,7 @@ startSketchOn(XZ)
|> startProfileAt([0.0001, 0], %)
|> xLine(length = knobDiameter / 2)
|> yLine(length = knobHeight - 0.05)
|> arc({
angleStart = 0,
angleEnd = 90,
radius = .05
}, %)
|> arc(angleStart = 0, angleEnd = 90, radius = .05)
|> xLine(endAbsolute = 0.0001)
|> close()
|> revolve(axis = Y)

View File

@ -33,17 +33,9 @@ export fn oLogo(surface, origin, scale) {
.788 * scale + origin[0],
.921 * scale + origin[1]
], %)
|> arc({
angleStart = 47.15 + 6,
angleEnd = 47.15 - 6 + 180,
radius = .525 * scale
}, %)
|> arc(angleStart = 47.15 + 6, angleEnd = 47.15 - 6 + 180, radius = .525 * scale)
|> angledLine(angle = 47.15, length = .24 * scale)
|> arc({
angleStart = 47.15 - 11 + 180,
angleEnd = 47.15 + 11,
radius = .288 * scale
}, %)
|> arc(angleStart = 47.15 - 11 + 180, angleEnd = 47.15 + 11, radius = .288 * scale)
|> close()
return oSketch001
}
@ -54,17 +46,9 @@ export fn oLogo2(surface, origin, scale) {
.16 * scale + origin[0],
.079 * scale + origin[1]
], %)
|> arc({
angleStart = 47.15 + 6 - 180,
angleEnd = 47.15 - 6,
radius = .525 * scale
}, %)
|> arc(angleStart = 47.15 + 6 - 180, angleEnd = 47.15 - 6, radius = .525 * scale)
|> angledLine(angle = 47.15, length = -.24 * scale)
|> arc({
angleStart = 47.15 - 11,
angleEnd = 47.15 + 11 - 180,
radius = .288 * scale
}, %)
|> arc(angleStart = 47.15 - 11, angleEnd = 47.15 + 11 - 180, radius = .288 * scale)
|> close()
return oSketch002
}

View File

@ -116,7 +116,7 @@
"@tsconfig/strictest": "^2.0.5",
"@types/glob": "^8.1.0",
"@types/mocha": "^10.0.10",
"@types/node": "^22.13.10",
"@types/node": "^22.14.1",
"@types/vscode": "^1.97.0",
"@typescript-eslint/eslint-plugin": "^8.27.0",
"@typescript-eslint/parser": "^8.27.0",

View File

@ -4,6 +4,6 @@ const height = 3
const body = startSketchOn(XY)
|> startProfileAt([center[0]+radius, center[1]], %)
|> arc({angleEnd: 360, angleStart: 0, radius}, %)
|> arc(angleEnd = 360, angleStart = 0, radius = radius)
|> close()
|> extrude(length = height)

View File

@ -5,7 +5,7 @@ const t = 0.005 // taper factor [0-1)
// Defines how to modify each layer of the vase.
// Each replica is shifted up the Z axis, and has a smoothly-varying radius
fn transform = (replicaId) => {
let scale = r * abs(1 - (t * replicaId)) * (5 + cos(replicaId / 8))
let scale = r * abs(1 - (t * replicaId)) * (5 + cos((replicaId / 8): number(rad)))
return {
translate: [0, 0, replicaId * 10],
scale: [scale, scale, 0],

View File

@ -1,7 +1,6 @@
let triangleHeight = 200
let plumbusLen = 100
let radius = 80
let circ = {angle_start: 0, angle_end: 360, radius: radius}
let triangleLen = 500
const p = startSketchOn(XY)
@ -14,7 +13,12 @@ const p = startSketchOn(XY)
fn circl = (x, face) => {
return startSketchOn(p, face = face)
|> startProfileAt([x + radius, triangleHeight/2], %)
|> arc(circ, %, $arc_tag)
|> arc(
angleStart = 0,
angleEnd = 360,
radius = radius,
tag = $arc_tag,
)
|> close()
}

View File

@ -3,108 +3,108 @@ const svg = startSketchOn(XY)
|> line(endAbsolute = [22.687663, -2.7664351]) // MoveRelative
|> line(endAbsolute = [15.687664000000002, -5.7664351]) // MoveRelative
|> bezierCurve({ control1: [9.6876636, -13.766435], control2: [12.350729000000001, -9.156355099999999], to: [12.350729000000001, -9.156355099999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [3.6876636000000005, -32.766435], control2: [6.962245000000001, -20.186315], to: [4.8344949, -25.885455]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [5.0392261000000005, -58.571125], control2: [2.9675173000000004, -41.612785], to: [3.0190312000000006, -49.894795]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [10.687664000000002, -73.766435], control2: [6.693877800000001, -63.826655], to: [8.2887432, -68.804835]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [20.375163, -80.578935], control2: [16.045534000000004, -78.630635], to: [16.045534000000004, -78.630635]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [30.062663, -82.266435], control2: [24.812782, -81.936245], to: [24.812782, -81.936245]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [41.125163, -79.516435], control2: [35.794902, -82.039475], to: [35.794902, -82.039475]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [49.687663, -72.766435], control2: [45.867323, -76.907555], to: [45.867323, -76.907555]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [9.6876636, -13.766435], control2 = [12.350729000000001, -9.156355099999999], end = [12.350729000000001, -9.156355099999999]) // CubicBezierRelative
|> bezierCurve(control1 = [3.6876636000000005, -32.766435], control2 = [6.962245000000001, -20.186315], end = [4.8344949, -25.885455]) // CubicBezierRelative
|> bezierCurve(control1 = [5.0392261000000005, -58.571125], control2 = [2.9675173000000004, -41.612785], end = [3.0190312000000006, -49.894795]) // CubicBezierRelative
|> bezierCurve(control1 = [10.687664000000002, -73.766435], control2 = [6.693877800000001, -63.826655], end = [8.2887432, -68.804835]) // CubicBezierRelative
|> bezierCurve(control1 = [20.375163, -80.578935], control2 = [16.045534000000004, -78.630635], end = [16.045534000000004, -78.630635]) // CubicBezierRelative
|> bezierCurve(control1 = [30.062663, -82.266435], control2 = [24.812782, -81.936245], end = [24.812782, -81.936245]) // CubicBezierRelative
|> bezierCurve(control1 = [41.125163, -79.516435], control2 = [35.794902, -82.039475], end = [35.794902, -82.039475]) // CubicBezierRelative
|> bezierCurve(control1 = [49.687663, -72.766435], control2 = [45.867323, -76.907555], end = [45.867323, -76.907555]) // CubicBezierRelative
|> line(endAbsolute = [50.687663, -69.766435]) // LineRelative
|> line(endAbsolute = [50.687663, -62.766435]) // VerticalLineHorizonal
|> line(endAbsolute = [48.687663, -57.891435]) // LineRelative
|> bezierCurve({ control1: [46.351725, -31.692225], control2: [46.191183, -48.997725], to: [46.295503000000004, -40.884555000000006]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [47.7736, -20.934404999999998], control2: [46.687663, -25.766435], to: [46.687663, -25.766435]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [46.351725, -31.692225], control2 = [46.191183, -48.997725], end = [46.295503000000004, -40.884555000000006]) // CubicBezierRelative
|> bezierCurve(control1 = [47.7736, -20.934404999999998], control2 = [46.687663, -25.766435], end = [46.687663, -25.766435]) // CubicBezierRelative
|> line(endAbsolute = [48.687663, -16.766434999999998]) // LineRelative
|> line(endAbsolute = [47.687663, -9.766435099999999]) // LineRelative
|> bezierCurve({ control1: [40.687663, -3.766435099999999], control2: [44.488820000000004, -6.310115099999999], to: [44.488820000000004, -6.310115099999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [22.687663, -2.766435099999999], control2: [34.632213, -2.2525750999999987], to: [28.903189, -2.550245099999999]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [40.687663, -3.766435099999999], control2 = [44.488820000000004, -6.310115099999999], end = [44.488820000000004, -6.310115099999999]) // CubicBezierRelative
|> bezierCurve(control1 = [22.687663, -2.766435099999999], control2 = [34.632213, -2.2525750999999987], end = [28.903189, -2.550245099999999]) // CubicBezierRelative
// StopRelative
|> line(endAbsolute = [116.68767, -9.766435099999999]) // MoveRelative
|> bezierCurve({ control1: [108.68767, -15.766434999999998], control2: [112.22719, -12.236704999999999], to: [112.22719, -12.236704999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [102.37517, -28.953934999999998], control2: [105.79825, -20.100575], to: [103.93048, -23.991764999999997]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [101.68767, -47.766435], control2: [101.45837999999999, -35.371444999999994], to: [101.28287, -41.289805]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [110.31267, -61.203935], control2: [103.94304, -53.097335], to: [106.65406999999999, -56.725305]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [116.68767, -66.766435], control2: [113.42043, -64.74899500000001], to: [113.42043, -64.74899500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [134.68767, -64.766435], control2: [123.4012, -67.124495], to: [128.03363, -66.429955]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [143.68767, -60.766435], control2: [139.37985, -63.042205], to: [139.37985, -63.042205]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [108.68767, -15.766434999999998], control2 = [112.22719, -12.236704999999999], end = [112.22719, -12.236704999999999]) // CubicBezierRelative
|> bezierCurve(control1 = [102.37517, -28.953934999999998], control2 = [105.79825, -20.100575], end = [103.93048, -23.991764999999997]) // CubicBezierRelative
|> bezierCurve(control1 = [101.68767, -47.766435], control2 = [101.45837999999999, -35.371444999999994], end = [101.28287, -41.289805]) // CubicBezierRelative
|> bezierCurve(control1 = [110.31267, -61.203935], control2 = [103.94304, -53.097335], end = [106.65406999999999, -56.725305]) // CubicBezierRelative
|> bezierCurve(control1 = [116.68767, -66.766435], control2 = [113.42043, -64.74899500000001], end = [113.42043, -64.74899500000001]) // CubicBezierRelative
|> bezierCurve(control1 = [134.68767, -64.766435], control2 = [123.4012, -67.124495], end = [128.03363, -66.429955]) // CubicBezierRelative
|> bezierCurve(control1 = [143.68767, -60.766435], control2 = [139.37985, -63.042205], end = [139.37985, -63.042205]) // CubicBezierRelative
|> line(endAbsolute = [148.68767, -55.766435]) // LineRelative
|> line(endAbsolute = [149.68767, -54.766435]) // LineRelative
|> bezierCurve({ control1: [149.75017, -46.078935], control2: [149.71427, -51.870655], to: [149.73387, -48.974805]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [150.68767, -36.766435], control2: [149.97673, -41.121905], to: [149.97673, -41.121905]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [158.68767, -30.766435], control2: [154.62517, -32.891435], to: [154.62517, -32.891435]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [149.75017, -46.078935], control2 = [149.71427, -51.870655], end = [149.73387, -48.974805]) // CubicBezierRelative
|> bezierCurve(control1 = [150.68767, -36.766435], control2 = [149.97673, -41.121905], end = [149.97673, -41.121905]) // CubicBezierRelative
|> bezierCurve(control1 = [158.68767, -30.766435], control2 = [154.62517, -32.891435], end = [154.62517, -32.891435]) // CubicBezierRelative
|> line(endAbsolute = [160.68767, -26.766435]) // LineRelative
|> line(endAbsolute = [160.68767, -20.766435]) // VerticalLineHorizonal
|> bezierCurve({ control1: [149.68767, -9.8289351], control2: [157.40521999999999, -16.321455], to: [154.13992, -13.098555000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [145.68767, -7.766435100000001], control2: [148.36767, -9.148315100000001], to: [147.04767, -8.4676851]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [116.68767, -9.7664351], control2: [135.27527, -6.278955100000001], to: [126.6914, -6.2357151]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [149.68767, -9.8289351], control2 = [157.40521999999999, -16.321455], end = [154.13992, -13.098555000000001]) // CubicBezierRelative
|> bezierCurve(control1 = [145.68767, -7.766435100000001], control2 = [148.36767, -9.148315100000001], end = [147.04767, -8.4676851]) // CubicBezierRelative
|> bezierCurve(control1 = [116.68767, -9.7664351], control2 = [135.27527, -6.278955100000001], end = [126.6914, -6.2357151]) // CubicBezierRelative
// StopRelative
|> line(endAbsolute = [60.687663, -9.7664351]) // MoveRelative
|> line(endAbsolute = [54.687663, -13.766435000000001]) // MoveRelative
|> bezierCurve({ control1: [48.937663, -25.516435], control2: [50.481933, -19.450155000000002], to: [50.481933, -19.450155000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [47.687663, -41.766435], control2: [47.773086, -31.339325000000002], to: [47.261382, -35.869545]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [50.687663, -56.766435], control2: [48.8286, -49.471785000000004], to: [48.8286, -49.471785000000004]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [48.937663, -25.516435], control2 = [50.481933, -19.450155000000002], end = [50.481933, -19.450155000000002]) // CubicBezierRelative
|> bezierCurve(control1 = [47.687663, -41.766435], control2 = [47.773086, -31.339325000000002], end = [47.261382, -35.869545]) // CubicBezierRelative
|> bezierCurve(control1 = [50.687663, -56.766435], control2 = [48.8286, -49.471785000000004], end = [48.8286, -49.471785000000004]) // CubicBezierRelative
|> line(endAbsolute = [54.687663, -62.766435]) // LineRelative
|> line(endAbsolute = [60.687663, -66.766435]) // LineRelative
|> bezierCurve({ control1: [69.562663, -67.203935], control2: [64.985029, -67.361225], to: [64.985029, -67.361225]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [74.17985, -67.199935], control2: [71.84817100000001, -67.201935], to: [71.84817100000001, -67.201935]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [86.687663, -63.766335], control2: [78.823333, -66.75328499999999], to: [82.418032, -65.599655]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [69.562663, -67.203935], control2 = [64.985029, -67.361225], end = [64.985029, -67.361225]) // CubicBezierRelative
|> bezierCurve(control1 = [74.17985, -67.199935], control2 = [71.84817100000001, -67.201935], end = [71.84817100000001, -67.201935]) // CubicBezierRelative
|> bezierCurve(control1 = [86.687663, -63.766335], control2 = [78.823333, -66.75328499999999], end = [82.418032, -65.599655]) // CubicBezierRelative
|> line(endAbsolute = [86.687663, -61.766335]) // VerticalLineHorizonal
|> line(endAbsolute = [90.687663, -60.766335]) // LineRelative
|> line(endAbsolute = [95.687663, -56.766335]) // LineRelative
|> line(endAbsolute = [98.687663, -49.766335]) // LineRelative
|> bezierCurve({ control1: [97.562663, -37.578835], control2: [98.934927, -43.021825], to: [98.934927, -43.021825]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [95.687663, -32.766335], control2: [96.943913, -35.990714999999994], to: [96.325163, -34.402584999999995]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [86.687663, -27.766334999999998], control2: [90.389309, -28.854045], to: [90.389309, -28.854045]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [97.562663, -37.578835], control2 = [98.934927, -43.021825], end = [98.934927, -43.021825]) // CubicBezierRelative
|> bezierCurve(control1 = [95.687663, -32.766335], control2 = [96.943913, -35.990714999999994], end = [96.325163, -34.402584999999995]) // CubicBezierRelative
|> bezierCurve(control1 = [86.687663, -27.766334999999998], control2 = [90.389309, -28.854045], end = [90.389309, -28.854045]) // CubicBezierRelative
|> line(endAbsolute = [84.687663, -23.766334999999998]) // LineRelative
|> line(endAbsolute = [82.687663, -22.766334999999998]) // LineRelative
|> line(endAbsolute = [79.687663, -17.766334999999998]) // LineRelative
|> line(endAbsolute = [77.687663, -17.766334999999998]) // HorizontalLineRelative
|> line(endAbsolute = [75.687663, -13.766334999999998]) // LineRelative
|> bezierCurve({ control1: [67.687663, -9.766335099999997], control2: [72.005138, -11.383034999999998], to: [72.005138, -11.383034999999998]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [67.687663, -9.766335099999997], control2 = [72.005138, -11.383034999999998], end = [72.005138, -11.383034999999998]) // CubicBezierRelative
|> line(endAbsolute = [60.687663, -9.766335099999997]) // HorizontalLineRelative
// StopRelative
|> line(endAbsolute = [295.68767, -33.766435]) // MoveAbsolute
|> bezierCurve({ control1: [286.31267, -36.578935], control2: [292.56461, -34.710375], to: [289.43947000000003, -35.647445000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [242.00408000000002, -50.172685], control2: [271.51088000000004, -41.004795], to: [256.74729, -45.555595000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [234.31267000000003, -52.578935], control2: [239.46591, -50.966755], to: [236.92775, -51.760815]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [227.28923000000003, -54.785975], control2: [231.99494, -53.307255], to: [229.67720000000003, -54.035585000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [208.68767000000003, -59.766435], control2: [221.12295000000003, -56.635855], to: [214.94597000000005, -58.261215]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [286.31267, -36.578935], control2 = [292.56461, -34.710375], end = [289.43947000000003, -35.647445000000005]) // CubicBezierRelative
|> bezierCurve(control1 = [242.00408000000002, -50.172685], control2 = [271.51088000000004, -41.004795], end = [256.74729, -45.555595000000004]) // CubicBezierRelative
|> bezierCurve(control1 = [234.31267000000003, -52.578935], control2 = [239.46591, -50.966755], end = [236.92775, -51.760815]) // CubicBezierRelative
|> bezierCurve(control1 = [227.28923000000003, -54.785975], control2 = [231.99494, -53.307255], end = [229.67720000000003, -54.035585000000005]) // CubicBezierRelative
|> bezierCurve(control1 = [208.68767000000003, -59.766435], control2 = [221.12295000000003, -56.635855], end = [214.94597000000005, -58.261215]) // CubicBezierRelative
|> line(endAbsolute = [208.68767000000003, -57.766435]) // VerticalLineHorizonal
|> line(endAbsolute = [212.68767000000003, -55.766435]) // LineRelative
|> bezierCurve({ control1: [217.68767000000003, -48.766435], control2: [215.57281000000003, -52.830805], to: [215.57281000000003, -52.830805]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [218.68767000000003, -37.766435], control2: [218.84802000000002, -43.253935], to: [218.84802000000002, -43.253935]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [217.68767000000003, -48.766435], control2 = [215.57281000000003, -52.830805], end = [215.57281000000003, -52.830805]) // CubicBezierRelative
|> bezierCurve(control1 = [218.68767000000003, -37.766435], control2 = [218.84802000000002, -43.253935], end = [218.84802000000002, -43.253935]) // CubicBezierRelative
|> line(endAbsolute = [215.68767000000003, -31.766435]) // LineRelative
|> bezierCurve({ control1: [208.68767000000003, -26.766435], control2: [212.58234000000002, -28.940575000000003], to: [212.58234000000002, -28.940575000000003]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [192.68767000000003, -22.766435], control2: [203.18777000000003, -24.627585], to: [198.58520000000001, -23.608945000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [174.68767000000003, -24.766435], control2: [186.30665000000002, -22.492965], to: [180.86041000000003, -23.137525]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [170.12517000000003, -25.953935], control2: [173.18205000000003, -25.158315], to: [171.67642000000004, -25.550185000000003]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [161.43767000000003, -31.016435], control2: [165.49678000000003, -27.618325000000002], to: [165.49678000000003, -27.618325000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [152.68767000000003, -41.766435], control2: [157.93412000000004, -34.519995], to: [155.07957000000002, -37.431115]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [152.68767000000003, -50.766435], control2: [151.93767000000003, -46.266435], to: [151.93767000000003, -46.266435]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [160.43767000000003, -61.578935], control2: [156.18761000000003, -57.582325], to: [156.18761000000003, -57.582325]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [164.68767000000003, -64.766435], control2: [162.54142000000002, -63.156755000000004], to: [162.54142000000002, -63.156755000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [180.68767000000003, -67.766435], control2: [172.62751000000003, -66.921865], to: [172.62751000000003, -66.921865]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [158.81267000000003, -75.266435], control2: [173.47790000000003, -70.856345], to: [166.33463000000003, -73.047575]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [138.52752000000004, -81.543785], control2: [148.62236000000001, -78.25548500000001], to: [148.62236000000001, -78.25548500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [130.12517000000003, -82.828935], control2: [134.68767000000003, -82.766435], to: [134.68767000000003, -82.766435]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [125.68767000000003, -81.766435], control2: [128.66080000000002, -82.478315], to: [127.19642000000003, -82.127685]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [117.68767000000003, -75.766435], control2: [122.99559000000002, -79.800785], to: [120.32975000000002, -77.798805]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [107.68767000000003, -72.766435], control2: [113.16586000000002, -73.682455], to: [113.16586000000002, -73.682455]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [84.93766300000003, -73.953935], control2: [99.87842800000003, -72.226315], to: [92.61523300000002, -72.36835500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [80.68766300000003, -75.766435], control2: [83.53516300000003, -74.552065], to: [82.13266300000002, -75.15018500000001]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [208.68767000000003, -26.766435], control2 = [212.58234000000002, -28.940575000000003], end = [212.58234000000002, -28.940575000000003]) // CubicBezierRelative
|> bezierCurve(control1 = [192.68767000000003, -22.766435], control2 = [203.18777000000003, -24.627585], end = [198.58520000000001, -23.608945000000002]) // CubicBezierRelative
|> bezierCurve(control1 = [174.68767000000003, -24.766435], control2 = [186.30665000000002, -22.492965], end = [180.86041000000003, -23.137525]) // CubicBezierRelative
|> bezierCurve(control1 = [170.12517000000003, -25.953935], control2 = [173.18205000000003, -25.158315], end = [171.67642000000004, -25.550185000000003]) // CubicBezierRelative
|> bezierCurve(control1 = [161.43767000000003, -31.016435], control2 = [165.49678000000003, -27.618325000000002], end = [165.49678000000003, -27.618325000000002]) // CubicBezierRelative
|> bezierCurve(control1 = [152.68767000000003, -41.766435], control2 = [157.93412000000004, -34.519995], end = [155.07957000000002, -37.431115]) // CubicBezierRelative
|> bezierCurve(control1 = [152.68767000000003, -50.766435], control2 = [151.93767000000003, -46.266435], end = [151.93767000000003, -46.266435]) // CubicBezierRelative
|> bezierCurve(control1 = [160.43767000000003, -61.578935], control2 = [156.18761000000003, -57.582325], end = [156.18761000000003, -57.582325]) // CubicBezierRelative
|> bezierCurve(control1 = [164.68767000000003, -64.766435], control2 = [162.54142000000002, -63.156755000000004], end = [162.54142000000002, -63.156755000000004]) // CubicBezierRelative
|> bezierCurve(control1 = [180.68767000000003, -67.766435], control2 = [172.62751000000003, -66.921865], end = [172.62751000000003, -66.921865]) // CubicBezierRelative
|> bezierCurve(control1 = [158.81267000000003, -75.266435], control2 = [173.47790000000003, -70.856345], end = [166.33463000000003, -73.047575]) // CubicBezierRelative
|> bezierCurve(control1 = [138.52752000000004, -81.543785], control2 = [148.62236000000001, -78.25548500000001], end = [148.62236000000001, -78.25548500000001]) // CubicBezierRelative
|> bezierCurve(control1 = [130.12517000000003, -82.828935], control2 = [134.68767000000003, -82.766435], end = [134.68767000000003, -82.766435]) // CubicBezierRelative
|> bezierCurve(control1 = [125.68767000000003, -81.766435], control2 = [128.66080000000002, -82.478315], end = [127.19642000000003, -82.127685]) // CubicBezierRelative
|> bezierCurve(control1 = [117.68767000000003, -75.766435], control2 = [122.99559000000002, -79.800785], end = [120.32975000000002, -77.798805]) // CubicBezierRelative
|> bezierCurve(control1 = [107.68767000000003, -72.766435], control2 = [113.16586000000002, -73.682455], end = [113.16586000000002, -73.682455]) // CubicBezierRelative
|> bezierCurve(control1 = [84.93766300000003, -73.953935], control2 = [99.87842800000003, -72.226315], end = [92.61523300000002, -72.36835500000001]) // CubicBezierRelative
|> bezierCurve(control1 = [80.68766300000003, -75.766435], control2 = [83.53516300000003, -74.552065], end = [82.13266300000002, -75.15018500000001]) // CubicBezierRelative
|> line(endAbsolute = [75.68766300000003, -80.766435]) // LineRelative
|> line(endAbsolute = [76.68766300000003, -84.766435]) // LineRelative
|> line(endAbsolute = [81.68766300000003, -87.766435]) // LineRelative
|> bezierCurve({ control1: [93.93766300000003, -87.891435], control2: [85.76704300000003, -87.950845], to: [89.85495700000003, -87.974265]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [105.68767000000003, -87.766435], control2: [97.85393000000003, -87.821635], to: [101.77078000000003, -87.772355]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [93.93766300000003, -87.891435], control2 = [85.76704300000003, -87.950845], end = [89.85495700000003, -87.974265]) // CubicBezierRelative
|> bezierCurve(control1 = [105.68767000000003, -87.766435], control2 = [97.85393000000003, -87.821635], end = [101.77078000000003, -87.772355]) // CubicBezierRelative
|> line(endAbsolute = [106.68767000000003, -88.766435]) // LineRelative
|> line(endAbsolute = [99.68766300000003, -90.766435]) // LineRelative
|> line(endAbsolute = [95.75016300000003, -93.266435]) // LineRelative
|> bezierCurve({ control1: [83.68766300000003, -97.766435], control2: [91.68766300000003, -95.766435], to: [91.68766300000003, -95.766435]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [68.68766300000003, -102.76643], control2: [78.56377900000003, -99.248045], to: [73.64162800000003, -100.78485]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [52.68766300000003, -101.76643], control2: [63.09091200000003, -102.95723], to: [58.18407400000003, -102.86573]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [83.68766300000003, -97.766435], control2 = [91.68766300000003, -95.766435], end = [91.68766300000003, -95.766435]) // CubicBezierRelative
|> bezierCurve(control1 = [68.68766300000003, -102.76643], control2 = [78.56377900000003, -99.248045], end = [73.64162800000003, -100.78485]) // CubicBezierRelative
|> bezierCurve(control1 = [52.68766300000003, -101.76643], control2 = [63.09091200000003, -102.95723], end = [58.18407400000003, -102.86573]) // CubicBezierRelative
|> line(endAbsolute = [48.68766300000003, -106.76643]) // LineRelative
|> line(endAbsolute = [48.68766300000003, -114.76643]) // VerticalLineHorizonal
|> line(endAbsolute = [51.68766300000003, -121.76643]) // LineRelative
@ -119,91 +119,91 @@ const svg = startSketchOn(XY)
|> line(endAbsolute = [85.68766300000003, -109.76643]) // LineRelative
|> line(endAbsolute = [88.68766300000003, -106.76643]) // LineRelative
|> line(endAbsolute = [88.68766300000003, -102.76643]) // VerticalLineHorizonal
|> bezierCurve({ control1: [99.68766300000003, -101.76643], control2: [93.93766300000003, -102.01643], to: [93.93766300000003, -102.01643]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [99.68766300000003, -101.76643], control2 = [93.93766300000003, -102.01643], end = [93.93766300000003, -102.01643]) // CubicBezierRelative
|> line(endAbsolute = [103.68767000000003, -105.76643]) // LineRelative
|> line(endAbsolute = [106.68767000000003, -106.76643]) // LineRelative
|> bezierCurve({ control1: [107.68767000000003, -102.76643], control2: [107.18267000000003, -104.78643], to: [107.18267000000003, -104.78643]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [107.68767000000003, -102.76643], control2 = [107.18267000000003, -104.78643], end = [107.18267000000003, -104.78643]) // CubicBezierRelative
|> line(endAbsolute = [116.68767000000003, -102.76643]) // HorizontalLineRelative
|> line(endAbsolute = [113.68767000000003, -108.76643]) // LineRelative
|> bezierCurve({ control1: [101.68767000000003, -114.76643], control2: [109.73020000000002, -110.84932], to: [105.72846000000003, -112.85018]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [101.68767000000003, -114.76643], control2 = [109.73020000000002, -110.84932], end = [105.72846000000003, -112.85018]) // CubicBezierRelative
|> line(endAbsolute = [97.68766300000003, -118.76643]) // LineRelative
|> line(endAbsolute = [97.68766300000003, -125.76643]) // VerticalLineHorizonal
|> line(endAbsolute = [101.68767000000003, -128.76643]) // LineRelative
|> bezierCurve({ control1: [115.75017000000003, -126.57893000000001], control2: [106.58566000000002, -128.61801000000003], to: [110.98125000000003, -127.69757000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [124.93767000000003, -122.01643000000001], control2: [120.74370000000002, -124.95192000000002], to: [120.74370000000002, -124.95192000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [134.68767000000003, -111.76643000000001], control2: [128.66063000000003, -118.78987000000001], to: [131.76465000000002, -115.73339000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [136.68767000000003, -96.76643500000002], control2: [137.05397000000002, -104.69775000000001], to: [137.05397000000002, -104.69775000000001]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [115.75017000000003, -126.57893000000001], control2 = [106.58566000000002, -128.61801000000003], end = [110.98125000000003, -127.69757000000001]) // CubicBezierRelative
|> bezierCurve(control1 = [124.93767000000003, -122.01643000000001], control2 = [120.74370000000002, -124.95192000000002], end = [120.74370000000002, -124.95192000000002]) // CubicBezierRelative
|> bezierCurve(control1 = [134.68767000000003, -111.76643000000001], control2 = [128.66063000000003, -118.78987000000001], end = [131.76465000000002, -115.73339000000001]) // CubicBezierRelative
|> bezierCurve(control1 = [136.68767000000003, -96.76643500000002], control2 = [137.05397000000002, -104.69775000000001], end = [137.05397000000002, -104.69775000000001]) // CubicBezierRelative
|> line(endAbsolute = [135.68767000000003, -95.76643500000002]) // LineRelative
|> line(endAbsolute = [144.68767000000003, -91.76643500000002]) // LineRelative
|> line(endAbsolute = [144.68767000000003, -89.76643500000002]) // VerticalLineHorizonal
|> bezierCurve({ control1: [149.18767000000003, -88.95393500000002], control2: [146.91517000000002, -89.36425500000001], to: [146.91517000000002, -89.36425500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [158.81267000000003, -86.20393500000002], control2: [154.52930000000003, -87.94347500000002], to: [154.52930000000003, -87.94347500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [170.68767000000003, -83.76643500000002], control2: [162.68767000000003, -84.76643500000002], to: [162.68767000000003, -84.76643500000002]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [149.18767000000003, -88.95393500000002], control2 = [146.91517000000002, -89.36425500000001], end = [146.91517000000002, -89.36425500000001]) // CubicBezierRelative
|> bezierCurve(control1 = [158.81267000000003, -86.20393500000002], control2 = [154.52930000000003, -87.94347500000002], end = [154.52930000000003, -87.94347500000002]) // CubicBezierRelative
|> bezierCurve(control1 = [170.68767000000003, -83.76643500000002], control2 = [162.68767000000003, -84.76643500000002], end = [162.68767000000003, -84.76643500000002]) // CubicBezierRelative
|> line(endAbsolute = [169.68767000000003, -87.76643500000002]) // LineRelative
|> bezierCurve({ control1: [173.81267000000003, -124.20393000000001], control2: [169.31325000000004, -100.37193000000002], to: [170.34211000000002, -112.05696000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [175.68767000000003, -129.76643], control2: [174.43142000000003, -126.03956000000001], to: [175.05017000000004, -127.87518000000001]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [173.81267000000003, -124.20393000000001], control2 = [169.31325000000004, -100.37193000000002], end = [170.34211000000002, -112.05696000000002]) // CubicBezierRelative
|> bezierCurve(control1 = [175.68767000000003, -129.76643], control2 = [174.43142000000003, -126.03956000000001], end = [175.05017000000004, -127.87518000000001]) // CubicBezierRelative
|> line(endAbsolute = [177.68767000000003, -129.76643]) // HorizontalLineRelative
|> line(endAbsolute = [179.68767000000003, -133.76643]) // LineRelative
|> line(endAbsolute = [185.68767000000003, -138.76643]) // LineRelative
|> bezierCurve({ control1: [202.68767000000003, -139.76643], control2: [191.47452, -140.21315], to: [196.74116000000004, -140.04174]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [210.68767000000003, -135.76643], control2: [207.25921000000002, -138.23436], to: [207.25921000000002, -138.23436]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [215.35564000000002, -128.27815], control2: [213.71484000000004, -132.0027], to: [213.71484000000004, -132.0027]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [216.91033000000002, -104.88753000000001], control2: [217.63118000000003, -120.57069000000001], to: [217.01741, -112.86275]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [214.68767000000003, -85.76643500000002], control2: [216.67209000000003, -98.33796500000001], to: [216.17402, -92.15775500000001]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [202.68767000000003, -139.76643], control2 = [191.47452, -140.21315], end = [196.74116000000004, -140.04174]) // CubicBezierRelative
|> bezierCurve(control1 = [210.68767000000003, -135.76643], control2 = [207.25921000000002, -138.23436], end = [207.25921000000002, -138.23436]) // CubicBezierRelative
|> bezierCurve(control1 = [215.35564000000002, -128.27815], control2 = [213.71484000000004, -132.0027], end = [213.71484000000004, -132.0027]) // CubicBezierRelative
|> bezierCurve(control1 = [216.91033000000002, -104.88753000000001], control2 = [217.63118000000003, -120.57069000000001], end = [217.01741, -112.86275]) // CubicBezierRelative
|> bezierCurve(control1 = [214.68767000000003, -85.76643500000002], control2 = [216.67209000000003, -98.33796500000001], end = [216.17402, -92.15775500000001]) // CubicBezierRelative
|> line(endAbsolute = [210.68767000000003, -78.76643500000002]) // LineRelative
|> line(endAbsolute = [207.68767000000003, -78.76643500000002]) // HorizontalLineRelative
|> line(endAbsolute = [207.68767000000003, -75.76643500000002]) // VerticalLineHorizonal
|> line(endAbsolute = [203.68767000000003, -74.76643500000002]) // LineRelative
|> line(endAbsolute = [204.68767000000003, -70.76643500000002]) // LineRelative
|> line(endAbsolute = [209.50017000000003, -70.01643500000002]) // LineRelative
|> bezierCurve({ control1: [226.68767000000003, -64.76643500000002], control2: [215.57464000000002, -68.78927500000002], to: [220.89892000000003, -66.95330500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [247.31267000000003, -58.578935000000016], control2: [233.53624000000002, -62.60005500000001], to: [240.40800000000002, -60.55978500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [277.21111, -48.92659500000001], control2: [257.37096, -55.63882500000002], to: [267.2794, -52.26503500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [299.68767, -41.766435000000016], control2: [284.67443000000003, -46.437325000000016], to: [292.16675000000004, -44.07484500000001]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [226.68767000000003, -64.76643500000002], control2 = [215.57464000000002, -68.78927500000002], end = [220.89892000000003, -66.95330500000001]) // CubicBezierRelative
|> bezierCurve(control1 = [247.31267000000003, -58.578935000000016], control2 = [233.53624000000002, -62.60005500000001], end = [240.40800000000002, -60.55978500000002]) // CubicBezierRelative
|> bezierCurve(control1 = [277.21111, -48.92659500000001], control2 = [257.37096, -55.63882500000002], end = [267.2794, -52.26503500000001]) // CubicBezierRelative
|> bezierCurve(control1 = [299.68767, -41.766435000000016], control2 = [284.67443000000003, -46.437325000000016], end = [292.16675000000004, -44.07484500000001]) // CubicBezierRelative
|> line(endAbsolute = [299.68767, -39.766435000000016]) // VerticalLineHorizonal
|> bezierCurve({ control1: [306.50017, -39.328935000000016], control2: [301.93580000000003, -39.62206500000001], to: [304.18392, -39.477685000000015]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [316.68767, -37.766435000000016], control2: [313.07319, -39.10529500000001], to: [313.07319, -39.10529500000001]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [306.50017, -39.328935000000016], control2 = [301.93580000000003, -39.62206500000001], end = [304.18392, -39.477685000000015]) // CubicBezierRelative
|> bezierCurve(control1 = [316.68767, -37.766435000000016], control2 = [313.07319, -39.10529500000001], end = [313.07319, -39.10529500000001]) // CubicBezierRelative
|> line(endAbsolute = [316.68767, -35.766435000000016]) // VerticalLineHorizonal
|> line(endAbsolute = [320.56267, -35.016435000000016]) // LineRelative
|> bezierCurve({ control1: [335.68767, -29.766435000000016], control2: [325.89187000000004, -33.71663500000002], to: [330.60815, -31.833685000000017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [343.56267, -27.266435000000016], control2: [339.5858, -28.528935000000015], to: [339.5858, -28.528935000000015]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [335.68767, -29.766435000000016], control2 = [325.89187000000004, -33.71663500000002], end = [330.60815, -31.833685000000017]) // CubicBezierRelative
|> bezierCurve(control1 = [343.56267, -27.266435000000016], control2 = [339.5858, -28.528935000000015], end = [339.5858, -28.528935000000015]) // CubicBezierRelative
|> line(endAbsolute = [350.68767, -24.766435000000016]) // LineRelative
|> line(endAbsolute = [354.68767, -20.766435000000016]) // LineRelative
|> bezierCurve({ control1: [295.68767, -33.766435000000016], control2: [334.809, -20.766435000000016], to: [314.44364, -27.758665000000015]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [295.68767, -33.766435000000016], control2 = [334.809, -20.766435000000016], end = [314.44364, -27.758665000000015]) // CubicBezierRelative
// StopRelative
|> line(endAbsolute = [299.68767, -66.76643500000002]) // MoveRelative
|> bezierCurve({ control1: [285.00017, -76.64143500000002], control2: [293.75788, -69.23718500000001], to: [289.90768, -72.43500500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [276.37517, -85.70393500000002], control2: [279.86247000000003, -81.42042500000002], to: [279.86247000000003, -81.42042500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [273.68767, -88.76643500000002], control2: [275.48830000000004, -86.71456500000002], to: [274.60142, -87.72518500000001]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [285.00017, -76.64143500000002], control2 = [293.75788, -69.23718500000001], end = [289.90768, -72.43500500000002]) // CubicBezierRelative
|> bezierCurve(control1 = [276.37517, -85.70393500000002], control2 = [279.86247000000003, -81.42042500000002], end = [279.86247000000003, -81.42042500000002]) // CubicBezierRelative
|> bezierCurve(control1 = [273.68767, -88.76643500000002], control2 = [275.48830000000004, -86.71456500000002], end = [274.60142, -87.72518500000001]) // CubicBezierRelative
|> line(endAbsolute = [267.68767, -91.76643500000002]) // LineRelative
|> line(endAbsolute = [264.68767, -96.76643500000002]) // LineRelative
|> bezierCurve({ control1: [266.68767, -111.76643000000001], control2: [264.32138000000003, -104.69775000000001], to: [264.32138000000003, -104.69775000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [278.68767, -123.76643000000001], control2: [270.61411000000004, -116.17816000000002], to: [274.2035, -120.01380000000002]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [266.68767, -111.76643000000001], control2 = [264.32138000000003, -104.69775000000001], end = [264.32138000000003, -104.69775000000001]) // CubicBezierRelative
|> bezierCurve(control1 = [278.68767, -123.76643000000001], control2 = [270.61411000000004, -116.17816000000002], end = [274.2035, -120.01380000000002]) // CubicBezierRelative
|> line(endAbsolute = [282.93767, -126.01643000000001]) // LineRelative
|> bezierCurve({ control1: [303.68767, -126.76643000000001], control2: [289.896, -127.11512000000002], to: [296.66137000000003, -126.99871000000002]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [303.68767, -126.76643000000001], control2 = [289.896, -127.11512000000002], end = [296.66137000000003, -126.99871000000002]) // CubicBezierRelative
|> line(endAbsolute = [305.68767, -125.76643000000001]) // LineRelative
|> line(endAbsolute = [310.68767, -124.76643000000001]) // LineRelative
|> line(endAbsolute = [317.68767, -122.76643000000001]) // LineRelative
|> bezierCurve({ control1: [324.37517, -113.14143000000001], control2: [322.56495, -117.43458000000001], to: [322.56495, -117.43458000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [327.68767, -96.76643500000002], control2: [326.02173000000005, -107.65292000000001], to: [327.05405, -102.46899000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [323.37517, -79.39143500000002], control2: [327.04242000000005, -90.45732500000001], to: [325.54155000000003, -85.36362500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [320.68767, -73.76643500000002], control2: [322.48830000000004, -77.53518500000001], to: [321.60142, -75.67893500000001]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [324.37517, -113.14143000000001], control2 = [322.56495, -117.43458000000001], end = [322.56495, -117.43458000000001]) // CubicBezierRelative
|> bezierCurve(control1 = [327.68767, -96.76643500000002], control2 = [326.02173000000005, -107.65292000000001], end = [327.05405, -102.46899000000002]) // CubicBezierRelative
|> bezierCurve(control1 = [323.37517, -79.39143500000002], control2 = [327.04242000000005, -90.45732500000001], end = [325.54155000000003, -85.36362500000001]) // CubicBezierRelative
|> bezierCurve(control1 = [320.68767, -73.76643500000002], control2 = [322.48830000000004, -77.53518500000001], end = [321.60142, -75.67893500000001]) // CubicBezierRelative
|> line(endAbsolute = [315.68767, -68.76643500000002]) // LineRelative
|> bezierCurve({ control1: [305.43767, -66.32893500000002], control2: [310.76687000000004, -66.51488500000002], to: [310.76687000000004, -66.51488500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [299.68767, -66.76643500000002], control2: [302.59142, -66.54550500000002], to: [302.59142, -66.54550500000002]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [305.43767, -66.32893500000002], control2 = [310.76687000000004, -66.51488500000002], end = [310.76687000000004, -66.51488500000002]) // CubicBezierRelative
|> bezierCurve(control1 = [299.68767, -66.76643500000002], control2 = [302.59142, -66.54550500000002], end = [302.59142, -66.54550500000002]) // CubicBezierRelative
// StopRelative
|> line(endAbsolute = [240.68767000000003, -68.76643500000002]) // MoveRelative
|> bezierCurve({ control1: [222.68767000000003, -80.76643500000002], control2: [233.66999, -72.11131500000002], to: [228.65800000000002, -75.79116500000002]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [222.68767000000003, -80.76643500000002], control2 = [233.66999, -72.11131500000002], end = [228.65800000000002, -75.79116500000002]) // CubicBezierRelative
|> line(endAbsolute = [219.68767000000003, -86.76643500000002]) // LineRelative
|> bezierCurve({ control1: [222.55095000000003, -116.67268000000001], control2: [219.05386000000001, -97.26953500000002], to: [220.04332000000002, -106.46619000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [227.68767000000003, -130.76643], control2: [223.91824000000003, -121.59681000000002], to: [225.39892000000003, -126.18894000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [236.43377000000004, -136.4969], control2: [232.25590000000003, -134.74853000000002], to: [232.25590000000003, -134.74853000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [249.75017000000003, -138.07893], control2: [241.08415000000005, -137.88476], to: [244.90570000000002, -138.13253]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [254.34783000000002, -138.06723000000002], control2: [251.26740000000004, -138.07493000000002], to: [252.78463000000002, -138.07093]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [265.68767, -135.76644000000002], control2: [259.20097000000004, -137.88174000000004], to: [259.20097000000004, -137.88174000000004]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [222.55095000000003, -116.67268000000001], control2 = [219.05386000000001, -97.26953500000002], end = [220.04332000000002, -106.46619000000001]) // CubicBezierRelative
|> bezierCurve(control1 = [227.68767000000003, -130.76643], control2 = [223.91824000000003, -121.59681000000002], end = [225.39892000000003, -126.18894000000002]) // CubicBezierRelative
|> bezierCurve(control1 = [236.43377000000004, -136.4969], control2 = [232.25590000000003, -134.74853000000002], end = [232.25590000000003, -134.74853000000002]) // CubicBezierRelative
|> bezierCurve(control1 = [249.75017000000003, -138.07893], control2 = [241.08415000000005, -137.88476], end = [244.90570000000002, -138.13253]) // CubicBezierRelative
|> bezierCurve(control1 = [254.34783000000002, -138.06723000000002], control2 = [251.26740000000004, -138.07493000000002], end = [252.78463000000002, -138.07093]) // CubicBezierRelative
|> bezierCurve(control1 = [265.68767, -135.76644000000002], control2 = [259.20097000000004, -137.88174000000004], end = [259.20097000000004, -137.88174000000004]) // CubicBezierRelative
|> line(endAbsolute = [265.68767, -132.76644000000002]) // VerticalLineHorizonal
|> line(endAbsolute = [267.68767, -132.76644000000002]) // HorizontalLineRelative
|> bezierCurve({ control1: [268.56267, -122.32894000000002], control2: [268.96128000000004, -128.41242000000003], to: [268.96128000000004, -128.41242000000003]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [268.56267, -122.32894000000002], control2 = [268.96128000000004, -128.41242000000003], end = [268.96128000000004, -128.41242000000003]) // CubicBezierRelative
|> line(endAbsolute = [267.68767, -115.76644000000002]) // LineRelative
|> line(endAbsolute = [262.68767, -110.76644000000002]) // LineRelative
|> line(endAbsolute = [259.68767, -104.76644000000002]) // LineRelative
@ -211,260 +211,260 @@ const svg = startSketchOn(XY)
|> line(endAbsolute = [263.68767, -91.76644500000002]) // LineRelative
|> line(endAbsolute = [263.68767, -88.76644500000002]) // VerticalLineHorizonal
|> line(endAbsolute = [265.68767, -88.76644500000002]) // HorizontalLineRelative
|> bezierCurve({ control1: [265.68767, -74.76644500000002], control2: [265.77327, -84.10056500000002], to: [265.76887000000005, -79.43241500000002]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [265.68767, -74.76644500000002], control2 = [265.77327, -84.10056500000002], end = [265.76887000000005, -79.43241500000002]) // CubicBezierRelative
|> line(endAbsolute = [263.68767, -71.76644500000002]) // LineRelative
|> line(endAbsolute = [257.68767, -68.76644500000002]) // LineRelative
|> bezierCurve({ control1: [240.68767000000003, -68.76644500000002], control2: [251.63750000000002, -68.30105500000002], to: [246.62747000000002, -68.01396500000001]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [240.68767000000003, -68.76644500000002], control2 = [251.63750000000002, -68.30105500000002], end = [246.62747000000002, -68.01396500000001]) // CubicBezierRelative
// StopRelative
|> line(endAbsolute = [348.06267, -71.45394500000002]) // MoveRelative
|> bezierCurve({ control1: [336.68767, -78.76644500000002], control2: [342.24112, -73.65657500000002], to: [342.24112, -73.65657500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [331.68767, -85.76644500000002], control2: [333.86052, -82.22373500000002], to: [333.86052, -82.22373500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [330.68767, -113.76644000000002], control2: [329.44062, -94.75465500000001], to: [330.36224000000004, -104.56387000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [333.68767, -125.76644000000002], control2: [331.54987, -120.49367000000002], to: [331.54987, -120.49367000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [339.68767, -134.76644000000002], control2: [336.35378000000003, -130.85268000000002], to: [336.35378000000003, -130.85268000000002]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [336.68767, -78.76644500000002], control2 = [342.24112, -73.65657500000002], end = [342.24112, -73.65657500000002]) // CubicBezierRelative
|> bezierCurve(control1 = [331.68767, -85.76644500000002], control2 = [333.86052, -82.22373500000002], end = [333.86052, -82.22373500000002]) // CubicBezierRelative
|> bezierCurve(control1 = [330.68767, -113.76644000000002], control2 = [329.44062, -94.75465500000001], end = [330.36224000000004, -104.56387000000002]) // CubicBezierRelative
|> bezierCurve(control1 = [333.68767, -125.76644000000002], control2 = [331.54987, -120.49367000000002], end = [331.54987, -120.49367000000002]) // CubicBezierRelative
|> bezierCurve(control1 = [339.68767, -134.76644000000002], control2 = [336.35378000000003, -130.85268000000002], end = [336.35378000000003, -130.85268000000002]) // CubicBezierRelative
|> line(endAbsolute = [344.68767, -136.76644000000002]) // LineRelative
|> bezierCurve({ control1: [354.50017, -136.89144000000002], control2: [347.95588000000004, -136.90388000000002], to: [351.22938000000005, -136.93595000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [359.7072, -136.83674000000002], control2: [357.07765, -136.86434000000003], to: [357.07765, -136.86434000000003]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [363.68767, -136.76644000000002], control2: [361.02076, -136.81354000000002], to: [362.33431, -136.79034000000001]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [354.50017, -136.89144000000002], control2 = [347.95588000000004, -136.90388000000002], end = [351.22938000000005, -136.93595000000002]) // CubicBezierRelative
|> bezierCurve(control1 = [359.7072, -136.83674000000002], control2 = [357.07765, -136.86434000000003], end = [357.07765, -136.86434000000003]) // CubicBezierRelative
|> bezierCurve(control1 = [363.68767, -136.76644000000002], control2 = [361.02076, -136.81354000000002], end = [362.33431, -136.79034000000001]) // CubicBezierRelative
|> line(endAbsolute = [364.68767, -133.76644000000002]) // LineRelative
|> line(endAbsolute = [369.68767, -132.76644000000002]) // LineRelative
|> line(endAbsolute = [374.68767, -127.76644000000002]) // LineRelative
|> line(endAbsolute = [375.68767, -125.76644000000002]) // LineRelative
|> line(endAbsolute = [378.68767, -124.76644000000002]) // LineRelative
|> line(endAbsolute = [381.68767, -119.76644000000002]) // LineRelative
|> bezierCurve({ control1: [383.68767, -90.76644500000002], control2: [383.35291, -110.03795000000002], to: [384.23553000000004, -100.62782000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [376.68767, -74.76644500000002], control2: [381.89678000000004, -84.77624500000002], to: [379.89992, -80.12019500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [361.68767, -69.76644500000002], control2: [371.66314, -72.44743500000001], to: [367.11478000000005, -70.85187500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [348.06267, -71.45394500000002], control2: [353.98599, -69.38331500000002], to: [353.98599, -69.38331500000002]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [383.68767, -90.76644500000002], control2 = [383.35291, -110.03795000000002], end = [384.23553000000004, -100.62782000000001]) // CubicBezierRelative
|> bezierCurve(control1 = [376.68767, -74.76644500000002], control2 = [381.89678000000004, -84.77624500000002], end = [379.89992, -80.12019500000002]) // CubicBezierRelative
|> bezierCurve(control1 = [361.68767, -69.76644500000002], control2 = [371.66314, -72.44743500000001], end = [367.11478000000005, -70.85187500000002]) // CubicBezierRelative
|> bezierCurve(control1 = [348.06267, -71.45394500000002], control2 = [353.98599, -69.38331500000002], end = [353.98599, -69.38331500000002]) // CubicBezierRelative
// StopRelative
|> line(endAbsolute = [420.68767, -75.76644500000002]) // MoveRelative
|> line(endAbsolute = [414.68767, -78.76644500000002]) // MoveRelative
|> line(endAbsolute = [411.68767, -81.76644500000002]) // MoveRelative
|> bezierCurve({ control1: [394.68767, -89.76644500000002], control2: [406.10302, -84.70574500000002], to: [400.49226000000004, -87.27876500000002]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [394.68767, -89.76644500000002], control2 = [406.10302, -84.70574500000002], end = [400.49226000000004, -87.27876500000002]) // CubicBezierRelative
|> line(endAbsolute = [390.68767, -93.76644500000002]) // LineRelative
|> bezierCurve({ control1: [387.00017, -105.95394000000002], control2: [388.81932, -97.84915500000002], to: [387.7277, -101.52261000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [386.68767, -123.76644000000002], control2: [386.61176, -111.93554000000002], to: [386.45034000000004, -117.77373000000001]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [387.00017, -105.95394000000002], control2 = [388.81932, -97.84915500000002], end = [387.7277, -101.52261000000001]) // CubicBezierRelative
|> bezierCurve(control1 = [386.68767, -123.76644000000002], control2 = [386.61176, -111.93554000000002], end = [386.45034000000004, -117.77373000000001]) // CubicBezierRelative
|> line(endAbsolute = [389.68767, -129.76644000000002]) // LineRelative
|> bezierCurve({ control1: [401.68767, -140.76644000000002], control2: [393.59112000000005, -133.6699], to: [397.39354000000003, -137.31580000000002]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [401.68767, -140.76644000000002], control2 = [393.59112000000005, -133.6699], end = [397.39354000000003, -137.31580000000002]) // CubicBezierRelative
|> line(endAbsolute = [406.68767, -142.76644000000002]) // LineRelative
|> bezierCurve({ control1: [419.18767, -141.64144000000002], control2: [414.16723, -143.08983], to: [414.16723, -143.08983]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [431.68767, -133.76644000000002], control2: [424.08865000000003, -139.59937000000002], to: [427.61672000000004, -137.15890000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [438.81267, -125.32894000000002], control2: [436.54426, -129.29261000000002], to: [436.54426, -129.29261000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [443.68767, -106.76644000000002], control2: [441.36597, -119.11592000000002], to: [442.65924, -113.42420000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [442.68767, -87.76644500000002], control2: [443.82181, -100.36380000000001], to: [443.70527000000004, -94.09420500000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [438.68767, -79.76644500000002], control2: [441.01966000000004, -83.40792500000002], to: [441.01966000000004, -83.40792500000002]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [419.18767, -141.64144000000002], control2 = [414.16723, -143.08983], end = [414.16723, -143.08983]) // CubicBezierRelative
|> bezierCurve(control1 = [431.68767, -133.76644000000002], control2 = [424.08865000000003, -139.59937000000002], end = [427.61672000000004, -137.15890000000002]) // CubicBezierRelative
|> bezierCurve(control1 = [438.81267, -125.32894000000002], control2 = [436.54426, -129.29261000000002], end = [436.54426, -129.29261000000002]) // CubicBezierRelative
|> bezierCurve(control1 = [443.68767, -106.76644000000002], control2 = [441.36597, -119.11592000000002], end = [442.65924, -113.42420000000001]) // CubicBezierRelative
|> bezierCurve(control1 = [442.68767, -87.76644500000002], control2 = [443.82181, -100.36380000000001], end = [443.70527000000004, -94.09420500000002]) // CubicBezierRelative
|> bezierCurve(control1 = [438.68767, -79.76644500000002], control2 = [441.01966000000004, -83.40792500000002], end = [441.01966000000004, -83.40792500000002]) // CubicBezierRelative
|> line(endAbsolute = [434.68767, -76.76644500000002]) // LineRelative
|> bezierCurve({ control1: [420.68767, -75.76644500000002], control2: [428.38627, -75.54725500000002], to: [428.38627, -75.54725500000002]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [420.68767, -75.76644500000002], control2 = [428.38627, -75.54725500000002], end = [428.38627, -75.54725500000002]) // CubicBezierRelative
|> line(endAbsolute = [119.83194, -25.193075]) // MoveRelative
|> bezierCurve({ control1: [126.83194, -26.193075], control2: [122.14194, -25.523075], to: [124.45194000000001, -25.853075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [129.83194, -32.193075], control2: [127.82194, -28.173075], to: [128.81194, -30.153075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [130.83194, -33.193075], control2: [130.16194000000002, -32.523075], to: [130.49194, -32.853075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [131.83194, -41.193075], control2: [131.16194000000002, -35.833075], to: [131.49194, -38.473075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [133.83194, -38.193075], control2: [132.49194, -40.203075], to: [133.15194, -39.213075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [135.26944, -32.068075], control2: [134.30631, -36.171825], to: [134.78069, -34.150575]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [136.83194, -26.193075], control2: [135.78506000000002, -30.129325], to: [136.30069, -28.190575]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [139.83194, -25.193075], control2: [137.82194, -25.863075000000002], to: [138.81194, -25.533075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [137.39444, -44.318075], control2: [139.51153, -31.793465], to: [139.18359, -37.939365]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [133.83194, -52.193075], control2: [135.83194, -48.193075], to: [135.83194, -48.193075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [129.83194, -51.193075], control2: [132.51194, -51.863075], to: [131.19194000000002, -51.533075000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [124.83194, -41.193075], control2: [126.83194, -46.193075], to: [126.83194, -46.193075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [120.83194, -51.193075], control2: [123.51194000000001, -44.493075], to: [122.19194, -47.793075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [117.83194, -51.193075], control2: [119.84194000000001, -51.193075], to: [118.85194, -51.193075]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [116.83194, -50.193075], control2: [117.50194, -50.863075], to: [117.17194, -50.533075000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [118.83194, -26.193075], control2: [116.5899, -41.883314999999996], to: [116.78264, -34.269515]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [119.83194, -25.193075], control2: [119.16194, -25.863075000000002], to: [119.49194, -25.533075]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [126.83194, -26.193075], control2 = [122.14194, -25.523075], end = [124.45194000000001, -25.853075]) // CubicBezierRelative
|> bezierCurve(control1 = [129.83194, -32.193075], control2 = [127.82194, -28.173075], end = [128.81194, -30.153075]) // CubicBezierRelative
|> bezierCurve(control1 = [130.83194, -33.193075], control2 = [130.16194000000002, -32.523075], end = [130.49194, -32.853075]) // CubicBezierRelative
|> bezierCurve(control1 = [131.83194, -41.193075], control2 = [131.16194000000002, -35.833075], end = [131.49194, -38.473075]) // CubicBezierRelative
|> bezierCurve(control1 = [133.83194, -38.193075], control2 = [132.49194, -40.203075], end = [133.15194, -39.213075]) // CubicBezierRelative
|> bezierCurve(control1 = [135.26944, -32.068075], control2 = [134.30631, -36.171825], end = [134.78069, -34.150575]) // CubicBezierRelative
|> bezierCurve(control1 = [136.83194, -26.193075], control2 = [135.78506000000002, -30.129325], end = [136.30069, -28.190575]) // CubicBezierRelative
|> bezierCurve(control1 = [139.83194, -25.193075], control2 = [137.82194, -25.863075000000002], end = [138.81194, -25.533075]) // CubicBezierRelative
|> bezierCurve(control1 = [137.39444, -44.318075], control2 = [139.51153, -31.793465], end = [139.18359, -37.939365]) // CubicBezierRelative
|> bezierCurve(control1 = [133.83194, -52.193075], control2 = [135.83194, -48.193075], end = [135.83194, -48.193075]) // CubicBezierRelative
|> bezierCurve(control1 = [129.83194, -51.193075], control2 = [132.51194, -51.863075], end = [131.19194000000002, -51.533075000000004]) // CubicBezierRelative
|> bezierCurve(control1 = [124.83194, -41.193075], control2 = [126.83194, -46.193075], end = [126.83194, -46.193075]) // CubicBezierRelative
|> bezierCurve(control1 = [120.83194, -51.193075], control2 = [123.51194000000001, -44.493075], end = [122.19194, -47.793075]) // CubicBezierRelative
|> bezierCurve(control1 = [117.83194, -51.193075], control2 = [119.84194000000001, -51.193075], end = [118.85194, -51.193075]) // CubicBezierRelative
|> bezierCurve(control1 = [116.83194, -50.193075], control2 = [117.50194, -50.863075], end = [117.17194, -50.533075000000004]) // CubicBezierRelative
|> bezierCurve(control1 = [118.83194, -26.193075], control2 = [116.5899, -41.883314999999996], end = [116.78264, -34.269515]) // CubicBezierRelative
|> bezierCurve(control1 = [119.83194, -25.193075], control2 = [119.16194, -25.863075000000002], end = [119.49194, -25.533075]) // CubicBezierRelative
|> line(endAbsolute = [65.254392, -26.686845]) // MoveRelative
|> bezierCurve({ control1: [69.254392, -26.686845], control2: [66.57439199999999, -26.686845], to: [67.894392, -26.686845]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [70.254392, -32.686845000000005], control2: [69.584392, -28.666845000000002], to: [69.91439199999999, -30.646845000000003]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [69.254392, -35.686845000000005], control2: [69.924392, -33.67684500000001], to: [69.594392, -34.666845]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [69.254392, -44.686845000000005], control2: [69.21439199999999, -38.686575000000005], to: [69.210922, -41.687155000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [72.629392, -39.374345000000005], control2: [70.36814199999999, -42.93371500000001], to: [71.481892, -41.180595000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [78.254392, -30.686845000000005], control2: [74.483601, -36.465155], to: [76.34075899999999, -33.557295]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [81.254392, -30.686845000000005], control2: [79.24439199999999, -30.686845000000005], to: [80.234392, -30.686845000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [80.004392, -42.811845000000005], control2: [81.254392, -38.686845000000005], to: [81.254392, -38.686845000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [74.254392, -52.686845000000005], control2: [78.254392, -46.686845000000005], to: [78.254392, -46.686845000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [73.254392, -53.686845000000005], control2: [73.924392, -53.016845], to: [73.594392, -53.346845]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [67.254392, -53.686845000000005], control2: [71.27439199999999, -53.686845000000005], to: [69.294392, -53.686845000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [61.254391999999996, -48.686845000000005], control2: [65.27439199999999, -52.03684500000001], to: [63.294391999999995, -50.38684500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [60.254391999999996, -46.686845000000005], control2: [60.924392, -48.02684500000001], to: [60.594392, -47.366845000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [61.254391999999996, -28.686845000000005], control2: [60.10475399999999, -40.47687500000001], to: [60.373141, -34.855605000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [65.254392, -26.686845000000005], control2: [62.574391999999996, -28.026845000000005], to: [63.894391999999996, -27.366845000000005]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [69.254392, -26.686845], control2 = [66.57439199999999, -26.686845], end = [67.894392, -26.686845]) // CubicBezierRelative
|> bezierCurve(control1 = [70.254392, -32.686845000000005], control2 = [69.584392, -28.666845000000002], end = [69.91439199999999, -30.646845000000003]) // CubicBezierRelative
|> bezierCurve(control1 = [69.254392, -35.686845000000005], control2 = [69.924392, -33.67684500000001], end = [69.594392, -34.666845]) // CubicBezierRelative
|> bezierCurve(control1 = [69.254392, -44.686845000000005], control2 = [69.21439199999999, -38.686575000000005], end = [69.210922, -41.687155000000004]) // CubicBezierRelative
|> bezierCurve(control1 = [72.629392, -39.374345000000005], control2 = [70.36814199999999, -42.93371500000001], end = [71.481892, -41.180595000000004]) // CubicBezierRelative
|> bezierCurve(control1 = [78.254392, -30.686845000000005], control2 = [74.483601, -36.465155], end = [76.34075899999999, -33.557295]) // CubicBezierRelative
|> bezierCurve(control1 = [81.254392, -30.686845000000005], control2 = [79.24439199999999, -30.686845000000005], end = [80.234392, -30.686845000000005]) // CubicBezierRelative
|> bezierCurve(control1 = [80.004392, -42.811845000000005], control2 = [81.254392, -38.686845000000005], end = [81.254392, -38.686845000000005]) // CubicBezierRelative
|> bezierCurve(control1 = [74.254392, -52.686845000000005], control2 = [78.254392, -46.686845000000005], end = [78.254392, -46.686845000000005]) // CubicBezierRelative
|> bezierCurve(control1 = [73.254392, -53.686845000000005], control2 = [73.924392, -53.016845], end = [73.594392, -53.346845]) // CubicBezierRelative
|> bezierCurve(control1 = [67.254392, -53.686845000000005], control2 = [71.27439199999999, -53.686845000000005], end = [69.294392, -53.686845000000005]) // CubicBezierRelative
|> bezierCurve(control1 = [61.254391999999996, -48.686845000000005], control2 = [65.27439199999999, -52.03684500000001], end = [63.294391999999995, -50.38684500000001]) // CubicBezierRelative
|> bezierCurve(control1 = [60.254391999999996, -46.686845000000005], control2 = [60.924392, -48.02684500000001], end = [60.594392, -47.366845000000005]) // CubicBezierRelative
|> bezierCurve(control1 = [61.254391999999996, -28.686845000000005], control2 = [60.10475399999999, -40.47687500000001], end = [60.373141, -34.855605000000004]) // CubicBezierRelative
|> bezierCurve(control1 = [65.254392, -26.686845000000005], control2 = [62.574391999999996, -28.026845000000005], end = [63.894391999999996, -27.366845000000005]) // CubicBezierRelative
|> line(endAbsolute = [185.48371, -31.108985]) // MoveRelative
|> bezierCurve({ control1: [197.48371, -31.108985], control2: [189.48289, -31.028185], to: [193.48463, -31.022985000000002]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [198.48371, -36.108985000000004], control2: [197.81371000000001, -32.758985], to: [198.14371, -34.408985]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [197.48371, -38.108985000000004], control2: [198.15371, -36.768985], to: [197.82371, -37.428985000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [189.48371, -38.108985000000004], control2: [194.84371000000002, -38.108985000000004], to: [192.20371, -38.108985000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [188.48371, -42.108985000000004], control2: [189.15371, -39.428985000000004], to: [188.82371, -40.748985000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [196.48371, -43.108985000000004], control2: [191.12371, -42.438985], to: [193.76371, -42.768985]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [196.48371, -47.108985000000004], control2: [196.48371, -44.428985000000004], to: [196.48371, -45.748985000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [191.54621, -48.983985000000004], control2: [194.85433, -47.727735], to: [193.22496, -48.346485]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [186.48371, -51.108985000000004], control2: [189.87558, -49.685235000000006], to: [188.20496, -50.38648500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [185.48371, -53.108985000000004], control2: [186.15371, -51.768985], to: [185.82371, -52.428985000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [195.48371, -52.108985000000004], control2: [188.78371, -52.778985000000006], to: [192.08371, -52.44898500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [193.48371, -56.108985000000004], control2: [194.82371, -53.428985000000004], to: [194.16371, -54.748985000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [188.48371, -58.108985000000004], control2: [191.83371, -56.768985], to: [190.18371, -57.428985000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [183.48371, -58.108985000000004], control2: [186.83371, -58.108985000000004], to: [185.18371, -58.108985000000004]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [179.48371, -55.108985000000004], control2: [182.16371, -57.118985], to: [180.84371000000002, -56.12898500000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [180.79621, -38.046485000000004], control2: [178.95086, -49.019255], to: [179.50181, -44.025395]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [182.48371, -33.108985000000004], control2: [181.35308, -36.41710500000001], to: [181.90996, -34.787735000000005]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [185.48371, -31.108985000000004], control2: [183.47371, -32.44898500000001], to: [184.46371, -31.788985000000004]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [197.48371, -31.108985], control2 = [189.48289, -31.028185], end = [193.48463, -31.022985000000002]) // CubicBezierRelative
|> bezierCurve(control1 = [198.48371, -36.108985000000004], control2 = [197.81371000000001, -32.758985], end = [198.14371, -34.408985]) // CubicBezierRelative
|> bezierCurve(control1 = [197.48371, -38.108985000000004], control2 = [198.15371, -36.768985], end = [197.82371, -37.428985000000004]) // CubicBezierRelative
|> bezierCurve(control1 = [189.48371, -38.108985000000004], control2 = [194.84371000000002, -38.108985000000004], end = [192.20371, -38.108985000000004]) // CubicBezierRelative
|> bezierCurve(control1 = [188.48371, -42.108985000000004], control2 = [189.15371, -39.428985000000004], end = [188.82371, -40.748985000000005]) // CubicBezierRelative
|> bezierCurve(control1 = [196.48371, -43.108985000000004], control2 = [191.12371, -42.438985], end = [193.76371, -42.768985]) // CubicBezierRelative
|> bezierCurve(control1 = [196.48371, -47.108985000000004], control2 = [196.48371, -44.428985000000004], end = [196.48371, -45.748985000000005]) // CubicBezierRelative
|> bezierCurve(control1 = [191.54621, -48.983985000000004], control2 = [194.85433, -47.727735], end = [193.22496, -48.346485]) // CubicBezierRelative
|> bezierCurve(control1 = [186.48371, -51.108985000000004], control2 = [189.87558, -49.685235000000006], end = [188.20496, -50.38648500000001]) // CubicBezierRelative
|> bezierCurve(control1 = [185.48371, -53.108985000000004], control2 = [186.15371, -51.768985], end = [185.82371, -52.428985000000004]) // CubicBezierRelative
|> bezierCurve(control1 = [195.48371, -52.108985000000004], control2 = [188.78371, -52.778985000000006], end = [192.08371, -52.44898500000001]) // CubicBezierRelative
|> bezierCurve(control1 = [193.48371, -56.108985000000004], control2 = [194.82371, -53.428985000000004], end = [194.16371, -54.748985000000005]) // CubicBezierRelative
|> bezierCurve(control1 = [188.48371, -58.108985000000004], control2 = [191.83371, -56.768985], end = [190.18371, -57.428985000000004]) // CubicBezierRelative
|> bezierCurve(control1 = [183.48371, -58.108985000000004], control2 = [186.83371, -58.108985000000004], end = [185.18371, -58.108985000000004]) // CubicBezierRelative
|> bezierCurve(control1 = [179.48371, -55.108985000000004], control2 = [182.16371, -57.118985], end = [180.84371000000002, -56.12898500000001]) // CubicBezierRelative
|> bezierCurve(control1 = [180.79621, -38.046485000000004], control2 = [178.95086, -49.019255], end = [179.50181, -44.025395]) // CubicBezierRelative
|> bezierCurve(control1 = [182.48371, -33.108985000000004], control2 = [181.35308, -36.41710500000001], end = [181.90996, -34.787735000000005]) // CubicBezierRelative
|> bezierCurve(control1 = [185.48371, -31.108985000000004], control2 = [183.47371, -32.44898500000001], end = [184.46371, -31.788985000000004]) // CubicBezierRelative
|> line(endAbsolute = [248.52117, -92.100105]) // MoveRelative
|> bezierCurve({ control1: [252.52117, -92.100105], control2: [249.84117, -92.100105], to: [251.16117, -92.100105]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [253.52117, -99.100105], control2: [252.85117000000002, -94.410105], to: [253.18117, -96.720105]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [248.89617, -100.8501], control2: [251.99492, -99.677605], to: [250.46867, -100.2551]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [237.52117, -107.1001], control2: [243.22058, -103.02548], to: [243.22058, -103.02548]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [236.52117, -109.1001], control2: [237.19117, -107.7601], to: [236.86117000000002, -108.42009999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [252.52117, -108.1001], control2: [241.80117, -108.7701], to: [247.08117000000001, -108.4401]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [253.52117, -112.1001], control2: [252.85117000000002, -109.42009999999999], to: [253.18117, -110.7401]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [248.52117, -117.1001], control2: [251.87117, -113.7501], to: [250.22117, -115.4001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [234.52117, -118.1001], control2: [242.52117, -118.1001], to: [242.52117, -118.1001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [231.52117, -112.1001], control2: [233.53117, -116.1201], to: [232.54117000000002, -114.1401]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [231.52117, -104.1001], control2: [231.52117, -109.4601], to: [231.52117, -106.8201]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [236.52117, -99.100105], control2: [233.17117000000002, -102.45009999999999], to: [234.82117000000002, -100.8001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [236.52117, -97.100105], control2: [236.52117, -98.440105], to: [236.52117, -97.780105]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [248.52117, -92.100105], control2: [240.49514000000002, -95.372295], to: [244.49777, -93.709465]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [252.52117, -92.100105], control2 = [249.84117, -92.100105], end = [251.16117, -92.100105]) // CubicBezierRelative
|> bezierCurve(control1 = [253.52117, -99.100105], control2 = [252.85117000000002, -94.410105], end = [253.18117, -96.720105]) // CubicBezierRelative
|> bezierCurve(control1 = [248.89617, -100.8501], control2 = [251.99492, -99.677605], end = [250.46867, -100.2551]) // CubicBezierRelative
|> bezierCurve(control1 = [237.52117, -107.1001], control2 = [243.22058, -103.02548], end = [243.22058, -103.02548]) // CubicBezierRelative
|> bezierCurve(control1 = [236.52117, -109.1001], control2 = [237.19117, -107.7601], end = [236.86117000000002, -108.42009999999999]) // CubicBezierRelative
|> bezierCurve(control1 = [252.52117, -108.1001], control2 = [241.80117, -108.7701], end = [247.08117000000001, -108.4401]) // CubicBezierRelative
|> bezierCurve(control1 = [253.52117, -112.1001], control2 = [252.85117000000002, -109.42009999999999], end = [253.18117, -110.7401]) // CubicBezierRelative
|> bezierCurve(control1 = [248.52117, -117.1001], control2 = [251.87117, -113.7501], end = [250.22117, -115.4001]) // CubicBezierRelative
|> bezierCurve(control1 = [234.52117, -118.1001], control2 = [242.52117, -118.1001], end = [242.52117, -118.1001]) // CubicBezierRelative
|> bezierCurve(control1 = [231.52117, -112.1001], control2 = [233.53117, -116.1201], end = [232.54117000000002, -114.1401]) // CubicBezierRelative
|> bezierCurve(control1 = [231.52117, -104.1001], control2 = [231.52117, -109.4601], end = [231.52117, -106.8201]) // CubicBezierRelative
|> bezierCurve(control1 = [236.52117, -99.100105], control2 = [233.17117000000002, -102.45009999999999], end = [234.82117000000002, -100.8001]) // CubicBezierRelative
|> bezierCurve(control1 = [236.52117, -97.100105], control2 = [236.52117, -98.440105], end = [236.52117, -97.780105]) // CubicBezierRelative
|> bezierCurve(control1 = [248.52117, -92.100105], control2 = [240.49514000000002, -95.372295], end = [244.49777, -93.709465]) // CubicBezierRelative
|> line(endAbsolute = [299.09756, -85.781585]) // MoveRelative
|> bezierCurve({ control1: [305.09756, -85.781585], control2: [301.07756, -85.781585], to: [303.05755999999997, -85.781585]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [307.09756, -86.781585], control2: [305.75756, -86.111585], to: [306.41756, -86.441585]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [308.09756, -97.781585], control2: [307.48978999999997, -90.442425], to: [307.81822999999997, -94.110415]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [309.09756, -102.78158], control2: [308.42755999999997, -99.43158500000001], to: [308.75756, -101.08158]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [307.09756, -104.78158], control2: [308.43755999999996, -103.44158], to: [307.77756, -104.10158]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [306.09756, -108.78158], control2: [306.76756, -106.10158], to: [306.43755999999996, -107.42158]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [301.09756, -113.78158], control2: [304.43089, -110.44825], to: [302.76423, -112.11491000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [301.09756, -105.78158], control2: [301.09756, -111.14158], to: [301.09756, -108.50158]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [298.09756, -106.78158], control2: [300.10756, -106.11158], to: [299.11755999999997, -106.44158]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [294.09756, -105.78158], control2: [296.77756, -106.45158], to: [295.45756, -106.12158000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [293.09756, -111.78158], control2: [293.76756, -107.76158000000001], to: [293.43755999999996, -109.74158]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [290.09756, -114.78158], control2: [292.10756, -112.77158], to: [291.11755999999997, -113.76158000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [290.09756, -100.78158], control2: [290.09756, -110.16158], to: [290.09756, -105.54158000000001]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [292.09756, -100.78158], control2: [290.75756, -100.78158], to: [291.41756, -100.78158]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [293.34756, -95.531585], control2: [292.51006, -99.049085], to: [292.92256, -97.316585]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [295.09756, -89.781585], control2: [293.92506, -93.63408500000001], to: [294.50255999999996, -91.736585]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [299.09756, -85.781585], control2: [296.41756, -88.46158500000001], to: [297.73756, -87.141585]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [305.09756, -85.781585], control2 = [301.07756, -85.781585], end = [303.05755999999997, -85.781585]) // CubicBezierRelative
|> bezierCurve(control1 = [307.09756, -86.781585], control2 = [305.75756, -86.111585], end = [306.41756, -86.441585]) // CubicBezierRelative
|> bezierCurve(control1 = [308.09756, -97.781585], control2 = [307.48978999999997, -90.442425], end = [307.81822999999997, -94.110415]) // CubicBezierRelative
|> bezierCurve(control1 = [309.09756, -102.78158], control2 = [308.42755999999997, -99.43158500000001], end = [308.75756, -101.08158]) // CubicBezierRelative
|> bezierCurve(control1 = [307.09756, -104.78158], control2 = [308.43755999999996, -103.44158], end = [307.77756, -104.10158]) // CubicBezierRelative
|> bezierCurve(control1 = [306.09756, -108.78158], control2 = [306.76756, -106.10158], end = [306.43755999999996, -107.42158]) // CubicBezierRelative
|> bezierCurve(control1 = [301.09756, -113.78158], control2 = [304.43089, -110.44825], end = [302.76423, -112.11491000000001]) // CubicBezierRelative
|> bezierCurve(control1 = [301.09756, -105.78158], control2 = [301.09756, -111.14158], end = [301.09756, -108.50158]) // CubicBezierRelative
|> bezierCurve(control1 = [298.09756, -106.78158], control2 = [300.10756, -106.11158], end = [299.11755999999997, -106.44158]) // CubicBezierRelative
|> bezierCurve(control1 = [294.09756, -105.78158], control2 = [296.77756, -106.45158], end = [295.45756, -106.12158000000001]) // CubicBezierRelative
|> bezierCurve(control1 = [293.09756, -111.78158], control2 = [293.76756, -107.76158000000001], end = [293.43755999999996, -109.74158]) // CubicBezierRelative
|> bezierCurve(control1 = [290.09756, -114.78158], control2 = [292.10756, -112.77158], end = [291.11755999999997, -113.76158000000001]) // CubicBezierRelative
|> bezierCurve(control1 = [290.09756, -100.78158], control2 = [290.09756, -110.16158], end = [290.09756, -105.54158000000001]) // CubicBezierRelative
|> bezierCurve(control1 = [292.09756, -100.78158], control2 = [290.75756, -100.78158], end = [291.41756, -100.78158]) // CubicBezierRelative
|> bezierCurve(control1 = [293.34756, -95.531585], control2 = [292.51006, -99.049085], end = [292.92256, -97.316585]) // CubicBezierRelative
|> bezierCurve(control1 = [295.09756, -89.781585], control2 = [293.92506, -93.63408500000001], end = [294.50255999999996, -91.736585]) // CubicBezierRelative
|> bezierCurve(control1 = [299.09756, -85.781585], control2 = [296.41756, -88.46158500000001], end = [297.73756, -87.141585]) // CubicBezierRelative
|> line(endAbsolute = [419.93938, -96.155625]) // MoveRelative
|> bezierCurve({ control1: [424.75188, -96.218125], control2: [422.32157, -96.186525], to: [422.32157, -96.186525]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [425.75188, -102.21812], control2: [425.08188, -98.198125], to: [425.41188000000005, -100.17812]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [417.75188, -104.21812], control2: [423.11188000000004, -102.87812], to: [420.47188000000006, -103.53811999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [415.75188, -107.21812], control2: [416.76188, -105.70312], to: [416.76188, -105.70312]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [422.75188, -108.21812], control2: [418.06188000000003, -107.54812], to: [420.37188000000003, -107.87812]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [423.75188, -112.21812], control2: [423.08188, -109.53811999999999], to: [423.41188000000005, -110.85812]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [413.75188, -117.21812], control2: [418.80188000000004, -114.69312], to: [418.80188000000004, -114.69312]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [422.75188, -117.21812], control2: [416.72188000000006, -117.21812], to: [419.69188, -117.21812]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [421.75188, -120.21812], control2: [422.42188000000004, -118.20812], to: [422.09188, -119.19812]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [418.75188, -122.21812], control2: [420.76188, -120.87812], to: [419.77188, -121.53811999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [411.75188, -123.21812], control2: [416.44188, -122.54812], to: [414.13188, -122.87812]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [407.75188, -121.21812], control2: [410.43188000000004, -122.55812], to: [409.11188000000004, -121.89812]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [409.18938, -103.59312], control2: [407.53385000000003, -114.968], to: [407.63543000000004, -109.67378]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [411.75188, -97.218125], control2: [410.75188, -99.218125], to: [410.75188, -99.218125]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [419.93938, -96.155625], control2: [414.75188, -96.218125], to: [414.75188, -96.218125]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [424.75188, -96.218125], control2 = [422.32157, -96.186525], end = [422.32157, -96.186525]) // CubicBezierRelative
|> bezierCurve(control1 = [425.75188, -102.21812], control2 = [425.08188, -98.198125], end = [425.41188000000005, -100.17812]) // CubicBezierRelative
|> bezierCurve(control1 = [417.75188, -104.21812], control2 = [423.11188000000004, -102.87812], end = [420.47188000000006, -103.53811999999999]) // CubicBezierRelative
|> bezierCurve(control1 = [415.75188, -107.21812], control2 = [416.76188, -105.70312], end = [416.76188, -105.70312]) // CubicBezierRelative
|> bezierCurve(control1 = [422.75188, -108.21812], control2 = [418.06188000000003, -107.54812], end = [420.37188000000003, -107.87812]) // CubicBezierRelative
|> bezierCurve(control1 = [423.75188, -112.21812], control2 = [423.08188, -109.53811999999999], end = [423.41188000000005, -110.85812]) // CubicBezierRelative
|> bezierCurve(control1 = [413.75188, -117.21812], control2 = [418.80188000000004, -114.69312], end = [418.80188000000004, -114.69312]) // CubicBezierRelative
|> bezierCurve(control1 = [422.75188, -117.21812], control2 = [416.72188000000006, -117.21812], end = [419.69188, -117.21812]) // CubicBezierRelative
|> bezierCurve(control1 = [421.75188, -120.21812], control2 = [422.42188000000004, -118.20812], end = [422.09188, -119.19812]) // CubicBezierRelative
|> bezierCurve(control1 = [418.75188, -122.21812], control2 = [420.76188, -120.87812], end = [419.77188, -121.53811999999999]) // CubicBezierRelative
|> bezierCurve(control1 = [411.75188, -123.21812], control2 = [416.44188, -122.54812], end = [414.13188, -122.87812]) // CubicBezierRelative
|> bezierCurve(control1 = [407.75188, -121.21812], control2 = [410.43188000000004, -122.55812], end = [409.11188000000004, -121.89812]) // CubicBezierRelative
|> bezierCurve(control1 = [409.18938, -103.59312], control2 = [407.53385000000003, -114.968], end = [407.63543000000004, -109.67378]) // CubicBezierRelative
|> bezierCurve(control1 = [411.75188, -97.218125], control2 = [410.75188, -99.218125], end = [410.75188, -99.218125]) // CubicBezierRelative
|> bezierCurve(control1 = [419.93938, -96.155625], control2 = [414.75188, -96.218125], end = [414.75188, -96.218125]) // CubicBezierRelative
|> line(endAbsolute = [198.29461, -92.109945]) // MoveRelative
|> bezierCurve({ control1: [202.29461, -92.109945], control2: [199.61461, -92.109945], to: [200.93461, -92.109945]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [205.29461, -97.109945], control2: [203.28461000000001, -93.759945], to: [204.27461, -95.409945]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [205.29461, -104.10994], control2: [205.29461, -99.419945], to: [205.29461, -101.72994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [203.29461, -103.10994], control2: [204.63461, -103.77994], to: [203.97461, -103.44994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [203.29461, -101.10994], control2: [203.29461, -102.44994], to: [203.29461, -101.78994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [195.29461, -105.10994], control2: [200.58634, -102.35660999999999], to: [197.91966, -103.69645]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [194.29461, -108.10994], control2: [194.96461, -106.09993999999999], to: [194.63461, -107.08994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [201.29461, -110.10994], control2: [196.60461, -108.76993999999999], to: [198.91461, -109.42993999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [203.29461, -112.10994], control2: [201.95461, -110.76993999999999], to: [202.61461, -111.42993999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [203.29461, -117.10994], control2: [203.29461, -113.75994], to: [203.29461, -115.40993999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [195.29461, -120.10994], control2: [200.65652, -118.18306], to: [197.98453, -119.17430999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [190.29461, -120.10994], control2: [193.64461, -120.10994], to: [191.99461, -120.10994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [188.29461, -117.10994], control2: [189.63461, -119.11994], to: [188.97461, -118.12993999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [194.29461, -114.10994], control2: [190.27461, -116.11994], to: [192.25461, -115.12993999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [188.29461, -110.10994], control2: [192.31461000000002, -112.78994], to: [190.33461, -111.46994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [186.29461, -107.10994], control2: [187.63461, -109.11994], to: [186.97461, -108.12993999999999]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [187.29461, -101.10994], control2: [186.62461000000002, -105.12993999999999], to: [186.95461, -103.14994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [191.29461, -96.109945], control2: [188.61461, -99.45994499999999], to: [189.93461, -97.809945]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [198.29461, -92.109945], control2: [193.60461, -94.789945], to: [195.91461, -93.469945]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [202.29461, -92.109945], control2 = [199.61461, -92.109945], end = [200.93461, -92.109945]) // CubicBezierRelative
|> bezierCurve(control1 = [205.29461, -97.109945], control2 = [203.28461000000001, -93.759945], end = [204.27461, -95.409945]) // CubicBezierRelative
|> bezierCurve(control1 = [205.29461, -104.10994], control2 = [205.29461, -99.419945], end = [205.29461, -101.72994]) // CubicBezierRelative
|> bezierCurve(control1 = [203.29461, -103.10994], control2 = [204.63461, -103.77994], end = [203.97461, -103.44994]) // CubicBezierRelative
|> bezierCurve(control1 = [203.29461, -101.10994], control2 = [203.29461, -102.44994], end = [203.29461, -101.78994]) // CubicBezierRelative
|> bezierCurve(control1 = [195.29461, -105.10994], control2 = [200.58634, -102.35660999999999], end = [197.91966, -103.69645]) // CubicBezierRelative
|> bezierCurve(control1 = [194.29461, -108.10994], control2 = [194.96461, -106.09993999999999], end = [194.63461, -107.08994]) // CubicBezierRelative
|> bezierCurve(control1 = [201.29461, -110.10994], control2 = [196.60461, -108.76993999999999], end = [198.91461, -109.42993999999999]) // CubicBezierRelative
|> bezierCurve(control1 = [203.29461, -112.10994], control2 = [201.95461, -110.76993999999999], end = [202.61461, -111.42993999999999]) // CubicBezierRelative
|> bezierCurve(control1 = [203.29461, -117.10994], control2 = [203.29461, -113.75994], end = [203.29461, -115.40993999999999]) // CubicBezierRelative
|> bezierCurve(control1 = [195.29461, -120.10994], control2 = [200.65652, -118.18306], end = [197.98453, -119.17430999999999]) // CubicBezierRelative
|> bezierCurve(control1 = [190.29461, -120.10994], control2 = [193.64461, -120.10994], end = [191.99461, -120.10994]) // CubicBezierRelative
|> bezierCurve(control1 = [188.29461, -117.10994], control2 = [189.63461, -119.11994], end = [188.97461, -118.12993999999999]) // CubicBezierRelative
|> bezierCurve(control1 = [194.29461, -114.10994], control2 = [190.27461, -116.11994], end = [192.25461, -115.12993999999999]) // CubicBezierRelative
|> bezierCurve(control1 = [188.29461, -110.10994], control2 = [192.31461000000002, -112.78994], end = [190.33461, -111.46994]) // CubicBezierRelative
|> bezierCurve(control1 = [186.29461, -107.10994], control2 = [187.63461, -109.11994], end = [186.97461, -108.12993999999999]) // CubicBezierRelative
|> bezierCurve(control1 = [187.29461, -101.10994], control2 = [186.62461000000002, -105.12993999999999], end = [186.95461, -103.14994]) // CubicBezierRelative
|> bezierCurve(control1 = [191.29461, -96.109945], control2 = [188.61461, -99.45994499999999], end = [189.93461, -97.809945]) // CubicBezierRelative
|> bezierCurve(control1 = [198.29461, -92.109945], control2 = [193.60461, -94.789945], end = [195.91461, -93.469945]) // CubicBezierRelative
|> line(endAbsolute = [0, -0]) // MoveRelative
|> bezierCurve({ control1: [3, -1], control2: [0.99, -0.33], to: [1.98, -0.66]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [3, -4], control2: [3, -1.99], to: [3, -2.98]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [8, -4], control2: [4.65, -4], to: [6.3, -4]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [13, -6], control2: [10.475, -4.99], to: [10.475, -4.99]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [13, -10], control2: [13, -7.32], to: [13, -8.64]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [7, -12], control2: [11.02, -10.66], to: [9.04, -11.32]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [3, -12], control2: [5.68, -12], to: [4.36, -12] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -19], control2: [2.01, -14.31], to: [1.02, -16.62] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-2, -18], control2: [-0.66, -18.67], to: [-1.32, -18.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-3, -8], control2: [-2.383986, -14.672121], to: [-2.7150643, -11.337819] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-4, -5], control2: [-3.33, -7.01], to: [-3.66, -6.02] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-1, -5], control2: [-3.01, -5], to: [-2.02, -5]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [0, -0], control2: [-0.6699999999999999, -3.35], to: [-0.33999999999999997, -1.7000000000000002]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [3, -1], control2 = [0.99, -0.33], end = [1.98, -0.66]) // CubicBezierRelative
|> bezierCurve(control1 = [3, -4], control2 = [3, -1.99], end = [3, -2.98]) // CubicBezierRelative
|> bezierCurve(control1 = [8, -4], control2 = [4.65, -4], end = [6.3, -4]) // CubicBezierRelative
|> bezierCurve(control1 = [13, -6], control2 = [10.475, -4.99], end = [10.475, -4.99]) // CubicBezierRelative
|> bezierCurve(control1 = [13, -10], control2 = [13, -7.32], end = [13, -8.64]) // CubicBezierRelative
|> bezierCurve(control1 = [7, -12], control2 = [11.02, -10.66], end = [9.04, -11.32]) // CubicBezierRelative
|> bezierCurve(control1 = [3, -12], control2 = [5.68, -12], end = [4.36, -12] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [0, -19], control2 = [2.01, -14.31], end = [1.02, -16.62] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [-2, -18], control2 = [-0.66, -18.67], end = [-1.32, -18.34] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [-3, -8], control2 = [-2.383986, -14.672121], end = [-2.7150643, -11.337819] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [-4, -5], control2 = [-3.33, -7.01], end = [-3.66, -6.02] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [-1, -5], control2 = [-3.01, -5], end = [-2.02, -5]) // CubicBezierRelative
|> bezierCurve(control1 = [0, -0], control2 = [-0.6699999999999999, -3.35], end = [-0.33999999999999997, -1.7000000000000002]) // CubicBezierRelative
|> line(endAbsolute = [0, -0]) // MoveRelative
|> bezierCurve({ control1: [7, -0], control2: [2.31, -0], to: [4.62, -0]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [17, -5], control2: [12.3125, -2.3125], to: [12.3125, -2.3125]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [19, -8], control2: [17.99, -6.485], to: [17.99, -6.485]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [17, -14], control2: [18.333333, -10], to: [17.666667, -12]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [15, -14], control2: [16.34, -14], to: [15.68, -14]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [14, -9], control2: [14.67, -12.35], to: [14.34, -10.7] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [6, -8], control2: [11.36, -8.67], to: [8.72, -8.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [6, -6], control2: [6, -7.34], to: [6, -6.68] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [1, -5], control2: [4.35, -5.67], to: [2.7, -5.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -0], control2: [0.67, -3.35], to: [0.34, -1.7] }, %) // CubicBezierAbsolute
|> bezierCurve(control1 = [7, -0], control2 = [2.31, -0], end = [4.62, -0]) // CubicBezierRelative
|> bezierCurve(control1 = [17, -5], control2 = [12.3125, -2.3125], end = [12.3125, -2.3125]) // CubicBezierRelative
|> bezierCurve(control1 = [19, -8], control2 = [17.99, -6.485], end = [17.99, -6.485]) // CubicBezierRelative
|> bezierCurve(control1 = [17, -14], control2 = [18.333333, -10], end = [17.666667, -12]) // CubicBezierRelative
|> bezierCurve(control1 = [15, -14], control2 = [16.34, -14], end = [15.68, -14]) // CubicBezierRelative
|> bezierCurve(control1 = [14, -9], control2 = [14.67, -12.35], end = [14.34, -10.7] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [6, -8], control2 = [11.36, -8.67], end = [8.72, -8.34] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [6, -6], control2 = [6, -7.34], end = [6, -6.68] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [1, -5], control2 = [4.35, -5.67], end = [2.7, -5.34] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [0, -0], control2 = [0.67, -3.35], end = [0.34, -1.7] ) // CubicBezierAbsolute
|> line(endAbsolute = [-19.467588, -31.053017]) // MoveRelative
|> bezierCurve({ control1: [-12.467588, -32.053017], control2: [-17.157588, -31.383017], to: [-14.847587999999998, -31.713017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-10.467588, -34.053017], control2: [-11.807587999999999, -32.713016999999994], to: [-11.147587999999999, -33.373017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-10.467588, -39.053017], control2: [-10.467588, -35.703016999999996], to: [-10.467588, -37.353016999999994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-14.467588, -37.053017], control2: [-11.787588, -38.393017], to: [-13.107588, -37.733017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-14.467588, -40.053017], control2: [-14.467588, -38.043017], to: [-14.467588, -39.033016999999994]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-26.467588, -40.053017], control2: [-18.427588, -40.053017], to: [-22.387588, -40.053017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-24.467588, -38.053017], control2: [-25.807588, -39.393017], to: [-25.147588, -38.733017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-17.467588, -36.053017], control2: [-22.157588, -37.393017], to: [-19.847588, -36.733017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-21.467588, -34.053017], control2: [-18.787588, -35.393017], to: [-20.107588, -34.733017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-21.467588, -32.053017], control2: [-21.467588, -33.393017], to: [-21.467588, -32.733017]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [-19.467588, -31.053016999999997], control2: [-20.807588, -31.723017], to: [-20.147588, -31.393016999999997]}, %) // CubicBezierRelative
|> bezierCurve(control1 = [-12.467588, -32.053017], control2 = [-17.157588, -31.383017], end = [-14.847587999999998, -31.713017]) // CubicBezierRelative
|> bezierCurve(control1 = [-10.467588, -34.053017], control2 = [-11.807587999999999, -32.713016999999994], end = [-11.147587999999999, -33.373017]) // CubicBezierRelative
|> bezierCurve(control1 = [-10.467588, -39.053017], control2 = [-10.467588, -35.703016999999996], end = [-10.467588, -37.353016999999994]) // CubicBezierRelative
|> bezierCurve(control1 = [-14.467588, -37.053017], control2 = [-11.787588, -38.393017], end = [-13.107588, -37.733017]) // CubicBezierRelative
|> bezierCurve(control1 = [-14.467588, -40.053017], control2 = [-14.467588, -38.043017], end = [-14.467588, -39.033016999999994]) // CubicBezierRelative
|> bezierCurve(control1 = [-26.467588, -40.053017], control2 = [-18.427588, -40.053017], end = [-22.387588, -40.053017]) // CubicBezierRelative
|> bezierCurve(control1 = [-24.467588, -38.053017], control2 = [-25.807588, -39.393017], end = [-25.147588, -38.733017]) // CubicBezierRelative
|> bezierCurve(control1 = [-17.467588, -36.053017], control2 = [-22.157588, -37.393017], end = [-19.847588, -36.733017]) // CubicBezierRelative
|> bezierCurve(control1 = [-21.467588, -34.053017], control2 = [-18.787588, -35.393017], end = [-20.107588, -34.733017]) // CubicBezierRelative
|> bezierCurve(control1 = [-21.467588, -32.053017], control2 = [-21.467588, -33.393017], end = [-21.467588, -32.733017]) // CubicBezierRelative
|> bezierCurve(control1 = [-19.467588, -31.053016999999997], control2 = [-20.807588, -31.723017], end = [-20.147588, -31.393016999999997]) // CubicBezierRelative
|> line(endAbsolute = [0, -0]) // MoveRelative
|> bezierCurve({ control1: [16, -3], control2: [5.4494016, -0.77848594], to: [10.65681, -1.7240142]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [18, -4], control2: [16.66, -3.33], to: [17.32, -3.66]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [18, -6], control2: [18, -4.66], to: [18, -5.32]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [14, -8], control2: [16.02, -6.99], to: [16.02, -6.99] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [7, -7], control2: [11.69, -7.67], to: [9.38, -7.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [1, -3], control2: [5.02, -5.68], to: [3.04, -4.36] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [1, -8], control2: [1, -4.65], to: [1, -6.3] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-3, -7], control2: [-0.32, -7.67], to: [-1.64, -7.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-4, -3], control2: [-3.33, -5.68], to: [-3.66, -4.36] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -0], control2: [-2.68, -2.01], to: [-1.36, -1.02] }, %) // CubicBezierAbsolute
|> bezierCurve(control1 = [16, -3], control2 = [5.4494016, -0.77848594], end = [10.65681, -1.7240142]) // CubicBezierRelative
|> bezierCurve(control1 = [18, -4], control2 = [16.66, -3.33], end = [17.32, -3.66]) // CubicBezierRelative
|> bezierCurve(control1 = [18, -6], control2 = [18, -4.66], end = [18, -5.32]) // CubicBezierRelative
|> bezierCurve(control1 = [14, -8], control2 = [16.02, -6.99], end = [16.02, -6.99] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [7, -7], control2 = [11.69, -7.67], end = [9.38, -7.34] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [1, -3], control2 = [5.02, -5.68], end = [3.04, -4.36] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [1, -8], control2 = [1, -4.65], end = [1, -6.3] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [-3, -7], control2 = [-0.32, -7.67], end = [-1.64, -7.34] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [-4, -3], control2 = [-3.33, -5.68], end = [-3.66, -4.36] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [0, -0], control2 = [-2.68, -2.01], end = [-1.36, -1.02] ) // CubicBezierAbsolute
|> line(endAbsolute = [0, -0]) // MoveAbsolute
|> bezierCurve({ control1: [7, -0], control2: [2.31, -0], to: [4.62, -0] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [7, -4], control2: [7, -1.32], to: [7, -2.64] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [9, -5], control2: [7.66, -4.33], to: [8.32, -4.66] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [5, -7], control2: [7.02, -5.99], to: [7.02, -5.99] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [8, -8], control2: [5.99, -7.33], to: [6.98, -7.66] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [5, -12], control2: [7.01, -9.32], to: [6.02, -10.64] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [6, -18], control2: [5.33, -13.98], to: [5.66, -15.96] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [2, -21], control2: [4.68, -18.99], to: [3.36, -19.98] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -21], control2: [1.34, -21], to: [0.68, -21] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [2, -3], control2: [-0.18556857, -14.319532], to: [0.34378347, -9.6248661] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -3], control2: [1.34, -3], to: [0.68, -3] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -0], control2: [0, -2.01], to: [0, -1.02] }, %) // CubicBezierAbsolute
|> bezierCurve(control1 = [7, -0], control2 = [2.31, -0], end = [4.62, -0] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [7, -4], control2 = [7, -1.32], end = [7, -2.64] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [9, -5], control2 = [7.66, -4.33], end = [8.32, -4.66] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [5, -7], control2 = [7.02, -5.99], end = [7.02, -5.99] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [8, -8], control2 = [5.99, -7.33], end = [6.98, -7.66] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [5, -12], control2 = [7.01, -9.32], end = [6.02, -10.64] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [6, -18], control2 = [5.33, -13.98], end = [5.66, -15.96] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [2, -21], control2 = [4.68, -18.99], end = [3.36, -19.98] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [0, -21], control2 = [1.34, -21], end = [0.68, -21] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [2, -3], control2 = [-0.18556857, -14.319532], end = [0.34378347, -9.6248661] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [0, -3], control2 = [1.34, -3], end = [0.68, -3] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [0, -0], control2 = [0, -2.01], end = [0, -1.02] ) // CubicBezierAbsolute
|> line(endAbsolute = [0, -0]) // MoveRelative
|> bezierCurve({ control1: [1, -4], control2: [0.33, -1.32], to: [0.66, -2.64]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [9, -4], control2: [3.64, -4], to: [6.28, -4]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [12, -1], control2: [9.99, -3.01], to: [10.98, -2.02]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [12, -3], control2: [12, -1.6600000000000001], to: [12, -2.3200000000000003]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [15, -4], control2: [12.99, -3.33], to: [13.98, -3.66]}, %) // CubicBezierRelative
|> bezierCurve({ control1: [12, -6], control2: [14.01, -4.66], to: [13.02, -5.32] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [2, -7], control2: [8.6740937, -6.4007116], to: [5.3398344, -6.7397532] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [9, -11], control2: [5.465, -8.98], to: [5.465, -8.98] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [9, -12], control2: [9, -11.33], to: [9, -11.66] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [1, -11], control2: [6.36, -11.67], to: [3.72, -11.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-2, -9], control2: [0.01, -10.34], to: [-0.98, -9.68] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-2, -4], control2: [-2, -7.35], to: [-2, -5.7] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [-4, -3], control2: [-2.66, -3.67], to: [-3.32, -3.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -2], control2: [-2.68, -2.67], to: [-1.36, -2.34] }, %) // CubicBezierAbsolute
|> bezierCurve({ control1: [0, -0], control2: [0, -1.34], to: [0, -0.68] }, %) // CubicBezierAbsolute
|> bezierCurve(control1 = [1, -4], control2 = [0.33, -1.32], end = [0.66, -2.64]) // CubicBezierRelative
|> bezierCurve(control1 = [9, -4], control2 = [3.64, -4], end = [6.28, -4]) // CubicBezierRelative
|> bezierCurve(control1 = [12, -1], control2 = [9.99, -3.01], end = [10.98, -2.02]) // CubicBezierRelative
|> bezierCurve(control1 = [12, -3], control2 = [12, -1.6600000000000001], end = [12, -2.3200000000000003]) // CubicBezierRelative
|> bezierCurve(control1 = [15, -4], control2 = [12.99, -3.33], end = [13.98, -3.66]) // CubicBezierRelative
|> bezierCurve(control1 = [12, -6], control2 = [14.01, -4.66], end = [13.02, -5.32] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [2, -7], control2 = [8.6740937, -6.4007116], end = [5.3398344, -6.7397532] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [9, -11], control2 = [5.465, -8.98], end = [5.465, -8.98] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [9, -12], control2 = [9, -11.33], end = [9, -11.66] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [1, -11], control2 = [6.36, -11.67], end = [3.72, -11.34] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [-2, -9], control2 = [0.01, -10.34], end = [-0.98, -9.68] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [-2, -4], control2 = [-2, -7.35], end = [-2, -5.7] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [-4, -3], control2 = [-2.66, -3.67], end = [-3.32, -3.34] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [0, -2], control2 = [-2.68, -2.67], end = [-1.36, -2.34] ) // CubicBezierAbsolute
|> bezierCurve(control1 = [0, -0], control2 = [0, -1.34], end = [0, -0.68] ) // CubicBezierAbsolute
|> close()

View File

@ -12,11 +12,11 @@ const length002 = depth + minClampingDistance
const sketch001 = startSketchOn(XZ)
|> startProfileAt([0, depth - templateGap], %)
|> xLine(length = length001, tag = $seg01)
|> arc({
angleEnd: 0,
angleStart: 90,
radius: radius - templateGap
}, %)
|> arc(
angleEnd = 0,
angleStart = 90,
radius = radius - templateGap
)
|> yLine(endAbsolute = -templateGap * 2 - (templateDiameter / 2), tag = $seg05)
|> xLine(endAbsolute = slateWidthHalf + templateThickness, tag = $seg04)
|> yLine(length = -length002, tag = $seg03)
@ -25,11 +25,11 @@ const sketch001 = startSketchOn(XZ)
|> yLine(length = segLen(seg03, %))
|> xLine(length = segLen(seg04, %))
|> yLine(length = segLen(seg05, %))
|> arc({
angleEnd: 90,
angleStart: 180,
radius: radius - templateGap
}, %)
|> arc(
angleEnd = 90,
angleStart = 180,
radius = radius - templateGap
)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
const extrude001 = extrude(sketch001, length = 5)

View File

@ -48,11 +48,11 @@ fn caster = (originStart) => {
const sketch002c = startSketchOn(sketch001c, face = 'START')
|> startProfileAt([-originStart[0], 2.2 + originStart[1]], %)
|> arc({
angle_start: 30,
angle_end: 330,
radius: 3.2 / 2
}, %)
|> arc(
angle_start = 30,
angle_end = 330,
radius = 3.2 / 2
)
|> close()
|> extrude(length = 3.1)
@ -378,17 +378,9 @@ const sketch017w = startSketchOn(plane002)
depth - 1 - (3.7 * cos(23 * pi() / 180)),
60.65 + 3.7 * sin(23 * pi() / 180) + 1.75 / 2
], %)
|> arc({
angleStart: -23,
angleEnd: 180 - 23,
radius: 7 / 2 + 2
}, %)
|> arc(angleStart = -23, angleEnd = 180 - 23, radius = 7 / 2 + 2)
|> angledLine(angle = -23 + 180, length = -1 )
|> arc({
angleStart: 180 - 23,
angleEnd: -23,
radius: 7 / 2 + 1
}, %)
|> arc(angleStart = 180 - 23, angleEnd = -23, radius = 7 / 2 + 1)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
const extrude017w = extrude(sketch017w, length = 1)
@ -398,17 +390,9 @@ const sketch018w = startSketchOn(plane002)
depth - 1 - (19.3 * cos(23 * pi() / 180)),
60.65 + 19.3 * sin(23 * pi() / 180) + 1.75 / 2
], %)
|> arc({
angleStart: -23,
angleEnd: 180 - 23,
radius: 7 / 2 + 2
}, %)
|> arc(angleStart = -23, angleEnd = 180 - 23, radius = 7 / 2 + 2)
|> angledLine(angle = -23 + 180, length = -1 )
|> arc({
angleStart: 180 - 23,
angleEnd: -23,
radius: 7 / 2 + 1
}, %)
|> arc(angleStart = 180 - 23, angleEnd = -23, radius = 7 / 2 + 1)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
const extrude018w = extrude(sketch018w, length = 1)
@ -627,17 +611,9 @@ const extrude002fl = extrude(sketch002fl, length = thickness)
// Bend
const sketch003fl = startSketchOn(planeXYfl)
|> startProfileAt([0 + thickness + bendRad+originStart[1], originStart[0]], %)
|> arc({
angleStart: 270,
angleEnd: 180,
radius: bendRad + thickness
}, %)
|> arc(angleStart = 270, angleEnd = 180, radius = bendRad + thickness)
|> xLine(length = thickness)
|> arc({
angleStart: 180,
angleEnd: 270,
radius: bendRad
}, %)
|> arc(angleStart = 180, angleEnd = 270, radius = bendRad)
|> yLine(length = -thickness)
|> close()
@ -853,17 +829,9 @@ const sketch003fr = startSketchOn(planeXYfr)
bendRad + originStart[1] + width - 2 - thickness - bendRad,
originStart[0] + bendRad + thickness
], %)
|> arc({
angleStart: 0,
angleEnd: -90,
radius: bendRad
}, %)
|> arc(angleStart = 0, angleEnd = -90, radius = bendRad)
|> yLine(length = -thickness)
|> arc({
angleStart: -90,
angleEnd: 0,
radius: bendRad + thickness
}, %)
|> arc(angleStart = -90, angleEnd = 0, radius = bendRad + thickness)
|> close()
const extrude003fr = extrude(sketch003fr, length = railHeight * 1.75)
@ -1093,17 +1061,9 @@ const sketch003rr = startSketchOn(planeXYrr)
bendRad + originStart[1] + width - 2-bendRad,
originStart[0]-bendRad
], %)
|> arc({
angleStart: 0,
angleEnd: 90,
radius: bendRad+thickness
}, %)
|> arc(angleStart = 0, angleEnd = 90, radius = bendRad+thickness)
|> yLine(length = -thickness)
|> arc({
angleStart: 90,
angleEnd: 0,
radius: bendRad
}, %)
|> arc(angleStart = 90, angleEnd = 0, radius = bendRad)
|> close()
const extrude003rr = extrude(sketch003rr, length = railHeight * 1.75)
@ -1332,17 +1292,9 @@ const sketch003rl = startSketchOn(planeXYrl)
bendRad + originStart[1] + thickness,
originStart[0]
], %)
|> arc({
angleStart: 90,
angleEnd: 180,
radius: bendRad
}, %)
|> arc(angleStart = 90, angleEnd = 180, radius = bendRad)
|> xLine(length = -thickness)
|> arc({
angleStart: 180,
angleEnd: 90,
radius: bendRad + thickness
}, %)
|> arc(angleStart = 180, angleEnd = 90, radius = bendRad + thickness)
|> close()
const extrude003rl = extrude(sketch003rl, length = railHeight * 1.75)

View File

@ -46,11 +46,11 @@ fn caster = (originStart) => {
const sketch002c = startSketchOn(sketch001c, face = 'START')
|> startProfileAt([-originStart[0], 2.2 + originStart[1]], %)
|> arc({
angle_start: 30,
angle_end: 330,
radius: 3.2 / 2
}, %)
|> arc(
angle_start = 30,
angle_end = 330,
radius = 3.2 / 2
)
|> close()
|> extrude(length = 3.1)
@ -368,17 +368,9 @@ const sketch017w = startSketchOn(plane002)
depth - 1 - (3.7 * cos(23 * pi() / 180)),
60.65 + 3.7 * sin(23 * pi() / 180) + 1.75 / 2
], %)
|> arc({
angleStart: -23,
angleEnd: 180 - 23,
radius: 7 / 2 + 2
}, %)
|> arc(angleStart = -23, angleEnd = 180 - 23, radius = 7 / 2 + 2)
|> angledLine(angle = -23 + 180, length = -1 )
|> arc({
angleStart: 180 - 23,
angleEnd: -23,
radius: 7 / 2 + 1
}, %)
|> arc(angleStart = 180 - 23, angleEnd = -23, radius = 7 / 2 + 1)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
const extrude017w = extrude(sketch017w, length = 1)
@ -388,17 +380,9 @@ const sketch018w = startSketchOn(plane002)
depth - 1 - (19.3 * cos(23 * pi() / 180)),
60.65 + 19.3 * sin(23 * pi() / 180) + 1.75 / 2
], %)
|> arc({
angleStart: -23,
angleEnd: 180 - 23,
radius: 7 / 2 + 2
}, %)
|> arc(angleStart = -23, angleEnd = 180 - 23, radius = 7 / 2 + 2)
|> angledLine(angle = -23 + 180, length = -1 )
|> arc({
angleStart: 180 - 23,
angleEnd: -23,
radius: 7 / 2 + 1
}, %)
|> arc(angleStart = 180 - 23, angleEnd = -23, radius = 7 / 2 + 1)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
const extrude018w = extrude(sketch018w, length = 1)
@ -628,17 +612,9 @@ const sketch003fl = startSketchOn(planeXYfl)
0 + thickness + bendRad + originStart[1],
originStart[0]
], %)
|> arc({
angleStart: 270,
angleEnd: 180,
radius: bendRad + thickness
}, %)
|> arc(angleStart = 270, angleEnd = 180, radius = bendRad + thickness)
|> xLine(length = thickness)
|> arc({
angleStart: 180,
angleEnd: 270,
radius: bendRad
}, %)
|> arc(angleStart = 180, angleEnd = 270, radius = bendRad)
|> yLine(length = -thickness)
|> close()
@ -761,17 +737,9 @@ const sketch003fr = startSketchOn(planeXYfr)
bendRad + originStart[1] + width - 2 - thickness - bendRad,
originStart[0] + bendRad + thickness
], %)
|> arc({
angleStart: 0,
angleEnd: -90,
radius: bendRad
}, %)
|> arc(angleStart = 0, angleEnd = -90, radius = bendRad)
|> yLine(length = -thickness)
|> arc({
angleStart: -90,
angleEnd: 0,
radius: bendRad + thickness
}, %)
|> arc(angleStart = -90, angleEnd = 0, radius = bendRad + thickness)
|> close()
const extrude003fr = extrude(sketch003fr, length = railHeight * 1.75)
@ -893,17 +861,9 @@ const sketch003rr = startSketchOn(planeXYrr)
bendRad + originStart[1] + width - 2 - bendRad,
originStart[0] - bendRad
], %)
|> arc({
angleStart: 0,
angleEnd: 90,
radius: bendRad + thickness
}, %)
|> arc(angleStart = 0, angleEnd = 90, radius = bendRad + thickness)
|> yLine(length = -thickness)
|> arc({
angleStart: 90,
angleEnd: 0,
radius: bendRad
}, %)
|> arc(angleStart = 90, angleEnd = 0, radius = bendRad)
|> close()
const extrude003rr = extrude(sketch003rr, length = railHeight * 1.75)
@ -1024,17 +984,9 @@ const sketch003rl = startSketchOn(planeXYrl)
bendRad + originStart[1] + thickness,
originStart[0]
], %)
|> arc({
angleStart: 90,
angleEnd: 180,
radius: bendRad
}, %)
|> arc(angleStart = 90, angleEnd = 180, radius = bendRad)
|> xLine(length = -thickness)
|> arc({
angleStart: 180,
angleEnd: 90,
radius: bendRad + thickness
}, %)
|> arc(angleStart = 180, angleEnd = 90, radius = bendRad + thickness)
|> close()
const extrude003rl = extrude(sketch003rl, length = railHeight * 1.75)

View File

@ -290,7 +290,7 @@ async fn optional_params() {
fn other_circle = (pos, radius, tag?) => {
sg = startSketchOn(XY)
|> startProfileAt(pos, %)
|> arc({angleEnd = 360, angleStart = 0, radius}, %)
|> arc(angleEnd = 360, angleStart = 0, radius = radius)
|> close()
|> extrude(length = 2)
@ -1191,11 +1191,12 @@ async fn kcl_test_plumbus_fillets() {
let code = r#"fn make_circle = (ext, face, pos, radius) => {
sg = startSketchOn(ext, face = face)
|> startProfileAt([pos[0] + radius, pos[1]], %)
|> arc({
|> arc(
angleEnd = 360,
angleStart = 0,
radius = radius
}, %, $arc1)
radius = radius,
tag = $arc1,
)
|> close()
return sg
@ -1769,11 +1770,11 @@ async fn kcl_test_extrude_custom_plane() {
async fn kcl_test_arc_error_same_start_end() {
let code = r#"startSketchOn(XY)
|> startProfileAt([10, 0], %)
|> arc({
angleStart: 180,
angleEnd: 180,
|> arc(
angleStart = 180,
angleEnd = 180,
radius = 1.5
}, %)
)
|> close()
|> patternCircular2d(
arcDegrees = 360,
@ -1784,11 +1785,9 @@ async fn kcl_test_arc_error_same_start_end() {
"#;
let result = execute_and_snapshot(code, None).await;
assert!(result.is_err());
assert_eq!(
result.err().unwrap().to_string(),
r#"type: KclErrorDetails { source_ranges: [SourceRange([55, 136, 0])], message: "Arc start and end angles must be different" }"#
);
let err = result.expect_err("Code should have failed due to end angle === start angle");
let err = err.as_kcl_error().unwrap();
assert_eq!(err.message(), "Arc start and end angles must be different");
}
#[tokio::test(flavor = "multi_thread")]

View File

@ -964,11 +964,7 @@ mod tests {
let snippet = arc_fn.to_autocomplete_snippet().unwrap();
assert_eq!(
snippet,
r#"arc({
angleStart = ${0:3.14},
angleEnd = ${1:3.14},
radius = ${2:3.14},
}, ${3:%})"#
r#"arc(${0:%}, angleStart = ${1:3.14}, angleEnd = ${2:3.14}, radius = ${3:3.14})"#
);
}

View File

@ -180,10 +180,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
)
.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?;
@ -298,23 +294,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
Ok(())
}
async fn set_units(
&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(
id_generator.next_uuid(),
source_range,
&ModelingCmd::from(mcmd::SetSceneUnits { unit: units.into() }),
)
.await?;
Ok(())
}
/// Re-run the command to apply the settings.
async fn reapply_settings(
&self,

View File

@ -1122,32 +1122,36 @@ fn artifacts_to_update(
let mut new_solid_ids = vec![id];
// Make sure we don't ever create a duplicate ID since merge_ids
// can't handle it.
let not_cmd_id = move |solid_id: &ArtifactId| *solid_id != id;
match response {
OkModelingCmdResponse::BooleanIntersection(intersection) => intersection
.extra_solid_ids
.iter()
.copied()
.map(ArtifactId::new)
.filter(not_cmd_id)
.for_each(|id| new_solid_ids.push(id)),
OkModelingCmdResponse::BooleanSubtract(subtract) => subtract
.extra_solid_ids
.iter()
.copied()
.map(ArtifactId::new)
.filter(not_cmd_id)
.for_each(|id| new_solid_ids.push(id)),
OkModelingCmdResponse::BooleanUnion(union) => union
.extra_solid_ids
.iter()
.copied()
.map(ArtifactId::new)
.filter(not_cmd_id)
.for_each(|id| new_solid_ids.push(id)),
_ => {}
}
let return_arr = new_solid_ids
.into_iter()
// Extra solid IDs may include the command's ID. Make sure we
// don't create a duplicate.
.filter(|solid_id| *solid_id != id)
.map(|solid_id| {
Artifact::CompositeSolid(CompositeSolid {
id: solid_id,

View File

@ -3,11 +3,7 @@ use std::collections::HashMap;
use async_recursion::async_recursion;
use indexmap::IndexMap;
use super::{
cad_op::Group,
kcl_value::TypeDef,
types::{PrimitiveType, CHECK_NUMERIC_TYPES},
};
use super::{cad_op::Group, kcl_value::TypeDef, types::PrimitiveType};
use crate::{
errors::{KclError, KclErrorDetails},
execution::{
@ -64,14 +60,6 @@ impl ExecutorContext {
if exec_state.mod_local.settings.update_from_annotation(annotation)? {
exec_state.mod_local.explicit_length_units = true;
}
let new_units = exec_state.length_unit();
self.engine
.set_units(
new_units.into(),
annotation.as_source_range(),
exec_state.id_generator(),
)
.await?;
} else {
exec_state.err(CompilationError::err(
annotation.as_source_range(),
@ -170,20 +158,23 @@ impl ExecutorContext {
self.exec_module_for_items(module_id, exec_state, source_range).await?;
for import_item in items {
// Extract the item from the module.
let item = exec_state
.stack()
.memory
let mem = &exec_state.stack().memory;
let mut value = mem
.get_from(&import_item.name.name, env_ref, import_item.into(), 0)
.map_err(|_err| {
KclError::UndefinedValue(KclErrorDetails {
.cloned();
let ty_name = format!("{}{}", memory::TYPE_PREFIX, import_item.name.name);
let mut ty = mem.get_from(&ty_name, env_ref, import_item.into(), 0).cloned();
if value.is_err() && ty.is_err() {
return Err(KclError::UndefinedValue(KclErrorDetails {
message: format!("{} is not defined in module", import_item.name.name),
source_ranges: vec![SourceRange::from(&import_item.name)],
})
})?
.clone();
// Check that the item is allowed to be imported.
if !module_exports.contains(&import_item.name.name) {
return Err(KclError::Semantic(KclErrorDetails {
}));
}
// Check that the item is allowed to be imported (in at least one namespace).
if value.is_ok() && !module_exports.contains(&import_item.name.name) {
value = Err(KclError::Semantic(KclErrorDetails {
message: format!(
"Cannot import \"{}\" from module because it is not exported. Add \"export\" before the definition to export it.",
import_item.name.name
@ -192,10 +183,22 @@ impl ExecutorContext {
}));
}
if ty.is_ok() && !module_exports.contains(&ty_name) {
ty = Err(KclError::Semantic(KclErrorDetails {
message: String::new(),
source_ranges: vec![],
}));
}
if value.is_err() && ty.is_err() {
return value.map(Option::Some);
}
// Add the item to the current module.
if let Ok(value) = value {
exec_state.mut_stack().add(
import_item.identifier().to_owned(),
item,
value,
SourceRange::from(&import_item.name),
)?;
@ -206,6 +209,21 @@ impl ExecutorContext {
.push(import_item.identifier().to_owned());
}
}
if let Ok(ty) = ty {
let ty_name = format!("{}{}", memory::TYPE_PREFIX, import_item.identifier());
// Add the item to the current module.
exec_state.mut_stack().add(
ty_name.clone(),
ty,
SourceRange::from(&import_item.name),
)?;
if let ItemVisibility::Export = import_stmt.visibility {
exec_state.mod_local.module_exports.push(ty_name);
}
}
}
}
ImportSelector::Glob(_) => {
let (env_ref, module_exports) =
@ -298,19 +316,20 @@ impl ExecutorContext {
value: TypeDef::RustRepr(t, props),
meta: vec![metadata],
};
let name_in_mem = format!("{}{}", memory::TYPE_PREFIX, ty.name.name);
exec_state
.mut_stack()
.add(
format!("{}{}", memory::TYPE_PREFIX, ty.name.name),
value,
metadata.source_range,
)
.add(name_in_mem.clone(), value, metadata.source_range)
.map_err(|_| {
KclError::Semantic(KclErrorDetails {
message: format!("Redefinition of type {}.", ty.name.name),
source_ranges: vec![metadata.source_range],
})
})?;
if let ItemVisibility::Export = ty.visibility {
exec_state.mod_local.module_exports.push(name_in_mem);
}
}
// Do nothing for primitive types, they get special treatment and their declarations are just for documentation.
annotations::Impl::Primitive => {}
@ -327,19 +346,20 @@ impl ExecutorContext {
),
meta: vec![metadata],
};
let name_in_mem = format!("{}{}", memory::TYPE_PREFIX, ty.name.name);
exec_state
.mut_stack()
.add(
format!("{}{}", memory::TYPE_PREFIX, ty.name.name),
value,
metadata.source_range,
)
.add(name_in_mem.clone(), value, metadata.source_range)
.map_err(|_| {
KclError::Semantic(KclErrorDetails {
message: format!("Redefinition of type {}.", ty.name.name),
source_ranges: vec![metadata.source_range],
})
})?;
if let ItemVisibility::Export = ty.visibility {
exec_state.mod_local.module_exports.push(name_in_mem);
}
}
None => {
return Err(KclError::Semantic(KclErrorDetails {
@ -485,7 +505,7 @@ impl ExecutorContext {
message: "Cannot import items from foreign modules".to_owned(),
source_ranges: vec![geom.source_range],
})),
ModuleRepr::Dummy => unreachable!(),
ModuleRepr::Dummy => unreachable!("Looking up {}, but it is still being interpreted", path),
};
exec_state.global.module_infos[&module_id].restore_repr(repr);
@ -559,10 +579,10 @@ impl ExecutorContext {
// It was an import cycle. Keep the original message.
err.override_source_ranges(vec![source_range])
} else {
// TODO would be great to have line/column for the underlying error here
KclError::Semantic(KclErrorDetails {
message: format!(
"Error loading imported file. Open it to view more details. {}: {}",
path,
"Error loading imported file ({path}). Open it to view more details.\n {}",
err.message()
),
source_ranges: vec![source_range],
@ -841,7 +861,10 @@ impl Node<MemberExpression> {
source_ranges: vec![self.clone().into()],
}))
}
(KclValue::MixedArray { value: arr, meta: _ }, Property::UInt(index)) => {
(
KclValue::MixedArray { value: arr, .. } | KclValue::HomArray { value: arr, .. },
Property::UInt(index),
) => {
let value_of_arr = arr.get(index);
if let Some(value) = value_of_arr {
Ok(value.to_owned())
@ -852,7 +875,7 @@ impl Node<MemberExpression> {
}))
}
}
(KclValue::MixedArray { .. }, p) => {
(KclValue::MixedArray { .. } | KclValue::HomArray { .. }, p) => {
let t = p.type_name();
let article = article_for(t);
Err(KclError::Semantic(KclErrorDetails {
@ -1019,7 +1042,7 @@ impl Node<BinaryExpression> {
BinaryOperator::Pow => KclValue::Number {
value: left.n.powf(right.n),
meta,
ty: NumericType::Unknown,
ty: exec_state.current_default_units(),
},
BinaryOperator::Neq => {
let (l, r, ty) = NumericType::combine_eq(left, right);
@ -1058,7 +1081,7 @@ impl Node<BinaryExpression> {
}
fn warn_on_unknown(&self, ty: &NumericType, verb: &str, exec_state: &mut ExecState) {
if *CHECK_NUMERIC_TYPES && ty == &NumericType::Unknown {
if ty == &NumericType::Unknown {
// TODO suggest how to fix this
exec_state.warn(CompilationError::err(
self.as_source_range(),
@ -1967,11 +1990,39 @@ fn assign_args_to_params(
for (index, param) in function_expression.params.iter().enumerate() {
if let Some(arg) = args.get(index) {
// Argument was provided.
if let Some(ty) = &param.type_ {
let value = arg
.value
.coerce(
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range).unwrap(),
exec_state,
)
.map_err(|e| {
let mut message = format!(
"Argument requires a value with type `{}`, but found {}",
ty.inner,
arg.value.human_friendly_type(),
);
if let Some(ty) = e.explicit_coercion {
// TODO if we have access to the AST for the argument we could choose which example to suggest.
message = format!("{message}\n\nYou may need to add information about the type of the argument, for example:\n using a numeric suffix: `42{ty}`\n or using type ascription: `foo(): number({ty})`");
}
KclError::Semantic(KclErrorDetails {
message,
source_ranges: vec![arg.source_range],
})
})?;
exec_state
.mut_stack()
.add(param.identifier.name.clone(), value, (&param.identifier).into())?;
} else {
exec_state.mut_stack().add(
param.identifier.name.clone(),
arg.value.clone(),
(&param.identifier).into(),
)?;
}
} else {
// Argument was not provided.
if let Some(ref default_val) = param.default_value {
@ -2139,6 +2190,34 @@ fn assign_args_to_params_kw(
Ok(())
}
fn coerce_result_type(
result: Result<Option<KclValue>, KclError>,
function_expression: NodeRef<'_, FunctionExpression>,
exec_state: &mut ExecState,
) -> Result<Option<KclValue>, KclError> {
if let Ok(Some(val)) = result {
if let Some(ret_ty) = &function_expression.return_type {
let ty = RuntimeType::from_parsed(ret_ty.inner.clone(), exec_state, ret_ty.as_source_range())
.map_err(|e| KclError::Semantic(e.into()))?;
let val = val.coerce(&ty, exec_state).map_err(|_| {
KclError::Semantic(KclErrorDetails {
message: format!(
"This function requires its result to be of type `{}`, but found {}",
ty.human_friendly_type(),
val.human_friendly_type(),
),
source_ranges: ret_ty.as_source_ranges(),
})
})?;
Ok(Some(val))
} else {
Ok(Some(val))
}
} else {
result
}
}
async fn call_user_defined_function(
args: Vec<Arg>,
memory: EnvironmentRef,
@ -2159,13 +2238,16 @@ async fn call_user_defined_function(
let result = ctx
.exec_block(&function_expression.body, exec_state, BodyType::Block)
.await;
let result = result.map(|_| {
let mut result = result.map(|_| {
exec_state
.stack()
.get(memory::RETURN_NAME, function_expression.as_source_range())
.ok()
.cloned()
});
result = coerce_result_type(result, function_expression, exec_state);
// Restore the previous memory.
exec_state.mut_stack().pop_env();
@ -2193,13 +2275,16 @@ async fn call_user_defined_function_kw(
let result = ctx
.exec_block(&function_expression.body, exec_state, BodyType::Block)
.await;
let result = result.map(|_| {
let mut result = result.map(|_| {
exec_state
.stack()
.get(memory::RETURN_NAME, function_expression.as_source_range())
.ok()
.cloned()
});
result = coerce_result_type(result, function_expression, exec_state);
// Restore the previous memory.
exec_state.mut_stack().pop_env();
@ -2695,6 +2780,27 @@ foo(x = { direction = [0, 0], origin = [0, 0]})
}
foo(x = { direction = [0, 0], origin = [0, 0]})
"#;
parse_execute(program).await.unwrap_err();
}
#[tokio::test(flavor = "multi_thread")]
async fn coerce_return() {
let program = r#"fn foo(): number(mm) {
return 42
}
a = foo()
"#;
parse_execute(program).await.unwrap();
let program = r#"fn foo(): number(mm) {
return { bar: 42 }
}
a = foo()
"#;
parse_execute(program).await.unwrap_err();

View File

@ -10,14 +10,13 @@ use serde::{Deserialize, Serialize};
use crate::{
errors::KclError,
execution::{types::NumericType, ArtifactId, ExecState, Metadata, TagEngineInfo, TagIdentifier, UnitLen},
execution::{
types::NumericType, ArtifactId, ExecState, ExecutorContext, Metadata, TagEngineInfo, TagIdentifier, UnitLen,
},
parsing::ast::types::{Node, NodeRef, TagDeclarator, TagNode},
std::{args::TyF64, sketch::PlaneData},
};
use super::ExecutorContext;
type Point2D = kcmc::shared::Point2d<f64>;
type Point3D = kcmc::shared::Point3d<f64>;
/// A geometry.
@ -265,7 +264,6 @@ pub struct Plane {
pub y_axis: Point3d,
/// The z-axis (normal).
pub z_axis: Point3d,
pub units: UnitLen,
#[serde(skip)]
pub meta: Vec<Metadata>,
}
@ -287,6 +285,8 @@ impl Plane {
x: 1.0,
y: 0.0,
z: 0.0,
// TODO axes must be normalized, so maybe these should all be count
// rather than mm?
units: UnitLen::Mm,
},
y_axis:
@ -483,7 +483,6 @@ impl Plane {
y_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
z_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
value: PlaneType::XY,
units: exec_state.length_unit(),
meta: vec![],
},
PlaneData::NegXY => Plane {
@ -494,7 +493,6 @@ impl Plane {
y_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
z_axis: Point3d::new(0.0, 0.0, -1.0, UnitLen::Mm),
value: PlaneType::XY,
units: exec_state.length_unit(),
meta: vec![],
},
PlaneData::XZ => Plane {
@ -505,7 +503,6 @@ impl Plane {
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
z_axis: Point3d::new(0.0, -1.0, 0.0, UnitLen::Mm),
value: PlaneType::XZ,
units: exec_state.length_unit(),
meta: vec![],
},
PlaneData::NegXZ => Plane {
@ -516,7 +513,6 @@ impl Plane {
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
z_axis: Point3d::new(0.0, 1.0, 0.0, UnitLen::Mm),
value: PlaneType::XZ,
units: exec_state.length_unit(),
meta: vec![],
},
PlaneData::YZ => Plane {
@ -527,7 +523,6 @@ impl Plane {
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
z_axis: Point3d::new(1.0, 0.0, 0.0, UnitLen::Mm),
value: PlaneType::YZ,
units: exec_state.length_unit(),
meta: vec![],
},
PlaneData::NegYZ => Plane {
@ -538,7 +533,6 @@ impl Plane {
y_axis: Point3d::new(0.0, 0.0, 1.0, UnitLen::Mm),
z_axis: Point3d::new(-1.0, 0.0, 0.0, UnitLen::Mm),
value: PlaneType::YZ,
units: exec_state.length_unit(),
meta: vec![],
},
PlaneData::Plane {
@ -556,7 +550,6 @@ impl Plane {
y_axis,
z_axis,
value: PlaneType::Custom,
units: exec_state.length_unit(),
meta: vec![],
}
}
@ -713,12 +706,6 @@ impl SketchSurface {
SketchSurface::Face(face) => face.z_axis,
}
}
pub(crate) fn units(&self) -> UnitLen {
match self {
SketchSurface::Plane(plane) => plane.units,
SketchSurface::Face(face) => face.units,
}
}
}
#[derive(Debug, Clone)]
@ -787,7 +774,8 @@ impl Sketch {
return Ok(Point2d::new(self.start.to[0], self.start.to[1], self.start.units));
};
Ok(path.get_to().into())
let to = path.get_base().to;
Ok(Point2d::new(to[0], to[1], path.get_base().units))
}
pub(crate) fn get_tangential_info_from_paths(&self) -> GetTangentialInfoFromPathsResult {
@ -829,6 +817,10 @@ impl Solid {
pub(crate) fn get_all_edge_cut_ids(&self) -> impl Iterator<Item = uuid::Uuid> + '_ {
self.edge_cuts.iter().map(|foc| foc.id())
}
pub(crate) fn height_in_mm(&self) -> f64 {
self.units.adjust_to(self.height, UnitLen::Mm).0
}
}
/// A fillet or a chamfer.
@ -889,28 +881,6 @@ pub struct Point2d {
pub units: UnitLen,
}
impl From<[TyF64; 2]> for Point2d {
fn from(p: [TyF64; 2]) -> Self {
Self {
x: p[0].n,
y: p[1].n,
units: p[0].ty.expect_length(),
}
}
}
impl From<Point2d> for [f64; 2] {
fn from(p: Point2d) -> Self {
[p.x, p.y]
}
}
impl From<Point2d> for Point2D {
fn from(p: Point2d) -> Self {
Self { x: p.x, y: p.y }
}
}
impl Point2d {
pub const ZERO: Self = Self {
x: 0.0,
@ -921,6 +891,18 @@ impl Point2d {
pub fn new(x: f64, y: f64, units: UnitLen) -> Self {
Self { x, y, units }
}
pub fn into_x(self) -> TyF64 {
TyF64::new(self.x, self.units.into())
}
pub fn into_y(self) -> TyF64 {
TyF64::new(self.y, self.units.into())
}
pub fn ignore_units(self) -> [f64; 2] {
[self.x, self.y]
}
}
#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Copy, ts_rs::TS, JsonSchema, Default)]
@ -968,9 +950,9 @@ impl From<Point3d> for Point3D {
impl From<Point3d> for kittycad_modeling_cmds::shared::Point3d<LengthUnit> {
fn from(p: Point3d) -> Self {
Self {
x: LengthUnit(p.x),
y: LengthUnit(p.y),
z: LengthUnit(p.z),
x: LengthUnit(p.units.adjust_to(p.x, UnitLen::Mm).0),
y: LengthUnit(p.units.adjust_to(p.y, UnitLen::Mm).0),
z: LengthUnit(p.units.adjust_to(p.z, UnitLen::Mm).0),
}
}
}
@ -1114,10 +1096,10 @@ pub enum Path {
/// Point 1 of the arc (base on the end of previous segment)
#[ts(type = "[number, number]")]
p1: [f64; 2],
/// Point 2 of the arc (interior kwarg)
/// Point 2 of the arc (interiorAbsolute kwarg)
#[ts(type = "[number, number]")]
p2: [f64; 2],
/// Point 3 of the arc (end kwarg)
/// Point 3 of the arc (endAbsolute kwarg)
#[ts(type = "[number, number]")]
p3: [f64; 2],
},
@ -1318,9 +1300,9 @@ impl Path {
ccw: *ccw,
},
Path::ArcThreePoint { p1, p2, p3, .. } => {
let circle_center = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]);
let circle = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]);
GetTangentialInfoFromPathsResult::Arc {
center: circle_center.center,
center: circle.center,
ccw: crate::std::utils::is_points_ccw(&[*p1, *p2, *p3]) > 0,
}
}
@ -1332,14 +1314,13 @@ impl Path {
radius: *radius,
},
Path::CircleThreePoint { p1, p2, p3, .. } => {
let circle_center = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]);
let radius = linear_distance(&[circle_center.center[0], circle_center.center[1]], p1);
let center_point = [circle_center.center[0], circle_center.center[1]];
let circle = crate::std::utils::calculate_circle_from_3_points([*p1, *p2, *p3]);
let center_point = [circle.center[0], circle.center[1]];
GetTangentialInfoFromPathsResult::Circle {
center: center_point,
// Note: a circle is always ccw regardless of the order of points
ccw: true,
radius,
radius: circle.radius,
}
}
Path::ToPoint { .. } | Path::Horizontal { .. } | Path::AngledLineTo { .. } | Path::Base { .. } => {

View File

@ -18,16 +18,6 @@ use crate::{
CompilationError, SourceRange,
};
lazy_static::lazy_static! {
pub(crate) static ref CHECK_NUMERIC_TYPES: bool = {
let env_var = std::env::var("ZOO_NUM_TYS");
let Ok(env_var) = env_var else {
return false;
};
!env_var.is_empty()
};
}
#[derive(Debug, Clone, PartialEq)]
pub enum RuntimeType {
Primitive(PrimitiveType),
@ -62,10 +52,18 @@ impl RuntimeType {
RuntimeType::Primitive(PrimitiveType::Solid)
}
pub fn helix() -> Self {
RuntimeType::Primitive(PrimitiveType::Helix)
}
pub fn plane() -> Self {
RuntimeType::Primitive(PrimitiveType::Plane)
}
pub fn bool() -> Self {
RuntimeType::Primitive(PrimitiveType::Boolean)
}
pub fn string() -> Self {
RuntimeType::Primitive(PrimitiveType::String)
}
@ -90,6 +88,10 @@ impl RuntimeType {
))))
}
pub fn known_length(len: UnitLen) -> Self {
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Known(UnitType::Length(len))))
}
pub fn angle() -> Self {
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Known(UnitType::Angle(
UnitAngle::Unknown,
@ -366,6 +368,7 @@ impl fmt::Display for PrimitiveType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PrimitiveType::Number(NumericType::Known(unit)) => write!(f, "number({unit})"),
PrimitiveType::Number(NumericType::Unknown) => write!(f, "number(unknown units)"),
PrimitiveType::Number(_) => write!(f, "number"),
PrimitiveType::String => write!(f, "string"),
PrimitiveType::Boolean => write!(f, "bool"),
@ -423,13 +426,61 @@ impl NumericType {
NumericType::Known(UnitType::Angle(UnitAngle::Degrees))
}
/// Combine two types when we expect them to be equal.
pub fn expect_default_length(&self) -> Self {
match self {
NumericType::Default { len, .. } => NumericType::Known(UnitType::Length(*len)),
_ => unreachable!(),
}
}
pub fn expect_default_angle(&self) -> Self {
match self {
NumericType::Default { angle, .. } => NumericType::Known(UnitType::Angle(*angle)),
_ => unreachable!(),
}
}
/// Combine two types when we expect them to be equal, erring on the side of less coercion. To be
/// precise, only adjusting one number or the other when they are of known types.
///
/// This combinator function is suitable for comparisons or arithmetic where uncertainty should
/// be handled by the user.
pub fn combine_eq(a: TyF64, b: TyF64) -> (f64, f64, NumericType) {
use NumericType::*;
match (a.ty, b.ty) {
(at, bt) if at == bt => (a.n, b.n, at),
(at, Any) => (a.n, b.n, at),
(Any, bt) => (a.n, b.n, bt),
(t @ Known(UnitType::Length(l1)), Known(UnitType::Length(l2))) => (a.n, l2.adjust_to(b.n, l1).0, t),
(t @ Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2))) => (a.n, a2.adjust_to(b.n, a1).0, t),
(Known(UnitType::Count), Default { .. }) | (Default { .. }, Known(UnitType::Count)) => {
(a.n, b.n, Known(UnitType::Count))
}
(t @ Known(UnitType::Length(l1)), Default { len: l2, .. }) if l1 == l2 => (a.n, b.n, t),
(Default { len: l1, .. }, t @ Known(UnitType::Length(l2))) if l1 == l2 => (a.n, b.n, t),
(t @ Known(UnitType::Angle(a1)), Default { angle: a2, .. }) if a1 == a2 => (a.n, b.n, t),
(Default { angle: a1, .. }, t @ Known(UnitType::Angle(a2))) if a1 == a2 => (a.n, b.n, t),
_ => (a.n, b.n, Unknown),
}
}
/// Combine two types when we expect them to be equal, erring on the side of more coercion. Including adjusting when
/// we are certain about only one type.
///
/// This combinator function is suitable for situations where the user would almost certainly want the types to be
/// coerced together, for example two arguments to the same function or two numbers in an array being used as a point.
///
/// Prefer to use `combine_eq` if possible since using that prioritises correctness over ergonomics.
pub fn combine_eq_coerce(a: TyF64, b: TyF64) -> (f64, f64, NumericType) {
use NumericType::*;
match (a.ty, b.ty) {
(at, bt) if at == bt => (a.n, b.n, at),
(at, Any) => (a.n, b.n, at),
(Any, bt) => (a.n, b.n, bt),
(Default { .. }, Default { .. }) | (_, Unknown) | (Unknown, _) => (a.n, b.n, Unknown),
// Known types and compatible, but needs adjustment.
@ -454,12 +505,9 @@ impl NumericType {
pub fn combine_eq_array(input: &[TyF64]) -> (Vec<f64>, NumericType) {
use NumericType::*;
let mut result = input.iter().map(|t| t.n).collect();
let result = input.iter().map(|t| t.n).collect();
let mut ty = Any;
// Invariant mismatch is true => ty is fully known
let mut mismatch = false;
for i in input {
if i.ty == Any || ty == i.ty {
continue;
@ -471,58 +519,24 @@ impl NumericType {
}
(_, Unknown) | (Default { .. }, Default { .. }) => return (result, Unknown),
// Known types and compatible, but needs adjustment.
(Known(UnitType::Length(_)), Known(UnitType::Length(_)))
| (Known(UnitType::Angle(_)), Known(UnitType::Angle(_))) => {
mismatch = true;
}
// Known but incompatible.
(Known(_), Known(_)) => return (result, Unknown),
// Known and unknown, no adjustment for counting numbers.
(Known(UnitType::Count), Default { .. }) | (Default { .. }, Known(UnitType::Count)) => {
ty = Known(UnitType::Count);
}
(Known(UnitType::Length(l1)), Default { len: l2, .. }) => {
mismatch |= l1 != l2;
}
(Known(UnitType::Angle(a1)), Default { angle: a2, .. }) => {
mismatch |= a1 != a2;
}
(Known(UnitType::Length(l1)), Default { len: l2, .. }) if l1 == l2 => {}
(Known(UnitType::Angle(a1)), Default { angle: a2, .. }) if a1 == a2 => {}
(Default { len: l1, .. }, Known(UnitType::Length(l2))) => {
mismatch |= l1 != l2;
(Default { len: l1, .. }, Known(UnitType::Length(l2))) if l1 == l2 => {
ty = Known(UnitType::Length(*l2));
}
(Default { angle: a1, .. }, Known(UnitType::Angle(a2))) => {
mismatch |= a1 != a2;
(Default { angle: a1, .. }, Known(UnitType::Angle(a2))) if a1 == a2 => {
ty = Known(UnitType::Angle(*a2));
}
(Unknown, _) | (_, Any) => unreachable!(),
_ => return (result, Unknown),
}
}
if !mismatch {
return (result, ty);
}
result = result
.into_iter()
.zip(input)
.map(|(n, i)| match (&ty, &i.ty) {
(Known(UnitType::Length(l1)), Known(UnitType::Length(l2)) | Default { len: l2, .. }) => {
l2.adjust_to(n, *l1).0
}
(Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2)) | Default { angle: a2, .. }) => {
a2.adjust_to(n, *a1).0
}
_ => unreachable!(),
})
.collect();
(result, ty)
}
@ -530,11 +544,11 @@ impl NumericType {
pub fn combine_mul(a: TyF64, b: TyF64) -> (f64, f64, NumericType) {
use NumericType::*;
match (a.ty, b.ty) {
(at @ Default { .. }, bt @ Default { .. }) if at != bt => (a.n, b.n, Unknown),
(at @ Default { .. }, bt @ Default { .. }) if at == bt => (a.n, b.n, at),
(Default { .. }, Default { .. }) => (a.n, b.n, Unknown),
(Known(UnitType::Count), bt) => (a.n, b.n, bt),
(at, Known(UnitType::Count)) => (a.n, b.n, at),
(Default { .. }, bt) => (a.n, b.n, bt),
(at, Default { .. }) => (a.n, b.n, at),
(at @ Known(_), Default { .. }) | (Default { .. }, at @ Known(_)) => (a.n, b.n, at),
(Any, Any) => (a.n, b.n, Any),
_ => (a.n, b.n, Unknown),
}
@ -548,18 +562,7 @@ impl NumericType {
(at, bt) if at == bt => (a.n, b.n, Known(UnitType::Count)),
(Default { .. }, Default { .. }) => (a.n, b.n, Unknown),
(at, Known(UnitType::Count) | Any) => (a.n, b.n, at),
(Known(UnitType::Length(l1)), Known(UnitType::Length(l2))) => {
(a.n, l2.adjust_to(b.n, l1).0, Known(UnitType::Count))
}
(Known(UnitType::Angle(a1)), Known(UnitType::Angle(a2))) => {
(a.n, a2.adjust_to(b.n, a1).0, Known(UnitType::Count))
}
(Default { len: l1, .. }, Known(UnitType::Length(l2))) => {
(l1.adjust_to(a.n, l2).0, b.n, Known(UnitType::Count))
}
(Default { angle: a1, .. }, Known(UnitType::Angle(a2))) => {
(a1.adjust_to(a.n, a2).0, b.n, Known(UnitType::Count))
}
(at @ Known(_), Default { .. }) => (a.n, b.n, at),
(Known(UnitType::Count), _) => (a.n, b.n, Known(UnitType::Count)),
_ => (a.n, b.n, Unknown),
}
@ -604,9 +607,18 @@ impl NumericType {
}
}
fn is_unknown(&self) -> bool {
matches!(
self,
NumericType::Unknown
| NumericType::Known(UnitType::Angle(UnitAngle::Unknown))
| NumericType::Known(UnitType::Length(UnitLen::Unknown))
)
}
fn example_ty(&self) -> Option<String> {
match self {
Self::Known(t) => Some(t.to_string()),
Self::Known(t) if !self.is_unknown() => Some(t.to_string()),
Self::Default { len, .. } => Some(len.to_string()),
_ => None,
}
@ -617,10 +629,6 @@ impl NumericType {
return Err(val.into());
};
if !*CHECK_NUMERIC_TYPES {
return Ok(val.clone());
}
if ty.subtype(self) {
return Ok(KclValue::Number {
value: *value,
@ -771,10 +779,10 @@ pub enum UnitLen {
}
impl UnitLen {
fn adjust_to(self, value: f64, to: UnitLen) -> (f64, UnitLen) {
pub fn adjust_to(self, value: f64, to: UnitLen) -> (f64, UnitLen) {
use UnitLen::*;
if !*CHECK_NUMERIC_TYPES || self == to {
if self == to {
return (value, to);
}
@ -894,15 +902,11 @@ pub enum UnitAngle {
}
impl UnitAngle {
fn adjust_to(self, value: f64, to: UnitAngle) -> (f64, UnitAngle) {
pub fn adjust_to(self, value: f64, to: UnitAngle) -> (f64, UnitAngle) {
use std::f64::consts::PI;
use UnitAngle::*;
if !*CHECK_NUMERIC_TYPES {
return (value, to);
}
if to == Unknown {
return (value, self);
}
@ -1053,8 +1057,6 @@ impl KclValue {
y_axis,
z_axis,
value: super::PlaneType::Uninit,
// TODO use length unit from origin
units: exec_state.length_unit(),
meta: meta.clone(),
};
@ -1948,10 +1950,6 @@ mod test {
assert_coerce_results(&unknown, &NumericType::Any.into(), &unknown, &mut exec_state);
assert_coerce_results(&default, &NumericType::Any.into(), &default, &mut exec_state);
if !*CHECK_NUMERIC_TYPES {
return;
}
assert_eq!(
default
.coerce(
@ -2064,20 +2062,14 @@ u = min(3rad, 4in)
"#;
let result = parse_execute(program).await.unwrap();
if *CHECK_NUMERIC_TYPES {
assert_eq!(result.exec_state.errors().len(), 3);
} else {
assert!(result.exec_state.errors().is_empty());
}
assert_eq!(result.exec_state.errors().len(), 5);
assert_value_and_type("a", &result, 9.0, NumericType::default());
assert_value_and_type("b", &result, 3.0, NumericType::default());
assert_value_and_type("c", &result, 13.0, NumericType::mm());
assert_value_and_type("d", &result, 13.0, NumericType::mm());
assert_value_and_type("e", &result, 13.0, NumericType::mm());
if *CHECK_NUMERIC_TYPES {
assert_value_and_type("f", &result, 5.0, NumericType::mm());
}
assert_value_and_type("g", &result, 20.0, NumericType::default());
assert_value_and_type("h", &result, 20.0, NumericType::mm());
@ -2087,16 +2079,14 @@ u = min(3rad, 4in)
assert_value_and_type("l", &result, 0.0, NumericType::default());
assert_value_and_type("m", &result, 2.0, NumericType::count());
if *CHECK_NUMERIC_TYPES {
assert_value_and_type("n", &result, 127.0, NumericType::count());
}
assert_value_and_type("o", &result, 1.0, NumericType::Unknown);
assert_value_and_type("n", &result, 5.0, NumericType::Unknown);
assert_value_and_type("o", &result, 1.0, NumericType::mm());
assert_value_and_type("p", &result, 1.0, NumericType::count());
assert_value_and_type("q", &result, 2.0, NumericType::Known(UnitType::Length(UnitLen::Inches)));
assert_value_and_type("r", &result, 0.0, NumericType::default());
assert_value_and_type("s", &result, -42.0, NumericType::mm());
assert_value_and_type("t", &result, 3.0, NumericType::Known(UnitType::Length(UnitLen::Inches)));
assert_value_and_type("t", &result, 3.0, NumericType::Unknown);
assert_value_and_type("u", &result, 3.0, NumericType::Unknown);
}
@ -2110,7 +2100,24 @@ b = 180 / PI * a + 360
let result = parse_execute(program).await.unwrap();
assert_value_and_type("a", &result, 1.0, NumericType::radians());
// TODO type is not ideal
assert_value_and_type("b", &result, 417.0, NumericType::radians());
assert_value_and_type("b", &result, 417.0, NumericType::Unknown);
}
#[tokio::test(flavor = "multi_thread")]
async fn cos_coercions() {
let program = r#"
a = cos(toRadians(30))
b = 3 / a
c = cos(30deg)
d = cos(30)
"#;
let result = parse_execute(program).await.unwrap();
assert_eq!(result.exec_state.errors().len(), 1);
assert_value_and_type("a", &result, 1.0, NumericType::count());
assert_value_and_type("b", &result, 3.0, NumericType::default());
assert_value_and_type("c", &result, 1.0, NumericType::count());
assert_value_and_type("d", &result, 0.0, NumericType::count());
}
}

View File

@ -1643,11 +1643,7 @@ sphere = startSketchOn(XZ)
0 - 0.05
], %)
|> line(end = [sphereDia - 0.1, 0])
|> arc({
angle_start: 0,
angle_end: -180,
radius: sphereDia / 2 - 0.05
}, %)
|> arc(angle_start = 0, angle_end = -180, radius = sphereDia / 2 - 0.05)
|> close()
|> revolve({ axis = X }, %)
|> patternCircular3d(
@ -1706,7 +1702,7 @@ outsideRevolve = startSketchOn(XZ)
tower_lsp::lsp_types::Range {
start: tower_lsp::lsp_types::Position { line: 0, character: 0 },
end: tower_lsp::lsp_types::Position {
line: 60,
line: 56,
character: 29
}
}
@ -1743,11 +1739,7 @@ sphere = startSketchOn(XZ)
0 - 0.05
], %)
|> line(end = [sphereDia - 0.1, 0])
|> arc({
angle_start = 0,
angle_end = -180,
radius = sphereDia / 2 - 0.05
}, %)
|> arc(angle_start = 0, angle_end = -180, radius = sphereDia / 2 - 0.05)
|> close()
|> revolve({ axis = X }, %)
|> patternCircular3d(

View File

@ -90,6 +90,7 @@ pub(crate) fn read_std(mod_name: &str) -> Option<&'static str> {
"math" => Some(include_str!("../std/math.kcl")),
"sketch" => Some(include_str!("../std/sketch.kcl")),
"turns" => Some(include_str!("../std/turns.kcl")),
"types" => Some(include_str!("../std/types.kcl")),
_ => None,
}
}

View File

@ -1,7 +1,7 @@
use sha2::{Digest as DigestTrait, Sha256};
use crate::parsing::ast::types::{
Annotation, ArrayExpression, ArrayRangeExpression, Ascription, BinaryExpression, BinaryPart, BodyItem,
Annotation, ArrayExpression, ArrayRangeExpression, AscribedExpression, BinaryExpression, BinaryPart, BodyItem,
CallExpression, CallExpressionKw, DefaultParamVal, ElseIf, Expr, ExpressionStatement, FunctionExpression,
Identifier, IfExpression, ImportItem, ImportSelector, ImportStatement, ItemVisibility, KclNone, LabelledExpression,
Literal, LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Name, ObjectExpression, ObjectProperty,
@ -464,7 +464,7 @@ impl LabelledExpression {
});
}
impl Ascription {
impl AscribedExpression {
compute_digest!(|slf, hasher| {
hasher.update(slf.expr.compute_digest());
hasher.update(slf.ty.compute_digest());

View File

@ -450,7 +450,6 @@ impl Program {
for item in &self.body {
let r = item.comment_range();
eprintln!("item {r:?}");
if pos >= r.0 && pos < r.1 {
return true;
}
@ -820,7 +819,7 @@ pub enum Expr {
UnaryExpression(BoxNode<UnaryExpression>),
IfExpression(BoxNode<IfExpression>),
LabelledExpression(BoxNode<LabelledExpression>),
AscribedExpression(BoxNode<Ascription>),
AscribedExpression(BoxNode<AscribedExpression>),
None(Node<KclNone>),
}
@ -1093,7 +1092,7 @@ impl LabelledExpression {
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type")]
pub struct Ascription {
pub struct AscribedExpression {
pub expr: Expr,
pub ty: Node<Type>,
@ -1102,12 +1101,12 @@ pub struct Ascription {
pub digest: Option<Digest>,
}
impl Ascription {
pub(crate) fn new(expr: Expr, ty: Node<Type>) -> Node<Ascription> {
impl AscribedExpression {
pub(crate) fn new(expr: Expr, ty: Node<Type>) -> Node<AscribedExpression> {
let start = expr.start();
let end = ty.end;
let module_id = expr.module_id();
Node::new(Ascription { expr, ty, digest: None }, start, end, module_id)
Node::new(AscribedExpression { expr, ty, digest: None }, start, end, module_id)
}
}
@ -3081,7 +3080,7 @@ impl PipeExpression {
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type")]
#[serde(tag = "p_type")]
pub enum PrimitiveType {
/// A string type.
String,

View File

@ -14,7 +14,7 @@ use winnow::{
};
use super::{
ast::types::{Ascription, ImportPath, LabelledExpression},
ast::types::{AscribedExpression, ImportPath, LabelledExpression},
token::{NumericSuffix, RESERVED_WORDS},
DeprecationKind,
};
@ -530,13 +530,6 @@ pub(crate) fn unsigned_number_literal(i: &mut TokenSlice) -> PResult<Node<Litera
CompilationError::fatal(token.as_source_range(), format!("Invalid float: {}", token.value))
})?;
if token.numeric_suffix().is_some() {
ParseContext::warn(CompilationError::err(
(&token).into(),
"Unit of Measure suffixes are experimental and currently do nothing.",
));
}
Ok((
LiteralValue::Number {
value,
@ -2015,9 +2008,7 @@ fn expression_but_not_pipe(i: &mut TokenSlice) -> PResult<Expr> {
let ty = opt((colon, opt(whitespace), argument_type)).parse_next(i)?;
if let Some((_, _, ty)) = ty {
ParseContext::warn(CompilationError::err((&ty).into(), "Type ascription is experimental."));
expr = Expr::AscribedExpression(Box::new(Ascription::new(expr, ty)))
expr = Expr::AscribedExpression(Box::new(AscribedExpression::new(expr, ty)))
}
let label = opt(label).parse_next(i)?;
match label {
@ -2811,13 +2802,6 @@ fn primitive_type(i: &mut TokenSlice) -> PResult<Node<PrimitiveType>> {
let mut result = Node::new(PrimitiveType::Boolean, ident.start, ident.end, ident.module_id);
result.inner = PrimitiveType::primitive_from_str(&ident.name, suffix).unwrap_or(PrimitiveType::Named(ident));
if suffix.is_some() {
ParseContext::warn(CompilationError::err(
result.as_source_range(),
"Unit of Measure types are experimental and currently do nothing.",
));
}
Ok(result)
}
@ -4532,19 +4516,19 @@ export fn cos(num: number(rad)): number(_) {}"#;
fn fn_decl_uom_ty() {
let some_program_string = r#"fn foo(x: number(mm)): number(_) { return 1 }"#;
let (_, errs) = assert_no_fatal(some_program_string);
assert_eq!(errs.len(), 2);
assert!(errs.is_empty(), "Expected no errors, found: {errs:?}");
}
#[test]
fn error_underscore() {
let (_, errs) = assert_no_fatal("_foo(_blah, _)");
assert_eq!(errs.len(), 3, "found: {:#?}", errs);
assert_eq!(errs.len(), 3, "found: {errs:#?}");
}
#[test]
fn error_type_ascription() {
let (_, errs) = assert_no_fatal("a + b: number");
assert_eq!(errs.len(), 1, "found: {:#?}", errs);
assert!(errs.is_empty());
}
#[test]
@ -5326,17 +5310,6 @@ mod snapshot_tests {
c: 3
}"
);
snapshot_test!(
ba,
r#"
sketch001 = startSketchOn('XY')
// |> arc({
// angleEnd: 270,
// angleStart: 450,
// }, %)
|> startProfileAt(%)
"#
);
snapshot_test!(
bb,
r#"

Some files were not shown because too many files have changed in this diff Show More