diff --git a/docs/kcl/helix.md b/docs/kcl/helix.md new file mode 100644 index 000000000..164c856bb --- /dev/null +++ b/docs/kcl/helix.md @@ -0,0 +1,306 @@ +--- +title: "helix" +excerpt: "Create a helix on a cylinder." +layout: manual +--- + +Create a helix on a cylinder. + + + +```js +helix(data: HelixData, extrude_group: ExtrudeGroup) -> ExtrudeGroup +``` + +### Examples + +```js +const part001 = startSketchOn('XY') + |> circle([5, 5], 10, %) + |> extrude(10, %) + |> helix({ revolutions: 16, angle_start: 0 }, %) +``` + +### Arguments + +* `data`: `HelixData` - Data for helices. (REQUIRED) +```js +{ + // Start angle (in degrees). + angle_start: number, + // Is the helix rotation counter clockwise? The default is `false`. + ccw: string, + // Length of the helix. If this argument is not provided, the height of the extrude group is used. + length: number, + // Number of revolutions. + revolutions: number, +} +``` +* `extrude_group`: `ExtrudeGroup` - An extrude group is a collection of extrude surfaces. (REQUIRED) +```js +{ + // The id of the extrusion end cap + endCapId: uuid, + // The height of the extrude group. + height: number, + // The id of the extrude group. + id: uuid, + // The position of the extrude group. + position: [number, number, number], + // The rotation of the extrude group. + rotation: [number, number, number, number], + // The sketch group paths. + sketchGroupValues: [{ + // The from point. + from: [number, number], + // The name of the path. + name: string, + // The to point. + to: [number, number], + type: "ToPoint", +} | +{ + // arc's direction + ccw: string, + // the arc's center + center: [number, number], + // The from point. + from: [number, number], + // The name of the path. + name: string, + // The to point. + to: [number, number], + type: "TangentialArcTo", +} | +{ + // The from point. + from: [number, number], + // The name of the path. + name: string, + // The to point. + to: [number, number], + type: "TangentialArc", +} | +{ + // The from point. + from: [number, number], + // The name of the path. + name: string, + // The to point. + to: [number, number], + type: "Horizontal", + // The x coordinate. + x: number, +} | +{ + // The from point. + from: [number, number], + // The name of the path. + name: string, + // The to point. + to: [number, number], + type: "AngledLineTo", + // The x coordinate. + x: number, + // The y coordinate. + y: number, +} | +{ + // The from point. + from: [number, number], + // The name of the path. + name: string, + // The to point. + to: [number, number], + type: "Base", +}], + // The id of the extrusion start cap + startCapId: uuid, + // The extrude surfaces. + value: [{ + // The face id for the extrude plane. + faceId: uuid, + // The id of the geometry. + id: uuid, + // The name. + name: string, + // The position. + position: [number, number, number], + // The rotation. + rotation: [number, number, number, number], + // The source range. + sourceRange: [number, number], + type: "extrudePlane", +} | +{ + // The face id for the extrude plane. + faceId: uuid, + // The id of the geometry. + id: uuid, + // The name. + name: string, + // The position. + position: [number, number, number], + // The rotation. + rotation: [number, number, number, number], + // The source range. + sourceRange: [number, number], + type: "extrudeArc", +}], + // The x-axis of the extrude group base plane in the 3D space + xAxis: { + x: number, + y: number, + z: number, +}, + // The y-axis of the extrude group base plane in the 3D space + yAxis: { + x: number, + y: number, + z: number, +}, + // The z-axis of the extrude group base plane in the 3D space + zAxis: { + x: number, + y: number, + z: number, +}, +} +``` + +### Returns + +`ExtrudeGroup` - An extrude group is a collection of extrude surfaces. +```js +{ + // The id of the extrusion end cap + endCapId: uuid, + // The height of the extrude group. + height: number, + // The id of the extrude group. + id: uuid, + // The position of the extrude group. + position: [number, number, number], + // The rotation of the extrude group. + rotation: [number, number, number, number], + // The sketch group paths. + sketchGroupValues: [{ + // The from point. + from: [number, number], + // The name of the path. + name: string, + // The to point. + to: [number, number], + type: "ToPoint", +} | +{ + // arc's direction + ccw: string, + // the arc's center + center: [number, number], + // The from point. + from: [number, number], + // The name of the path. + name: string, + // The to point. + to: [number, number], + type: "TangentialArcTo", +} | +{ + // The from point. + from: [number, number], + // The name of the path. + name: string, + // The to point. + to: [number, number], + type: "TangentialArc", +} | +{ + // The from point. + from: [number, number], + // The name of the path. + name: string, + // The to point. + to: [number, number], + type: "Horizontal", + // The x coordinate. + x: number, +} | +{ + // The from point. + from: [number, number], + // The name of the path. + name: string, + // The to point. + to: [number, number], + type: "AngledLineTo", + // The x coordinate. + x: number, + // The y coordinate. + y: number, +} | +{ + // The from point. + from: [number, number], + // The name of the path. + name: string, + // The to point. + to: [number, number], + type: "Base", +}], + // The id of the extrusion start cap + startCapId: uuid, + // The extrude surfaces. + value: [{ + // The face id for the extrude plane. + faceId: uuid, + // The id of the geometry. + id: uuid, + // The name. + name: string, + // The position. + position: [number, number, number], + // The rotation. + rotation: [number, number, number, number], + // The source range. + sourceRange: [number, number], + type: "extrudePlane", +} | +{ + // The face id for the extrude plane. + faceId: uuid, + // The id of the geometry. + id: uuid, + // The name. + name: string, + // The position. + position: [number, number, number], + // The rotation. + rotation: [number, number, number, number], + // The source range. + sourceRange: [number, number], + type: "extrudeArc", +}], + // The x-axis of the extrude group base plane in the 3D space + xAxis: { + x: number, + y: number, + z: number, +}, + // The y-axis of the extrude group base plane in the 3D space + yAxis: { + x: number, + y: number, + z: number, +}, + // The z-axis of the extrude group base plane in the 3D space + zAxis: { + x: number, + y: number, + z: number, +}, +} +``` + + + diff --git a/docs/kcl/index.md b/docs/kcl/index.md index f395e92e2..3694d6f40 100644 --- a/docs/kcl/index.md +++ b/docs/kcl/index.md @@ -34,6 +34,7 @@ layout: manual * [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge) * [`getOppositeEdge`](kcl/getOppositeEdge) * [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge) +* [`helix`](kcl/helix) * [`hole`](kcl/hole) * [`import`](kcl/import) * [`lastSegX`](kcl/lastSegX) diff --git a/docs/kcl/std.json b/docs/kcl/std.json index 575d5c244..58e5397a7 100644 --- a/docs/kcl/std.json +++ b/docs/kcl/std.json @@ -28956,6 +28956,1567 @@ "const part001 = startSketchOn('XY')\n |> startProfileAt([0, 0], %)\n |> line([0, 10], %, \"thing\")\n |> line([10, 0], %, \"thing1\")\n |> line([0, -10], %, \"thing2\")\n |> close(%)\n |> extrude(10, %)\n |> fillet({\n radius: 2,\n tags: [getPreviousAdjacentEdge(\"thing2\", %)]\n }, %)" ] }, + { + "name": "helix", + "summary": "Create a helix on a cylinder.", + "description": "", + "tags": [], + "args": [ + { + "name": "data", + "type": "HelixData", + "schema": { + "description": "Data for helices.", + "type": "object", + "required": [ + "angle_start", + "revolutions" + ], + "properties": { + "angle_start": { + "description": "Start angle (in degrees).", + "type": "number", + "format": "double" + }, + "ccw": { + "description": "Is the helix rotation counter clockwise? The default is `false`.", + "default": false, + "type": "boolean" + }, + "length": { + "description": "Length of the helix. If this argument is not provided, the height of the extrude group is used.", + "type": "number", + "format": "double", + "nullable": true + }, + "revolutions": { + "description": "Number of revolutions.", + "type": "number", + "format": "double" + } + } + }, + "required": true + }, + { + "name": "extrude_group", + "type": "ExtrudeGroup", + "schema": { + "description": "An extrude group is a collection of extrude surfaces.", + "type": "object", + "required": [ + "__meta", + "height", + "id", + "position", + "rotation", + "sketchGroupValues", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "__meta": { + "description": "Metadata.", + "type": "array", + "items": { + "description": "Metadata.", + "type": "object", + "required": [ + "sourceRange" + ], + "properties": { + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + } + }, + "endCapId": { + "description": "The id of the extrusion end cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "height": { + "description": "The height of the extrude group.", + "type": "number", + "format": "double" + }, + "id": { + "description": "The id of the extrude group.", + "type": "string", + "format": "uuid" + }, + "position": { + "description": "The position of the extrude group.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 3, + "minItems": 3 + }, + "rotation": { + "description": "The rotation of the extrude group.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 4, + "minItems": 4 + }, + "sketchGroupValues": { + "description": "The sketch group paths.", + "type": "array", + "items": { + "description": "A path.", + "oneOf": [ + { + "description": "A path that goes to a point.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "name", + "to", + "type" + ], + "properties": { + "__geoMeta": { + "description": "Metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "name": { + "description": "The name of the path.", + "type": "string" + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "ToPoint" + ] + } + } + }, + { + "description": "A arc that is tangential to the last path segment that goes to a point", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "name", + "to", + "type" + ], + "properties": { + "__geoMeta": { + "description": "Metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + }, + "ccw": { + "description": "arc's direction", + "type": "boolean" + }, + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "name": { + "description": "The name of the path.", + "type": "string" + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "TangentialArcTo" + ] + } + } + }, + { + "description": "A arc that is tangential to the last path segment", + "type": "object", + "required": [ + "__geoMeta", + "from", + "name", + "to", + "type" + ], + "properties": { + "__geoMeta": { + "description": "Metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "name": { + "description": "The name of the path.", + "type": "string" + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "TangentialArc" + ] + } + } + }, + { + "description": "A path that is horizontal.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "name", + "to", + "type", + "x" + ], + "properties": { + "__geoMeta": { + "description": "Metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "name": { + "description": "The name of the path.", + "type": "string" + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "Horizontal" + ] + }, + "x": { + "description": "The x coordinate.", + "type": "number", + "format": "double" + } + } + }, + { + "description": "An angled line to.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "name", + "to", + "type" + ], + "properties": { + "__geoMeta": { + "description": "Metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "name": { + "description": "The name of the path.", + "type": "string" + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "AngledLineTo" + ] + }, + "x": { + "description": "The x coordinate.", + "type": "number", + "format": "double", + "nullable": true + }, + "y": { + "description": "The y coordinate.", + "type": "number", + "format": "double", + "nullable": true + } + } + }, + { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "name", + "to", + "type" + ], + "properties": { + "__geoMeta": { + "description": "Metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "name": { + "description": "The name of the path.", + "type": "string" + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "Base" + ] + } + } + } + ] + } + }, + "startCapId": { + "description": "The id of the extrusion start cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "value": { + "description": "The extrude surfaces.", + "type": "array", + "items": { + "description": "An extrude surface.", + "oneOf": [ + { + "description": "An extrude plane.", + "type": "object", + "required": [ + "faceId", + "id", + "name", + "position", + "rotation", + "sourceRange", + "type" + ], + "properties": { + "faceId": { + "description": "The face id for the extrude plane.", + "type": "string", + "format": "uuid" + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "name": { + "description": "The name.", + "type": "string" + }, + "position": { + "description": "The position.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 3, + "minItems": 3 + }, + "rotation": { + "description": "The rotation.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 4, + "minItems": 4 + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "extrudePlane" + ] + } + } + }, + { + "description": "An extruded arc.", + "type": "object", + "required": [ + "faceId", + "id", + "name", + "position", + "rotation", + "sourceRange", + "type" + ], + "properties": { + "faceId": { + "description": "The face id for the extrude plane.", + "type": "string", + "format": "uuid" + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "name": { + "description": "The name.", + "type": "string" + }, + "position": { + "description": "The position.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 3, + "minItems": 3 + }, + "rotation": { + "description": "The rotation.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 4, + "minItems": 4 + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "extrudeArc" + ] + } + } + } + ] + } + }, + "xAxis": { + "description": "The x-axis of the extrude group base plane in the 3D space", + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } + } + }, + "yAxis": { + "description": "The y-axis of the extrude group base plane in the 3D space", + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } + } + }, + "zAxis": { + "description": "The z-axis of the extrude group base plane in the 3D space", + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } + } + } + } + }, + "required": true + } + ], + "returnValue": { + "name": "", + "type": "ExtrudeGroup", + "schema": { + "description": "An extrude group is a collection of extrude surfaces.", + "type": "object", + "required": [ + "__meta", + "height", + "id", + "position", + "rotation", + "sketchGroupValues", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "__meta": { + "description": "Metadata.", + "type": "array", + "items": { + "description": "Metadata.", + "type": "object", + "required": [ + "sourceRange" + ], + "properties": { + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + } + }, + "endCapId": { + "description": "The id of the extrusion end cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "height": { + "description": "The height of the extrude group.", + "type": "number", + "format": "double" + }, + "id": { + "description": "The id of the extrude group.", + "type": "string", + "format": "uuid" + }, + "position": { + "description": "The position of the extrude group.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 3, + "minItems": 3 + }, + "rotation": { + "description": "The rotation of the extrude group.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 4, + "minItems": 4 + }, + "sketchGroupValues": { + "description": "The sketch group paths.", + "type": "array", + "items": { + "description": "A path.", + "oneOf": [ + { + "description": "A path that goes to a point.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "name", + "to", + "type" + ], + "properties": { + "__geoMeta": { + "description": "Metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "name": { + "description": "The name of the path.", + "type": "string" + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "ToPoint" + ] + } + } + }, + { + "description": "A arc that is tangential to the last path segment that goes to a point", + "type": "object", + "required": [ + "__geoMeta", + "ccw", + "center", + "from", + "name", + "to", + "type" + ], + "properties": { + "__geoMeta": { + "description": "Metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + }, + "ccw": { + "description": "arc's direction", + "type": "boolean" + }, + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "name": { + "description": "The name of the path.", + "type": "string" + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "TangentialArcTo" + ] + } + } + }, + { + "description": "A arc that is tangential to the last path segment", + "type": "object", + "required": [ + "__geoMeta", + "from", + "name", + "to", + "type" + ], + "properties": { + "__geoMeta": { + "description": "Metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "name": { + "description": "The name of the path.", + "type": "string" + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "TangentialArc" + ] + } + } + }, + { + "description": "A path that is horizontal.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "name", + "to", + "type", + "x" + ], + "properties": { + "__geoMeta": { + "description": "Metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "name": { + "description": "The name of the path.", + "type": "string" + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "Horizontal" + ] + }, + "x": { + "description": "The x coordinate.", + "type": "number", + "format": "double" + } + } + }, + { + "description": "An angled line to.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "name", + "to", + "type" + ], + "properties": { + "__geoMeta": { + "description": "Metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "name": { + "description": "The name of the path.", + "type": "string" + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "AngledLineTo" + ] + }, + "x": { + "description": "The x coordinate.", + "type": "number", + "format": "double", + "nullable": true + }, + "y": { + "description": "The y coordinate.", + "type": "number", + "format": "double", + "nullable": true + } + } + }, + { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "name", + "to", + "type" + ], + "properties": { + "__geoMeta": { + "description": "Metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + } + } + }, + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "name": { + "description": "The name of the path.", + "type": "string" + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "Base" + ] + } + } + } + ] + } + }, + "startCapId": { + "description": "The id of the extrusion start cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "value": { + "description": "The extrude surfaces.", + "type": "array", + "items": { + "description": "An extrude surface.", + "oneOf": [ + { + "description": "An extrude plane.", + "type": "object", + "required": [ + "faceId", + "id", + "name", + "position", + "rotation", + "sourceRange", + "type" + ], + "properties": { + "faceId": { + "description": "The face id for the extrude plane.", + "type": "string", + "format": "uuid" + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "name": { + "description": "The name.", + "type": "string" + }, + "position": { + "description": "The position.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 3, + "minItems": 3 + }, + "rotation": { + "description": "The rotation.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 4, + "minItems": 4 + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "extrudePlane" + ] + } + } + }, + { + "description": "An extruded arc.", + "type": "object", + "required": [ + "faceId", + "id", + "name", + "position", + "rotation", + "sourceRange", + "type" + ], + "properties": { + "faceId": { + "description": "The face id for the extrude plane.", + "type": "string", + "format": "uuid" + }, + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" + }, + "name": { + "description": "The name.", + "type": "string" + }, + "position": { + "description": "The position.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 3, + "minItems": 3 + }, + "rotation": { + "description": "The rotation.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 4, + "minItems": 4 + }, + "sourceRange": { + "description": "The source range.", + "type": "array", + "items": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "maxItems": 2, + "minItems": 2 + }, + "type": { + "type": "string", + "enum": [ + "extrudeArc" + ] + } + } + } + ] + } + }, + "xAxis": { + "description": "The x-axis of the extrude group base plane in the 3D space", + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } + } + }, + "yAxis": { + "description": "The y-axis of the extrude group base plane in the 3D space", + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } + } + }, + "zAxis": { + "description": "The z-axis of the extrude group base plane in the 3D space", + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } + } + } + } + }, + "required": true + }, + "unpublished": false, + "deprecated": false, + "examples": [ + "const part001 = startSketchOn('XY')\n |> circle([5, 5], 10, %)\n |> extrude(10, %)\n |> helix({ revolutions: 16, angle_start: 0 }, %)" + ] + }, { "name": "hole", "summary": "Use a sketch to cut a hole in another sketch.", diff --git a/e2e/playwright/export-snapshots/gltf-binary.png b/e2e/playwright/export-snapshots/gltf-binary.png index ce5bc341c..95d434168 100644 Binary files a/e2e/playwright/export-snapshots/gltf-binary.png and b/e2e/playwright/export-snapshots/gltf-binary.png differ diff --git a/e2e/playwright/export-snapshots/gltf-embedded.png b/e2e/playwright/export-snapshots/gltf-embedded.png index ce5bc341c..95d434168 100644 Binary files a/e2e/playwright/export-snapshots/gltf-embedded.png and b/e2e/playwright/export-snapshots/gltf-embedded.png differ diff --git a/e2e/playwright/export-snapshots/gltf-standard.png b/e2e/playwright/export-snapshots/gltf-standard.png index ce5bc341c..95d434168 100644 Binary files a/e2e/playwright/export-snapshots/gltf-standard.png and b/e2e/playwright/export-snapshots/gltf-standard.png differ diff --git a/e2e/playwright/export-snapshots/obj-.png b/e2e/playwright/export-snapshots/obj-.png index 5a6fcfa37..c9a400916 100644 Binary files a/e2e/playwright/export-snapshots/obj-.png and b/e2e/playwright/export-snapshots/obj-.png differ diff --git a/e2e/playwright/export-snapshots/ply-ascii.png b/e2e/playwright/export-snapshots/ply-ascii.png index 5a6fcfa37..c9a400916 100644 Binary files a/e2e/playwright/export-snapshots/ply-ascii.png and b/e2e/playwright/export-snapshots/ply-ascii.png differ diff --git a/e2e/playwright/export-snapshots/ply-binary_big_endian.png b/e2e/playwright/export-snapshots/ply-binary_big_endian.png index 5a6fcfa37..c9a400916 100644 Binary files a/e2e/playwright/export-snapshots/ply-binary_big_endian.png and b/e2e/playwright/export-snapshots/ply-binary_big_endian.png differ diff --git a/e2e/playwright/export-snapshots/ply-binary_little_endian.png b/e2e/playwright/export-snapshots/ply-binary_little_endian.png index 5a6fcfa37..c9a400916 100644 Binary files a/e2e/playwright/export-snapshots/ply-binary_little_endian.png and b/e2e/playwright/export-snapshots/ply-binary_little_endian.png differ diff --git a/e2e/playwright/export-snapshots/step-.png b/e2e/playwright/export-snapshots/step-.png index ce5bc341c..95d434168 100644 Binary files a/e2e/playwright/export-snapshots/step-.png and b/e2e/playwright/export-snapshots/step-.png differ diff --git a/e2e/playwright/export-snapshots/stl-ascii.png b/e2e/playwright/export-snapshots/stl-ascii.png index 5a6fcfa37..c9a400916 100644 Binary files a/e2e/playwright/export-snapshots/stl-ascii.png and b/e2e/playwright/export-snapshots/stl-ascii.png differ diff --git a/e2e/playwright/export-snapshots/stl-binary.png b/e2e/playwright/export-snapshots/stl-binary.png index 5a6fcfa37..c9a400916 100644 Binary files a/e2e/playwright/export-snapshots/stl-binary.png and b/e2e/playwright/export-snapshots/stl-binary.png differ diff --git a/src/wasm-lib/kcl/src/engine/mod.rs b/src/wasm-lib/kcl/src/engine/mod.rs index 32d972d89..a0f20f1e0 100644 --- a/src/wasm-lib/kcl/src/engine/mod.rs +++ b/src/wasm-lib/kcl/src/engine/mod.rs @@ -134,6 +134,11 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static { pub fn is_cmd_with_return_values(cmd: &kittycad::types::ModelingCmd) -> bool { let (kittycad::types::ModelingCmd::Export { .. } | kittycad::types::ModelingCmd::Extrude { .. } + | kittycad::types::ModelingCmd::DefaultCameraLookAt { .. } + | kittycad::types::ModelingCmd::DefaultCameraFocusOn { .. } + | kittycad::types::ModelingCmd::DefaultCameraGetSettings { .. } + | kittycad::types::ModelingCmd::DefaultCameraPerspectiveSettings { .. } + | kittycad::types::ModelingCmd::DefaultCameraZoom { .. } | kittycad::types::ModelingCmd::SketchModeDisable { .. } | kittycad::types::ModelingCmd::ObjectBringToFront { .. } | kittycad::types::ModelingCmd::SelectWithPoint { .. } @@ -144,8 +149,6 @@ pub fn is_cmd_with_return_values(cmd: &kittycad::types::ModelingCmd) -> bool { | kittycad::types::ModelingCmd::EntityGetAllChildUuids { .. } | kittycad::types::ModelingCmd::CameraDragMove { .. } | kittycad::types::ModelingCmd::CameraDragEnd { .. } - | kittycad::types::ModelingCmd::DefaultCameraGetSettings { .. } - | kittycad::types::ModelingCmd::DefaultCameraZoom { .. } | kittycad::types::ModelingCmd::SelectGet { .. } | kittycad::types::ModelingCmd::Solid3DGetAllEdgeFaces { .. } | kittycad::types::ModelingCmd::Solid3DGetAllOppositeEdges { .. } diff --git a/src/wasm-lib/kcl/src/std/helix.rs b/src/wasm-lib/kcl/src/std/helix.rs new file mode 100644 index 000000000..0c87a51d3 --- /dev/null +++ b/src/wasm-lib/kcl/src/std/helix.rs @@ -0,0 +1,70 @@ +//! Standard library helices. + +use anyhow::Result; +use derive_docs::stdlib; +use kittycad::types::ModelingCmd; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::{ + errors::KclError, + executor::{ExtrudeGroup, MemoryItem}, + std::Args, +}; + +/// Data for helices. +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] +#[ts(export)] +pub struct HelixData { + /// Number of revolutions. + pub revolutions: f64, + /// Start angle (in degrees). + pub angle_start: f64, + /// Is the helix rotation counter clockwise? + /// The default is `false`. + #[serde(default)] + pub ccw: bool, + /// Length of the helix. If this argument is not provided, the height of + /// the extrude group is used. + pub length: Option, +} + +/// Create a helix on a cylinder. +pub async fn helix(args: Args) -> Result { + let (data, extrude_group): (HelixData, Box) = args.get_data_and_extrude_group()?; + + let extrude_group = inner_helix(data, extrude_group, args).await?; + Ok(MemoryItem::ExtrudeGroup(extrude_group)) +} + +/// Create a helix on a cylinder. +/// +/// ```no_run +/// const part001 = startSketchOn('XY') +/// |> circle([5, 5], 10, %) +/// |> extrude(10, %) +/// |> helix({revolutions: 16, angle_start: 0}, %) +/// ``` +#[stdlib { + name = "helix", +}] +async fn inner_helix( + data: HelixData, + extrude_group: Box, + args: Args, +) -> Result, KclError> { + let id = uuid::Uuid::new_v4(); + args.send_modeling_cmd( + id, + ModelingCmd::EntityMakeHelix { + cylinder_id: extrude_group.id, + is_clockwise: !data.ccw, + length: data.length.unwrap_or(extrude_group.height), + revolutions: data.revolutions, + start_angle: kittycad::types::Angle::from_degrees(data.angle_start), + }, + ) + .await?; + + Ok(extrude_group) +} diff --git a/src/wasm-lib/kcl/src/std/mod.rs b/src/wasm-lib/kcl/src/std/mod.rs index 9e74c6e89..d66bb91f0 100644 --- a/src/wasm-lib/kcl/src/std/mod.rs +++ b/src/wasm-lib/kcl/src/std/mod.rs @@ -2,6 +2,7 @@ pub mod extrude; pub mod fillet; +pub mod helix; pub mod import; pub mod kcl_stdlib; pub mod math; @@ -79,6 +80,7 @@ lazy_static! { Box::new(crate::std::fillet::GetOppositeEdge), Box::new(crate::std::fillet::GetNextAdjacentEdge), Box::new(crate::std::fillet::GetPreviousAdjacentEdge), + Box::new(crate::std::helix::Helix), Box::new(crate::std::import::Import), Box::new(crate::std::math::Cos), Box::new(crate::std::math::Sin), diff --git a/src/wasm-lib/tests/executor/inputs/riddle.kcl b/src/wasm-lib/tests/executor/inputs/riddle.kcl new file mode 100644 index 000000000..a34f88895 --- /dev/null +++ b/src/wasm-lib/tests/executor/inputs/riddle.kcl @@ -0,0 +1,2654 @@ +const ANSWER = 41803 + +fn m = (s) => { + return (ANSWER * s + 12345) % 214748 +} +fn p = (xs, ys) => { + let ox = 35 - (m(xs) % 70) + let oy = 35 - (m(ys) % 70) + const r = startSketchOn('XZ') + |> startProfileAt([ox, oy], %) + |> line([1, 0], %) + |> line([0, -1], %) + |> line([-1, 0], %) + |> close(%) + |> extrude(1, %) + return r +} +p(177533, 177533) +p(133828, 31489) +p(144509, 138041) +p(87312, 57981) +p(160197, 14025) +p(76508, 129013) +p(212949, 43329) +p(155560, 70405) +p(23301, 60893) +p(64504, 75837) +p(32297, 166861) +p(113668, 168121) +p(84273, 151141) +p(156140, 172777) +p(172545, 179961) +p(23840, 102521) +p(14437, 158125) +p(175384, 118925) +p(74857, 149881) +p(188160, 98057) +p(7481, 153469) +p(53632, 172685) +p(71397, 109897) +p(161504, 66717) +p(59133, 126201) +p(107904, 151817) +p(70065, 208005) +p(88948, 18197) +p(117193, 119701) +p(143744, 134645) +p(192365, 65941) +p(77044, 11013) +p(9317, 54293) +p(83804, 116305) +p(87401, 139301) +p(162664, 3545) +p(53985, 72733) +p(4748, 151041) +p(109849, 31589) +p(66428, 19649) +p(211705, 141629) +p(195360, 39449) +p(62425, 42361) +p(164956, 112325) +p(169429, 128821) +p(158808, 2769) +p(127569, 108153) +p(129956, 174721) +p(91825, 71181) +p(147196, 149005) +p(103533, 49053) +p(86320, 136389) +p(26261, 148421) +p(205548, 114361) +p(69701, 7909) +p(80524, 44689) +p(35217, 156281) +p(120084, 149297) +p(173561, 146193) +p(152268, 196165) +p(28745, 13733) +p(122832, 155021) +p(42297, 30521) +p(155600, 68853) +p(51093, 184325) +p(173616, 137457) +p(61057, 197425) +p(116036, 138817) +p(65681, 162981) +p(162981, 12040) +p(12040, 12040) +p(62221, 143240) +p(148348, 201848) +p(202309, 83656) +p(7412, 49112) +p(15573, 212236) +p(167400, 74052) +p(40189, 102872) +p(68092, 162356) +p(24629, 139260) +p(129196, 186712) +p(64189, 21068) +p(156816, 24948) +p(176817, 102096) +p(131844, 161480) +p(58493, 185744) +p(130844, 93844) +p(95141, 164876) +p(83260, 68812) +p(53089, 93068) +p(115736, 49888) +p(187745, 132760) +p(36420, 153328) +p(48461, 91224) +p(0, 6416) +p(115581, 15828) +p(24708, 57164) +p(144561, 117716) +p(88332, 184384) +p(136277, 92584) +p(184272, 38924) +p(193985, 91616) +p(91664, 188848) +p(191425, 13108) +p(84064, 127420) +p(109881, 202624) +p(169908, 194380) +p(34253, 124024) +p(89624, 60952) +p(134657, 194672) +p(107056, 38240) +p(144713, 155080) +p(111972, 123732) +p(11353, 112768) +p(145224, 170508) +p(140961, 196224) +p(26800, 76572) +p(156649, 116748) +p(187372, 159252) +p(18433, 104424) +p(42264, 100544) +p(161141, 44548) +p(206324, 173320) +p(174017, 16020) +p(108476, 71040) +p(169521, 209708) +p(37796, 163132) +p(108545, 106168) +p(63188, 211844) +p(214089, 61728) +p(205804, 71816) +p(85093, 48628) +p(11400, 160704) +p(72637, 9228) +p(24176, 197484) +p(43785, 151292) +p(33164, 159152) +p(183489, 3112) +p(214121, 34269) +p(88704, 137617) +p(137617, 137617) +p(48980, 164985) +p(71017, 72601) +p(84560, 78325) +p(71369, 46885) +p(155752, 53193) +p(146157, 26409) +p(35976, 131309) +p(116913, 197201) +p(152000, 94045) +p(25273, 161681) +p(139352, 169641) +p(40669, 118985) +p(127480, 154505) +p(206281, 152077) +p(163544, 102973) +p(168209, 22045) +p(192524, 59017) +p(102677, 79877) +p(88952, 62221) +p(181145, 8845) +p(171692, 49021) +p(177717, 35045) +p(20860, 183033) +p(128581, 129173) +p(53628, 166829) +p(115257, 81821) +p(90568, 20685) +p(135501, 191477) +p(81700, 82497) +p(112473, 123549) +p(78564, 67553) +p(210449, 149265) +p(107060, 9237) +p(204301, 76581) +p(108096, 157801) +p(119553, 135481) +p(64876, 20785) +p(194725, 25341) +p(30492, 93661) +p(200901, 193221) +p(8916, 161973) +p(130321, 208649) +p(176472, 7393) +p(111657, 70565) +p(62512, 2345) +p(34961, 62413) +p(172328, 188173) +p(119353, 144509) +p(100872, 122965) +p(148141, 154989) +p(152080, 12049) +p(100557, 126361) +p(39964, 205837) +p(10569, 69789) +p(6356, 120153) +p(93893, 57949) +p(166920, 9429) +p(163533, 196033) +p(158544, 40677) +p(15221, 51833) +p(18092, 106369) +p(127657, 101521) +p(166240, 35437) +p(59021, 70857) +p(194928, 96281) +p(139625, 133637) +p(16937, 95364) +p(159252, 42380) +p(132377, 98568) +p(39633, 208124) +p(92476, 48980) +p(201849, 104100) +p(17693, 174356) +p(173300, 148348) +p(175445, 189592) +p(63969, 125836) +p(68876, 174548) +p(160685, 164168) +p(138041, 212497) +p(117716, 56749) +p(154989, 12793) +p(111733, 146513) +p(9020, 144085) +p(142073, 106921) +p(134525, 76549) +p(864, 63449) +p(41917, 39285) +p(158097, 110025) +p(116036, 89065) +p(65681, 25117) +p(196457, 214592) +p(143240, 87472) +p(90165, 15664) +p(102705, 4792) +p(94128, 72820) +p(176033, 71460) +p(127249, 46228) +p(156028, 140356) +p(115861, 31576) +p(9725, 28472) +p(85372, 204696) +p(212793, 193048) +p(78557, 96017) +p(71816, 165013) +p(150041, 82725) +p(213533, 213533) +p(184088, 112513) +p(70561, 62833) +p(30344, 104169) +p(36469, 66713) +p(65540, 153173) +p(197809, 118629) +p(141488, 198105) +p(208065, 90101) +p(21612, 110769) +p(208417, 158029) +p(31084, 52061) +p(170637, 202569) +p(17468, 92329) +p(176329, 201017) +p(110081, 206157) +p(177092, 34105) +p(185253, 190537) +p(200544, 148709) +p(132525, 188693) +p(75812, 127849) +p(15749, 48181) +p(199116, 15573) +p(71905, 86705) +p(198085, 18385) +p(143316, 183645) +p(106445, 93789) +p(31684, 63025) +p(150953, 154725) +p(6712, 108441) +p(85905, 145121) +p(152432, 139689) +p(22017, 32553) +p(131732, 70885) +p(210341, 193541) +p(169156, 50993) +p(99877, 57785) +p(14052, 205189) +p(54137, 125421) +p(165081, 118821) +p(30936, 121441) +p(161845, 208001) +p(177533, 105972) +p(203500, 197188) +p(144509, 207284) +p(212949, 198356) +p(198356, 198356) +p(103261, 97144) +p(64504, 106264) +p(208229, 11844) +p(189748, 151972) +p(134637, 59104) +p(29504, 150804) +p(145861, 99764) +p(9380, 165456) +p(153589, 184864) +p(81256, 76084) +p(185773, 58812) +p(118096, 115000) +p(2725, 104128) +p(138225, 60656) +p(49780, 65796) +p(11457, 154784) +p(30044, 91612) +p(178909, 165072) +p(161404, 206600) +p(11093, 121692) +p(40164, 30184) +p(162537, 61624) +p(162473, 147116) +p(107796, 34940) +p(1161, 114416) +p(2864, 53864) +p(82349, 131104) +p(209328, 15532) +p(204197, 92388) +p(149036, 182536) +p(68309, 173900) +p(176172, 169436) +p(87001, 9032) +p(179536, 19512) +p(121029, 46004) +p(202308, 170796) +p(188633, 164780) +p(20689, 65120) +p(154268, 167400) +p(144381, 154300) +p(195097, 211173) +p(102872, 11753) +p(67553, 172649) +p(142309, 79389) +p(194376, 129269) +p(129269, 129269) +p(66832, 113549) +p(182121, 124905) +p(141036, 199917) +p(25665, 8649) +p(168756, 195353) +p(61629, 175461) +p(63048, 123545) +p(93913, 184681) +p(155008, 75901) +p(139681, 137905) +p(173892, 214569) +p(110829, 190113) +p(4989, 166049) +p(120228, 138297) +p(166137, 170413) +p(91664, 178373) +p(142813, 143921) +p(84064, 3509) +p(144713, 33589) +p(177280, 188369) +p(186117, 114909) +p(156649, 108893) +p(53068, 73765) +p(18433, 59113) +p(42264, 45429) +p(161141, 67457) +p(168184, 91229) +p(153541, 103069) +p(108476, 7581) +p(169521, 38245) +p(21200, 46881) +p(22085, 54841) +p(113452, 190889) +p(88037, 131697) +p(209876, 141009) +p(41713, 196905) +p(201569, 183513) +p(68684, 105789) +p(23761, 70561) +p(57013, 30344) +p(56972, 52664) +p(100745, 115452) +p(202569, 140000) +p(206600, 149220) +p(62117, 121952) +p(50017, 181144) +p(76952, 80416) +p(191949, 120300) +p(39725, 149120) +p(46676, 193176) +p(5441, 150964) +p(41304, 16568) +p(73237, 212876) +p(95808, 180560) +p(64876, 66832) +p(194725, 189296) +p(41748, 99048) +p(124437, 132140) +p(59472, 80808) +p(116445, 135728) +p(124433, 39272) +p(190084, 145340) +p(64817, 65280) +p(189249, 75176) +p(192604, 200552) +p(43949, 43252) +p(10501, 9484) +p(196388, 50820) +p(205901, 110888) +p(151817, 184549) +p(155080, 159901) +p(70857, 154469) +p(164237, 86833) +p(115000, 8617) +p(67457, 45105) +p(1689, 109637) +p(26396, 20457) +p(97045, 115553) +p(56321, 127101) +p(184568, 126425) +p(11649, 27441) +p(205880, 115653) +p(108073, 44813) +p(76108, 112741) +p(23832, 156797) +p(210153, 116913) +p(122776, 208713) +p(30401, 101485) +p(31528, 29385) +p(190097, 83145) +p(77657, 162037) +p(80044, 36177) +p(59577, 3085) +p(85609, 19973) +p(45492, 115261) +p(164569, 18613) +p(165081, 186101) +p(30936, 193961) +p(161845, 169897) +p(177533, 158500) +p(15828, 22644) +p(19717, 187128) +p(212949, 49720) +p(168952, 122696) +p(103261, 175096) +p(155209, 18180) +p(54440, 12556) +p(123345, 166944) +p(126869, 69320) +p(61328, 206052) +p(61821, 42828) +p(29948, 104840) +p(361, 107460) +p(112788, 93292) +p(44984, 53216) +p(59453, 191300) +p(162952, 193144) +p(161017, 207796) +p(205424, 19540) +p(48225, 106684) +p(72033, 11388) +p(17648, 51856) +p(56957, 152968) +p(129765, 208672) +p(211428, 204984) +p(56273, 3044) +p(36217, 94360) +p(109828, 3528) +p(36669, 125800) +p(204125, 60793) +p(12432, 108145) +p(129173, 30613) +p(183645, 119401) +p(112088, 64189) +p(36401, 207029) +p(95141, 25665) +p(203880, 65349) +p(53089, 43129) +p(48461, 37697) +p(0, 141) +p(115581, 31289) +p(24708, 203049) +p(144561, 151233) +p(117060, 127553) +p(91664, 128137) +p(117873, 84273) +p(139468, 7517) +p(144713, 212461) +p(86740, 119985) +p(30077, 34009) +p(90757, 203533) +p(2220, 171417) +p(180973, 117173) +p(35929, 183933) +p(169216, 197809) +p(45793, 188881) +p(143445, 145601) +p(130980, 16637) +p(54717, 21393) +p(13733, 17664) +p(119560, 38040) +p(197201, 135856) +p(201985, 195632) +p(114416, 135472) +p(2049, 161964) +p(173933, 176324) +p(121592, 35228) +p(143529, 182340) +p(207897, 58516) +p(20184, 14560) +p(180789, 38332) +p(160, 100344) +p(25301, 23388) +p(157328, 52892) +p(1516, 130232) +p(190557, 113344) +p(131608, 80060) +p(142193, 188164) +p(72964, 166328) +p(96261, 49880) +p(58641, 16404) +p(52000, 112860) +p(116441, 211644) +p(180029, 67836) +p(105368, 82488) +p(49573, 202816) +p(59021, 53568) +p(70236, 154104) +p(71697, 5340) +p(119701, 64641) +p(170508, 23497) +p(133637, 75413) +p(184521, 201273) +p(60656, 79293) +p(202145, 201757) +p(68649, 100929) +p(200000, 6025) +p(152357, 11657) +p(62045, 90841) +p(95288, 100153) +p(99569, 194281) +p(201124, 37081) +p(170761, 153913) +p(153932, 191277) +p(184532, 56005) +p(158917, 40669) +p(125884, 136449) +p(41949, 124609) +p(114884, 149841) +p(175445, 187197) +p(9829, 160613) +p(163108, 147513) +p(156617, 214273) +p(99877, 173129) +p(126812, 184385) +p(130893, 66385) +p(165081, 54161) +p(30936, 78417) +p(127493, 82205) +p(138041, 157176) +p(117716, 1812) +p(154989, 37332) +p(207709, 50332) +p(106264, 83908) +p(193025, 11224) +p(66221, 100504) +p(118096, 37232) +p(2725, 92936) +p(21969, 139028) +p(64432, 53728) +p(45709, 59844) +p(144529, 20252) +p(111880, 78476) +p(4077, 46260) +p(37420, 48104) +p(111857, 35680) +p(83380, 66636) +p(145885, 196668) +p(193004, 110400) +p(87529, 35872) +p(13129, 77700) +p(205424, 62756) +p(81801, 153488) +p(11965, 208024) +p(188340, 192304) +p(86069, 201132) +p(209333, 45576) +p(211428, 209476) +p(210077, 212680) +p(17293, 104192) +p(51504, 103508) +p(203089, 122432) +p(61377, 116617) +p(212236, 62665) +p(81821, 110993) +p(183645, 65477) +p(24752, 41997) +p(36401, 27053) +p(95141, 150485) +p(203880, 156501) +p(159833, 150777) +p(151517, 30741) +p(39008, 115649) +p(192821, 199881) +p(152581, 32001) +p(52688, 140781) +p(193985, 20161) +p(91664, 49465) +p(191425, 127097) +p(201480, 12493) +p(30889, 203469) +p(169908, 179789) +p(100337, 24333) +p(51461, 74113) +p(129344, 14629) +p(78989, 106621) +p(157909, 190853) +p(137492, 162617) +p(59769, 113029) +p(68437, 2697) +p(211528, 32969) +p(56173, 162325) +p(43785, 60045) +p(104196, 152137) +p(134193, 68197) +p(148421, 31084) +p(68904, 69708) +p(137617, 184020) +p(201017, 184312) +p(155752, 120656) +p(110637, 210320) +p(71269, 93388) +p(20572, 77084) +p(102677, 57576) +p(177717, 81156) +p(20860, 60588) +p(54737, 43216) +p(83685, 99596) +p(166808, 140064) +p(28825, 63400) +p(165024, 80672) +p(75177, 214008) +p(171884, 161024) +p(11389, 87080) +p(87520, 1780) +p(73845, 67572) +p(124437, 91252) +p(59472, 68056) +p(31437, 193140) +p(124433, 208376) +p(46760, 66896) +p(64817, 131036) +p(64941, 48556) +p(195708, 55056) +p(6101, 99012) +p(82793, 96784) +p(128168, 79412) +p(205901, 23616) +p(151817, 185773) +p(155080, 102225) +p(70857, 83109) +p(51185, 172481) +p(115000, 172189) +p(67457, 52053) +p(40824, 196353) +p(105073, 180825) +p(203140, 59621) +p(165885, 180049) +p(173604, 1689) +p(79293, 38177) +p(80220, 7513) +p(130009, 133857) +p(115416, 27889) +p(27889, 27889) +p(47064, 122309) +p(57845, 66513) +p(75437, 93005) +p(177092, 207609) +p(185253, 72337) +p(169077, 19353) +p(108192, 36817) +p(34841, 71269) +p(18181, 35749) +p(137692, 153557) +p(57833, 118137) +p(108932, 125321) +p(182693, 18285) +p(56984, 213625) +p(115701, 181701) +p(131572, 133473) +p(71905, 10425) +p(198085, 75733) +p(143316, 79805) +p(79953, 89509) +p(202668, 42157) +p(150953, 105813) +p(6712, 63309) +p(85905, 25561) +p(81984, 63017) +p(22017, 138905) +p(131732, 30125) +p(210341, 146181) +p(12632, 95141) +p(146453, 212265) +p(45492, 74081) +p(62581, 21197) +p(75809, 127841) +p(167660, 21873) +p(42293, 155985) +p(57981, 62492) +p(117716, 88208) +p(154989, 70352) +p(207709, 52596) +p(106264, 76368) +p(81333, 98012) +p(200552, 146532) +p(24337, 133916) +p(57872, 188160) +p(75445, 147016) +p(65408, 209604) +p(185261, 54440) +p(103900, 118096) +p(190853, 126540) +p(138120, 58612) +p(180825, 151380) +p(151380, 151380) +p(63377, 8440) +p(59909, 105872) +p(49780, 194760) +p(11457, 70744) +p(133465, 88792) +p(86556, 3884) +p(117129, 155844) +p(177809, 38620) +p(181356, 200000) +p(63757, 17468) +p(20436, 160408) +p(166681, 144588) +p(174692, 122076) +p(186541, 97912) +p(146132, 204364) +p(77529, 80448) +p(206721, 156428) +p(49572, 211548) +p(93153, 176320) +p(134064, 120040) +p(82349, 137504) +p(209328, 192524) +p(204197, 78896) +p(164464, 136728) +p(6297, 148084) +p(18196, 72680) +p(43045, 140900) +p(12340, 171080) +p(197401, 20280) +p(173196, 39788) +p(91693, 121592) +p(185949, 168268) +p(54224, 55408) +p(1249, 13296) +p(104465, 14173) +p(120920, 92681) +p(76581, 30185) +p(19745, 92197) +p(113640, 51053) +p(113549, 208353) +p(49852, 93649) +p(182121, 164489) +p(211484, 132565) +p(25665, 202821) +p(168756, 53089) +p(83465, 158181) +p(130292, 86957) +p(93913, 20097) +p(155008, 23201) +p(139681, 16701) +p(173892, 110829) +p(110829, 110829) +p(4989, 154593) +p(120228, 213977) +p(166137, 193793) +p(68641, 104421) +p(81992, 40765) +p(193985, 154785) +p(30889, 182153) +p(169908, 149837) +p(34253, 7481) +p(89624, 120141) +p(134657, 14565) +p(107056, 114225) +p(144713, 198549) +p(177280, 203789) +p(186117, 15533) +p(141997, 106073) +p(2220, 43869) +p(180973, 210389) +p(144152, 8257) +p(208501, 155661) +p(196136, 63377) +p(17201, 99573) +p(172716, 97045) +p(95577, 22133) +p(55944, 83169) +p(74969, 143821) +p(45816, 94233) +p(113361, 181085) +p(4348, 66189) +p(41521, 116453) +p(176245, 186809) +p(104196, 49401) +p(134193, 152357) +p(114361, 22384) +p(147704, 24128) +p(78325, 145624) +p(177717, 174928) +p(15328, 70128) +p(128581, 181336) +p(106973, 166584) +p(480, 77988) +p(118097, 203848) +p(110365, 56252) +p(115564, 25196) +p(106937, 2492) +p(5853, 111272) +p(95960, 115736) +p(116445, 13356) +p(197397, 124080) +p(154660, 62460) +p(205901, 192008) +p(151817, 15793) +p(155080, 5213) +p(70857, 97889) +p(182665, 41801) +p(82288, 211425) +p(180889, 143789) +p(128125, 196965) +p(6596, 125833) +p(107233, 125349) +p(183633, 93809) +p(142832, 40633) +p(198253, 76345) +p(179457, 202497) +p(202220, 111181) +p(137113, 82945) +p(206225, 187745) +p(30544, 178817) +p(153601, 191725) +p(59825, 136956) +p(133828, 211576) +p(144509, 64464) +p(197317, 205268) +p(170108, 67376) +p(46585, 72424) +p(66121, 47000) +p(77044, 184408) +p(9317, 122396) +p(40693, 207696) +p(81604, 99300) +p(181365, 201872) +p(145105, 199736) +p(162628, 104932) +p(80249, 126960) +p(73965, 148888) +p(124480, 54760) +p(159133, 35160) +p(208489, 51273) +p(51924, 85725) +p(62221, 177717) +p(148348, 200621) +p(202309, 160253) +p(7412, 129681) +p(15573, 83589) +p(171088, 78057) +p(120441, 56421) +p(102836, 127937) +p(32197, 211485) +p(172768, 94845) +p(119401, 3437) +p(181756, 85625) +p(122281, 125025) +p(131844, 207897) +p(58493, 140261) +p(130844, 102705) +p(131529, 7217) +p(185348, 106493) +p(161677, 35069) +p(13356, 201397) +p(178817, 12365) +p(36420, 48461) +p(48461, 48461) +p(49296, 151517) +p(115581, 169373) +p(121840, 80777) +p(137469, 206345) +p(117636, 101445) +p(44961, 5765) +p(58312, 80193) +p(43469, 178009) +p(169288, 53701) +p(201997, 197317) +p(15836, 142881) +p(127829, 207021) +p(53552, 87277) +p(184177, 150549) +p(209560, 154913) +p(133873, 63405) +p(148000, 181213) +p(68925, 111733) +p(134384, 32741) +p(35701, 20901) +p(138908, 18765) +p(152409, 64373) +p(189048, 138225) +p(187213, 116581) +p(124968, 21969) +p(41713, 59909) +p(77192, 179369) +p(154249, 15369) +p(122668, 56321) +p(116953, 182665) +p(37628, 182181) +p(209397, 118525) +p(149005, 130324) +p(151292, 173312) +p(35729, 191068) +p(13076, 131776) +p(184069, 190192) +p(6636, 92476) +p(158029, 13776) +p(206600, 206304) +p(62117, 95288) +p(121952, 85100) +p(205993, 177092) +p(160928, 56380) +p(204601, 52108) +p(17664, 155456) +p(105493, 26200) +p(6860, 147888) +p(133113, 135272) +p(93388, 9704) +p(168209, 27168) +p(192524, 14260) +p(198649, 59192) +p(51496, 65500) +p(82945, 111300) +p(171692, 20860) +p(200621, 15328) +p(15328, 15328) +p(128581, 22028) +p(79628, 56472) +p(194725, 203584) +p(41748, 129640) +p(48065, 94128) +p(52296, 149924) +p(31437, 202032) +p(90588, 18240) +p(79149, 105284) +p(173912, 208440) +p(17497, 31824) +p(24248, 39008) +p(145845, 40752) +p(38768, 211060) +p(95641, 162924) +p(6812, 140804) +p(68049, 152736) +p(145832, 144976) +p(10569, 75788) +p(188112, 213872) +p(105341, 177192) +p(166920, 138084) +p(163533, 88496) +p(158544, 182240) +p(15221, 54920) +p(18092, 52692) +p(127657, 107904) +p(166240, 170108) +p(59021, 124208) +p(70236, 78792) +p(71697, 63172) +p(86317, 155365) +p(170508, 55413) +p(133637, 142073) +p(42380, 207281) +p(42097, 213005) +p(164036, 61821) +p(184521, 49397) +p(60656, 45709) +p(202145, 11457) +p(197740, 57549) +p(150005, 164101) +p(92032, 11649) +p(142013, 123049) +p(180496, 210869) +p(177593, 33777) +p(48104, 185061) +p(144277, 120429) +p(107648, 180889) +p(66513, 196217) +p(15624, 105585) +p(186809, 94713) +p(13164, 5149) +p(109437, 37949) +p(10412, 99569) +p(75437, 8837) +p(177092, 101313) +p(101313, 101313) +p(22472, 210193) +p(182693, 128581) +p(133256, 170601) +p(119097, 199421) +p(117504, 179045) +p(84421, 51241) +p(76520, 73077) +p(1709, 117617) +p(64356, 128873) +p(196725, 118877) +p(15996, 4373) +p(201641, 180789) +p(164144, 95881) +p(90985, 177977) +p(144896, 188065) +p(37969, 93937) +p(193576, 199713) +p(23861, 90933) +p(111740, 107037) +p(63905, 16405) +p(180120, 136833) +p(86093, 115581) +p(98476, 187581) +p(1153, 166137) +p(2664, 8253) +p(144737, 207473) +p(36400, 62981) +p(102393, 205245) +p(114192, 64049) +p(51029, 89089) +p(60893, 86136) +p(188848, 177160) +p(120153, 106320) +p(212461, 57508) +p(99660, 88948) +p(167597, 39360) +p(103900, 134656) +p(192505, 212964) +p(82324, 19276) +p(59909, 200448) +p(49780, 183660) +p(11457, 133104) +p(44761, 185796) +p(26764, 6660) +p(74033, 45668) +p(140752, 113404) +p(196365, 94288) +p(195648, 123784) +p(64937, 70608) +p(177948, 99912) +p(54233, 7436) +p(121929, 44317) +p(102872, 16757) +p(67553, 114965) +p(112709, 147081) +p(113344, 150769) +p(61629, 99729) +p(63048, 111953) +p(206573, 50433) +p(107164, 167173) +p(97565, 62273) +p(140804, 15305) +p(60945, 131653) +p(17201, 191913) +p(173492, 105161) +p(151373, 70425) +p(93984, 61205) +p(131541, 197545) +p(171384, 171637) +p(200209, 126805) +p(37628, 200749) +p(186593, 25685) +p(149005, 76108) +p(159152, 78920) +p(119469, 194300) +p(204601, 51360) +p(17664, 209728) +p(56973, 90760) +p(107004, 143644) +p(133113, 52428) +p(93388, 81540) +p(198385, 166356) +p(74036, 61456) +p(143233, 192456) +p(18753, 136952) +p(145832, 93572) +p(124881, 74940) +p(93592, 97360) +p(146877, 63200) +p(56104, 86296) +p(82793, 29724) +p(128168, 49616) +p(202605, 78144) +p(109897, 94457) +p(38240, 212357) +p(63673, 101149) +p(163392, 33513) +p(138653, 38561) +p(203436, 41373) +p(59844, 164905) +p(130009, 144529) +p(140156, 181109) +p(9476, 80481) +p(211425, 154425) +p(23804, 48165) +p(39633, 100765) +p(92476, 109785) +p(37949, 128125) +p(168401, 168401) +p(141868, 74273) +p(208445, 190137) +p(191808, 116093) +p(202973, 76893) +p(34476, 136669) +p(183633, 169077) +p(142832, 180917) +p(198253, 209545) +p(55948, 110469) +p(202101, 30601) +p(142284, 111921) +p(214001, 65053) +p(129536, 207117) +p(43277, 124729) +p(65748, 98629) +p(148921, 42149) +p(183424, 50401) +p(32825, 200517) +p(56364, 70777) +p(9405, 83685) +p(29356, 2657) +p(69149, 135501) +p(118404, 98821) +p(212760, 112989) +p(161721, 106973) +p(72308, 157237) +p(157613, 92321) +p(46556, 84945) +p(2509, 6637) +p(140853, 181460) +p(150516, 43660) +p(7393, 128960) +p(10264, 23092) +p(191637, 29592) +p(112604, 111204) +p(150868, 25904) +p(46653, 127216) +p(204980, 105672) +p(72940, 87524) +p(156497, 82768) +p(131132, 213576) +p(206345, 137696) +p(138084, 139540) +p(137609, 109260) +p(18861, 131772) +p(131772, 131772) +p(5245, 38036) +p(153476, 122844) +p(39657, 196596) +p(162856, 46672) +p(106001, 195336) +p(26676, 21732) +p(116833, 84712) +p(135424, 65204) +p(100013, 19696) +p(131120, 113048) +p(61649, 7080) +p(95768, 49000) +p(40173, 52396) +p(152792, 191548) +p(105933, 20180) +p(36412, 88884) +p(168781, 123720) +p(120704, 111880) +p(42305, 8340) +p(38184, 185924) +p(104761, 86556) +p(47564, 26196) +p(14508, 49484) +p(130865, 118288) +p(212528, 18920) +p(8073, 37744) +p(155336, 76076) +p(171941, 174084) +p(19749, 112857) +p(65124, 114509) +p(94045, 58713) +p(27728, 139349) +p(20845, 34841) +p(126872, 27949) +p(104192, 46873) +p(75473, 214069) +p(68832, 116837) +p(89828, 102085) +p(43061, 20189) +p(181204, 76953) +p(3437, 115285) +p(143616, 118097) +p(118877, 172633) +p(57485, 57161) +p(181460, 140417) +p(140417, 140417) +p(180552, 110045) +p(35585, 6989) +p(128020, 18345) +p(168981, 85205) +p(214156, 2333) +p(95873, 155461) +p(18492, 187577) +p(184145, 84329) +p(177020, 167009) +p(121909, 91605) +p(157972, 54249) +p(96261, 5729) +p(168804, 168753) +p(97005, 18729) +p(103656, 193985) +p(104925, 16693) +p(69464, 78797) +p(157585, 100633) +p(156768, 113925) +p(44209, 199417) +p(104044, 36293) +p(165500, 88017) +p(158717, 78121) +p(160128, 17569) +p(65521, 193109) +p(83820, 146141) +p(42393, 13881) +p(141629, 198700) +p(209708, 15000) +p(33885, 41492) +p(137676, 59932) +p(109733, 175020) +p(28472, 142220) +p(12761, 4136) +p(154784, 203356) +p(111805, 203648) +p(36460, 71964) +p(100609, 173952) +p(92032, 69152) +p(68649, 28008) +p(200000, 129704) +p(203013, 22768) +p(200544, 200544) +p(72749, 186860) +p(75812, 18788) +p(28853, 50228) +p(149532, 207044) +p(84033, 39748) +p(17816, 117672) +p(187641, 94476) +p(18652, 83612) +p(77469, 170848) +p(199116, 177832) +p(93057, 189772) +p(70504, 165024) +p(47317, 98456) +p(86868, 50520) +p(208976, 101076) +p(75457, 148628) +p(6712, 144164) +p(85609, 180552) +p(45492, 182688) +p(62581, 107384) +p(104629, 107868) +p(167660, 151248) +p(42293, 204232) +p(57981, 125733) +p(117716, 213745) +p(154989, 143297) +p(111184, 196181) +p(153113, 94485) +p(197128, 55477) +p(34397, 120685) +p(97144, 38297) +p(23301, 210933) +p(64504, 191425) +p(208229, 170465) +p(189748, 176773) +p(155209, 39657) +p(54440, 11905) +p(123345, 66149) +p(203356, 97297) +p(97297, 97297) +p(98324, 102829) +p(117741, 85657) +p(23764, 101669) +p(136241, 144657) +p(6268, 80801) +p(185213, 82645) +p(28748, 185801) +p(168393, 178909) +p(20656, 205985) +p(56569, 133009) +p(204808, 183957) +p(185117, 125925) +p(199144, 121945) +p(193448, 148437) +p(199765, 82353) +p(168476, 202973) +p(71249, 72749) +p(105560, 132525) +p(190285, 114961) +p(36217, 65373) +p(131564, 47033) +p(94209, 26557) +p(61377, 160720) +p(212236, 101236) +p(81821, 77756) +p(178044, 188380) +p(100129, 171884) +p(95916, 2936) +p(183645, 97064) +p(24752, 109872) +p(194093, 126368) +p(112832, 107060) +p(136129, 17204) +p(102896, 30396) +p(95141, 131608) +p(82192, 186536) +p(202529, 128020) +p(91664, 12740) +p(191425, 84064) +p(84064, 84064) +p(61945, 139468) +p(182716, 201480) +p(13877, 115888) +p(38484, 84840) +p(134465, 80376) +p(122100, 124916) +p(44961, 125208) +p(25804, 180128) +p(162053, 19824) +p(169288, 163148) +p(201997, 42044) +p(11372, 70572) +p(5676, 162856) +p(92829, 1092) +p(75416, 75036) +p(95897, 174504) +p(6192, 68728) +p(41713, 208272) +p(112005, 99492) +p(45004, 142380) +p(29001, 131416) +p(71181, 83681) +p(20776, 186445) +p(100745, 145885) +p(140000, 65925) +p(206577, 51173) +p(193144, 197217) +p(62756, 168689) +p(9389, 54569) +p(120656, 25265) +p(81165, 186545) +p(30760, 183633) +p(117329, 30697) +p(198800, 206821) +p(76345, 50105) +p(96488, 73977) +p(45649, 7017) +p(9704, 198869) +p(75989, 136665) +p(6660, 97657) +p(26461, 122981) +p(134716, 28853) +p(207044, 6925) +p(197249, 163157) +p(18364, 172377) +p(172377, 172377) +p(89848, 56897) +p(118777, 69221) +p(119097, 198285) +p(117504, 101053) +p(149245, 11389) +p(76520, 211869) +p(1709, 2845) +p(186236, 200029) +p(64096, 96489) +p(94085, 148505) +p(208064, 14685) +p(146453, 195181) +p(76156, 118517) +p(62581, 168981) +p(162392, 68637) +p(75841, 42537) +p(197780, 124533) +p(107441, 180621) +p(95660, 174997) +p(144573, 204493) +p(14025, 110716) +p(184384, 211344) +p(12049, 182816) +p(75176, 169908) +p(88769, 197368) +p(57872, 152052) +p(103900, 181748) +p(5509, 211928) +p(152772, 26676) +p(168309, 181164) +p(182336, 4748) +p(55417, 88588) +p(140092, 81604) +p(203857, 185436) +p(86784, 184852) +p(59909, 65008) +p(49780, 170876) +p(164101, 175732) +p(205880, 190384) +p(108073, 88688) +p(138020, 204068) +p(30044, 181356) +p(75661, 36088) +p(161404, 123424) +p(197217, 98876) +p(98876, 98876) +p(40077, 114112) +p(46997, 172720) +p(141276, 67044) +p(71221, 15812) +p(195780, 91500) +p(33441, 169324) +p(88812, 142832) +p(170932, 149532) +p(87001, 166704) +p(179536, 37448) +p(121029, 144484) +p(202308, 76848) +p(118185, 177576) +p(120080, 128664) +p(157061, 105084) +p(110828, 84416) +p(85605, 32792) +p(39864, 64232) +p(144381, 46084) +p(83505, 138669) +p(162356, 99369) +p(67553, 102181) +p(72556, 180297) +p(22009, 119553) +p(13524, 121689) +p(195116, 42889) +p(41121, 175641) +p(193140, 189225) +p(21197, 74329) +p(163220, 126053) +p(214369, 137893) +p(47224, 203493) +p(191725, 73069) +p(136956, 95873) +p(169373, 75397) +p(64140, 75013) +p(192821, 98009) +p(84484, 72585) +p(68481, 213681) +p(113372, 63849) +p(16168, 151961) +p(170465, 43181) +p(80376, 100337) +p(21577, 34253) +p(170976, 61037) +p(61037, 61037) +p(51461, 66861) +p(163888, 150509) +p(166033, 16789) +p(145224, 56381) +p(199769, 60745) +p(119768, 34737) +p(146384, 210961) +p(75069, 136241) +p(174780, 148273) +p(35929, 164385) +p(169216, 87529) +p(45793, 29889) +p(27120, 43281) +p(152405, 174765) +p(179824, 33185) +p(19913, 111209) +p(78772, 128673) +p(156997, 124017) +p(156281, 26644) +p(94428, 115048) +p(96473, 64976) +p(128456, 23832) +p(208909, 150952) +p(190044, 47412) +p(125321, 76424) +p(34932, 82732) +p(10393, 23732) +p(211485, 211988) +p(175540, 159396) +p(73077, 88556) +p(55180, 214316) +p(102349, 200248) +p(213416, 64392) +p(132493, 41296) +p(114012, 63132) +p(175641, 126888) +p(126888, 126888) +p(130677, 41588) +p(197888, 70892) +p(106116, 213156) +p(190741, 111944) +p(110548, 140280) +p(126296, 35280) +p(179481, 4032) +p(59404, 185888) +p(150748, 141248) +p(52457, 169100) +p(45140, 194040) +p(59021, 91076) +p(194928, 174824) +p(9885, 170552) +p(72733, 137277) +p(173320, 100013) +p(50381, 211705) +p(196092, 168041) +p(209101, 24709) +p(28472, 103217) +p(165589, 67605) +p(17468, 111853) +p(43193, 132229) +p(110081, 87105) +p(209116, 173373) +p(21837, 210153) +p(15004, 110977) +p(80321, 184829) +p(168584, 56057) +p(28853, 125437) +p(161172, 35289) +p(142649, 118061) +p(17816, 187641) +p(187641, 187641) +p(174400, 182693) +p(70504, 149893) +p(47317, 132521) +p(86868, 205689) +p(161332, 89533) +p(75457, 79537) +p(6712, 208893) +p(123580, 94097) +p(94085, 176385) +p(153528, 155809) +p(175077, 198313) +p(167660, 67021) +p(58789, 87205) +p(57981, 108608) +p(117716, 10500) +p(154989, 29132) +p(60236, 89592) +p(153113, 166640) +p(197128, 119964) +p(182861, 13028) +p(118096, 199924) +p(2725, 91144) +p(59909, 24284) +p(136048, 94732) +p(37557, 166832) +p(205880, 69792) +p(108073, 81732) +p(138020, 43400) +p(24681, 150528) +p(114112, 128500) +p(128673, 83476) +p(26644, 68724) +p(167649, 104244) +p(104244, 104244) +p(168904, 87356) +p(194429, 149268) +p(39224, 113072) +p(108348, 45436) +p(113789, 36992) +p(122092, 163244) +p(76420, 142284) +p(60509, 116468) +p(76964, 172948) +p(172265, 118604) +p(177948, 34180) +p(54233, 105796) +p(83505, 88141) +p(102872, 15457) +p(67553, 40397) +p(133696, 107257) +p(129533, 39621) +p(73888, 156845) +p(139689, 133557) +p(153232, 11577) +p(79389, 182369) +p(66832, 101633) +p(138941, 45253) +p(45448, 15073) +p(144825, 76401) +p(52892, 85329) +p(173129, 200901) +p(195116, 124437) +p(41121, 199349) +p(169660, 5853) +p(74081, 20697) +p(59580, 170045) +p(86957, 38069) +p(47808, 124529) +p(109337, 99981) +p(101436, 142193) +p(159669, 70869) +p(211060, 148209) +p(62981, 164997) +p(186664, 208761) +p(134657, 49909) +p(107056, 144713) +p(147525, 51269) +p(25312, 204005) +p(169713, 201193) +p(93984, 104253) +p(131541, 10317) +p(45816, 146849) +p(80173, 139089) +p(113124, 13129) +p(38413, 55049) +p(114361, 192708) +p(147704, 205424) +p(78325, 207944) +p(128456, 19980) +p(132245, 80340) +p(91352, 102852) +p(34105, 141276) +p(121692, 40164) +p(142369, 81600) +p(153976, 134584) +p(116913, 210756) +p(152000, 167868) +p(83981, 31528) +p(139352, 102268) +p(136449, 41524) +p(62656, 148944) +p(56357, 125556) +p(77084, 146424) +p(185289, 173300) +p(136728, 211632) +p(101609, 114884) +p(174928, 32596) +p(37821, 199116) +p(137632, 131572) +p(198385, 175436) +p(29304, 174468) +p(81905, 2124) +p(126888, 163988) +p(130677, 109644) +p(136360, 97804) +p(413, 26188) +p(178340, 136912) +p(212801, 38220) +p(174428, 169904) +p(40909, 201736) +p(186620, 44820) +p(59021, 111972) +p(194928, 129344) +p(139625, 47056) +p(16937, 136045) +p(116748, 75301) +p(132377, 124205) +p(172412, 36193) +p(42097, 125565) +p(38176, 116737) +p(184521, 198149) +p(60656, 16785) +p(202145, 101793) +p(130104, 147885) +p(126425, 80249) +p(133176, 166709) +p(125417, 107809) +p(74528, 33381) +p(19125, 41917) +p(35872, 199025) +p(152137, 56569) +p(184020, 51037) +p(80873, 154869) +p(97912, 48225) +p(196513, 104897) +p(100792, 77529) +p(151065, 49101) +p(7308, 71221) +p(130365, 162537) +p(187572, 187285) +p(20677, 207853) +p(76424, 145073) +p(104185, 156813) +p(133256, 93057) +p(171297, 152249) +p(101876, 84613) +p(133709, 166417) +p(123580, 202421) +p(131833, 130321) +p(77256, 31437) +p(75809, 31145) +p(167660, 122753) +p(42293, 40073) +p(57981, 106116) +p(117716, 6072) +p(154989, 182488) +p(59909, 165992) +p(136048, 125332) +p(37557, 38480) +p(205880, 151340) +p(27337, 77396) +p(138020, 85156) +p(30044, 58664) +p(178909, 170940) +p(161404, 70796) +p(58956, 58956) +p(194429, 195780) +p(56688, 135328) +p(202476, 17520) +p(82349, 2868) +p(209328, 129504) +p(46505, 211208) +p(116044, 23536) +p(151665, 139500) +p(167440, 194328) +p(124845, 76520) +p(188268, 192968) +p(185949, 155996) +p(54224, 126692) +p(1249, 146968) +p(127461, 167745) +p(21068, 178125) +p(76581, 13741) +p(177133, 122429) +p(75788, 172501) +p(178753, 138049) +p(141932, 88269) +p(13461, 214713) +p(101824, 123105) +p(62360, 2485) +p(23745, 73809) +p(163148, 201997) +p(203256, 211609) +p(211609, 211609) +p(50672, 197049) +p(76224, 105933) +p(131253, 95937) +p(47856, 123981) +p(41849, 5981) +p(145540, 163573) +p(175053, 127569) +p(27120, 134169) +p(152405, 68961) +p(67648, 185117) +p(76777, 44313) +p(78772, 18013) +p(156997, 8501) +p(156281, 93660) +p(153912, 183132) +p(78325, 134420) +p(83589, 203800) +p(29304, 148004) +p(81905, 86868) +p(38976, 28452) +p(16757, 154120) +p(154808, 142280) +p(33440, 88036) +p(142037, 160812) +p(30396, 57564) +p(75160, 30488) +p(116897, 52032) +p(52032, 52032) +p(1604, 36020) +p(128441, 209916) +p(47956, 54168) +p(6721, 103656) +p(81400, 118308) +p(10569, 20400) +p(3248, 52516) +p(34697, 66684) +p(105204, 107152) +p(10501, 147420) +p(196388, 15836) +p(205901, 211468) +p(151817, 130157) +p(155080, 92117) +p(70857, 177417) +p(65837, 141997) +p(63468, 90757) +p(91229, 78433) +p(9968, 145293) +p(198425, 209925) +p(166068, 154321) +p(160937, 181589) +p(33484, 168781) +p(164493, 133261) +p(91476, 99785) +p(130009, 150049) +p(140156, 73193) +p(183929, 150925) +p(25136, 33701) +p(96561, 12349) +p(113285, 166937) +p(173312, 179937) +p(105585, 182073) +p(171021, 2937) +p(18920, 30013) +p(10485, 48161) +p(57312, 152669) +p(148437, 140829) +p(34476, 168389) +p(23248, 206721) +p(205981, 130641) +p(163244, 114337) +p(117545, 8469) +p(102268, 49129) +p(80925, 36029) +p(40608, 9829) +p(92049, 198085) +p(2344, 121329) +p(188665, 132969) +p(23656, 185953) +p(159521, 138017) +p(76485, 152769) +p(63344, 21377) +p(82469, 124141) +p(52065, 203476) +p(185744, 151852) +p(93661, 171360) +p(191505, 167380) +p(39212, 172328) +p(75901, 24248) +p(214428, 119636) +p(82369, 46760) +p(187128, 190084) +p(203049, 10856) +p(166328, 64908) +p(121797, 107504) +p(1812, 152920) +p(6477, 93144) +p(41564, 16580) +p(21097, 174948) +p(119264, 57724) +p(200201, 37732) +p(68937, 201632) +p(75788, 204836) +p(11065, 69464) +p(18861, 145836) +p(131772, 116532) +p(5245, 107896) +p(172692, 81404) +p(39657, 43072) +p(204292, 73444) +p(174824, 90716) +p(137277, 2220) +p(91144, 83632) +p(27589, 186012) +p(95768, 157676) +p(40173, 179220) +p(52256, 568) +p(204809, 91884) +p(119176, 152144) +p(14093, 205904) +p(7552, 175140) +p(150401, 134388) +p(8073, 188340) +p(155336, 17648) +p(171941, 172620) +p(140369, 56957) +p(65124, 52009) +p(161681, 178161) +p(43425, 51617) +p(138288, 112561) +p(165273, 197761) +p(181144, 113337) +p(949, 141965) +p(208672, 189801) +p(121245, 52201) +p(111792, 59577) +p(124609, 9405) +p(165520, 76657) +p(45393, 142057) +p(99596, 168457) +p(51569, 117801) +p(39788, 19209) +p(111505, 1837) +p(94845, 79953) +p(81996, 145745) +p(117617, 184661) +p(205565, 60645) +p(126148, 4557) +p(209413, 158169) +p(23544, 107513) +p(190557, 173597) +p(131608, 15813) +p(29748, 213965) +p(29565, 162925) +p(136360, 119353) +p(124529, 145845) +p(54816, 10865) +p(122753, 64817) +p(32264, 198729) +p(36737, 171269) +p(54160, 3781) +p(77073, 121781) +p(85668, 201933) +p(116433, 95289) +p(175561, 198829) +p(194928, 189417) +p(139625, 18433) +p(21009, 42264) +p(100544, 14704) +p(167797, 206840) +p(72921, 191220) +p(60656, 54588) +p(111805, 129500) +p(101741, 62448) +p(105580, 33336) +p(152357, 85152) +p(75437, 175208) +p(177092, 50608) +p(21837, 136392) +p(99136, 91752) +p(80321, 138528) +p(209728, 108348) +p(169077, 208100) +p(108192, 65452) +p(34841, 49732) +p(161332, 161332) +p(150953, 208976) +p(6712, 182192) +p(85609, 139304) +p(45492, 180348) +p(164569, 46920) +p(165081, 67688) +p(30936, 70016) +p(161845, 100872) +p(138041, 148141) +p(117716, 158621) +p(154989, 105345) +p(207709, 131061) +p(106264, 186473) +p(81333, 126305) +p(199941, 137853) +p(111496, 117185) +p(145665, 16165) +p(18765, 161141) +p(61328, 140281) +p(16213, 119221) +p(29948, 87973) +p(361, 52653) +p(112788, 80989) +p(89601, 196077) +p(117512, 2581) +p(143329, 63617) +p(91752, 14321) +p(14321, 14321) +p(42616, 113789) +p(129765, 87297) +p(211428, 83801) +p(56273, 3841) +p(49217, 78269) +p(29092, 84869) +p(203089, 149693) +p(61377, 3900) +p(212236, 84928) +p(81821, 46112) +p(84277, 118696) +p(67640, 150720) +p(211173, 192156) +p(95141, 53872) +p(83260, 130244) +p(53089, 198948) +p(151517, 126848) +p(39008, 164404) +p(187581, 21072) +p(24708, 206516) +p(68481, 45044) +p(113372, 191672) +p(136277, 191864) +p(105672, 73864) +p(18729, 87256) +p(112712, 75416) +p(38585, 189052) +p(189052, 189052) +p(191577, 47856) +p(42680, 124228) +p(203285, 138880) +p(149069, 155376) +p(60240, 131312) +p(23761, 47564) +p(193253, 112881) +p(20776, 150629) +p(35729, 85805) +p(202569, 69701) +p(167884, 29041) +p(62117, 18169) +p(168209, 124237) +p(192524, 204197) +p(198649, 46505) +p(177717, 4877) +p(20860, 140149) +p(54737, 84837) +p(44700, 53397) +p(174257, 214577) +p(90568, 185273) +p(2657, 169453) +p(38712, 140633) +p(32997, 127049) +p(50520, 68341) +p(28985, 60673) +p(2936, 212349) +p(211869, 202545) +p(87520, 171297) +p(97525, 190321) +p(64392, 72513) +p(172989, 177705) +p(110936, 62225) +p(90569, 48057) +p(207360, 181777) +p(130321, 105605) +p(176472, 24093) +p(2777, 37969) +p(9528, 65237) +p(30593, 30593) +p(187076, 117637) +p(46281, 188669) +p(162565, 120449) +p(142240, 6721) +p(128081, 159657) +p(206348, 177121) +p(54589, 116469) +p(25728, 27197) +p(10985, 67465) +p(5512, 83093) +p(122353, 2549) +p(191801, 204540) +p(194380, 198332) +p(140337, 173392) +p(28481, 134384) +p(61916, 181736) +p(146349, 22108) +p(191889, 173492) +p(148568, 172716) +p(97045, 174652) +p(182665, 91104) +p(190776, 122252) +p(185061, 57720) +p(186088, 34240) +p(52177, 190764) +p(46704, 213860) +p(128125, 80524) +p(6596, 10660) +p(107233, 172032) +p(66240, 154376) +p(202973, 117596) +p(22828, 104688) +p(183633, 135160) +p(142832, 202796) +p(198253, 23952) +p(94280, 134968) +p(202101, 39380) +p(160140, 91588) +p(141901, 116528) +p(125556, 31812) +p(172241, 149036) +p(129504, 130888) +p(181037, 164464) +p(174788, 25212) +p(202737, 140208) +p(140208, 140208) +p(91497, 207552) +p(52325, 31228) +p(33944, 48600) +p(122065, 152432) +p(173456, 99448) +p(107573, 123128) +p(119372, 110704) +p(157613, 101584) +p(126032, 19972) +p(161461, 199884) +p(115621, 127693) +p(142756, 139825) +p(70565, 116145) +p(203829, 133325) +p(141100, 46281) +p(113, 92181) +p(28181, 72773) +p(86172, 32789) +p(7481, 141185) +p(87277, 117989) +p(63172, 189705) +p(8353, 54433) +p(134656, 200961) +p(59261, 35701) +p(131128, 76845) +p(57677, 143997) +p(195336, 57245) +p(193501, 86941) +p(204424, 60057) +p(187937, 82961) +p(166060, 169521) +p(40693, 210665) +p(81604, 169713) +p(181365, 151373) +p(67788, 95577) +p(101373, 64521) +p(103760, 124105) +p(10317, 42009) +p(162628, 65689) +p(81317, 44629) +p(212860, 57537) +p(87977, 194169) +p(129956, 51905) +p(43209, 208045) +p(200368, 56469) +p(56469, 56469) +p(42913, 39581) +p(172420, 145549) +p(66269, 170973) +p(114164, 137013) +p(185881, 178157) +p(115876, 100425) +p(50285, 101593) +p(207352, 19789) +p(174461, 59381) +p(68853, 57104) +p(182832, 59340) +p(152077, 76420) +p(198297, 64288) +p(173900, 176172) +p(170897, 202372) +p(128717, 137940) +p(205624, 200920) +p(133341, 62344) +p(125025, 131732) +p(20184, 123580) +p(177977, 40416) +p(124533, 129112) +p(83448, 64964) +p(72585, 158224) +p(213156, 129788) +p(36549, 76128) +p(29132, 164432) +p(159753, 150748) +p(14836, 3736) +p(157585, 32264) +p(32848, 32848) +p(55269, 165500) +p(160128, 152884) +p(42617, 107276) +p(49276, 37796) +p(179409, 100484) +p(42361, 190541) +p(56388, 120577) +p(181381, 131541) +p(165013, 178901) +p(136152, 75069) +p(70561, 145517) +p(207609, 139985) +p(30760, 96029) +p(204273, 214221) +p(210709, 80209) +p(9704, 60509) +p(89473, 8109) +p(2845, 105925) +p(87520, 210341) +p(149733, 11213) +p(70800, 131833) +p(94097, 94085) +p(71636, 41877) +p(140929, 122905) +p(64908, 199177) +p(48513, 31013) +p(6356, 7525) +p(7525, 7525) +p(56104, 202673) +p(197397, 205485) +p(154660, 37805) +p(163497, 199469) +p(54101, 172160) +p(38240, 147904) +p(35437, 160128) +p(101357, 207580) +p(61916, 97832) +p(67457, 189048) +p(183929, 183224) +p(88792, 190116) +p(57845, 121120) +p(131233, 97732) +p(95288, 107144) +p(99569, 152268) +p(50105, 183808) +p(115080, 136064) +p(213973, 138976) +p(74972, 76964) +p(125437, 176916) +p(92112, 179536) +p(198085, 2344) +p(143316, 10396) +p(50549, 112776) +p(123580, 57656) +p(131833, 12632) +p(12632, 12632) +p(165081, 33300) +p(30936, 97440) +p(120701, 165468) +p(31489, 170325) +p(15828, 132869) +p(207973, 187597) +p(212949, 148881) +p(155560, 208657) +p(103261, 150433) +p(64504, 74061) +p(32297, 150725) +p(113668, 64941) +p(84273, 189249) +p(156140, 15645) +p(150133, 163533) +p(80512, 144417) +p(24333, 67753) +p(96784, 194005) +p(38661, 98709) +p(147016, 91433) +p(198549, 115113) +p(63405, 34861) +p(120328, 65817) +p(142073, 126753) +p(32856, 187213) +p(162121, 9145) +p(166060, 66593) +p(80869, 131993) +p(81604, 95897) +p(181365, 214089) +p(146849, 113361) +p(138564, 3613) +p(80249, 68437) +p(151340, 35637) +p(191617, 211277) +p(37864, 35929) +p(183433, 49705) +p(19392, 181973) +p(146329, 76197) +p(86320, 16421) +p(108449, 13993) +p(115200, 79885) +p(112297, 14093) +p(80524, 3805) +p(35217, 42913) +p(30105, 30105) +p(122832, 178669) +p(209693, 6133) +p(172749, 108121) +p(143404, 205161) +p(174461, 179353) +p(68853, 71984) +p(210876, 86928) +p(118985, 137484) +p(63901, 60436) +p(15532, 211428) +p(170897, 145052) +p(150964, 48988) +p(3085, 166112) +p(196832, 50924) +p(104457, 173196) +p(176324, 33944) +p(108597, 23656) +p(87888, 198620) +p(105945, 210360) +p(1780, 143792) +p(44777, 195416) +p(178648, 157476) +p(51053, 2212) +p(32641, 126812) +p(198444, 104492) +p(93937, 45492) +p(107868, 207548) +p(58873, 22204) +p(151308, 84500) +p(1393, 127588) +p(110716, 193964) +p(78409, 51508) +p(179649, 180764) +p(136912, 69172) +p(25421, 205120) +p(179576, 16864) +p(214713, 22104) +p(184976, 157376) +p(17589, 48696) +p(67720, 167472) +p(171269, 124776) +p(67204, 40736) +p(131837, 85668) +p(95016, 26084) +p(200801, 107304) +p(107600, 130984) +p(117989, 19000) +p(203901, 122156) +p(122156, 122156) +p(212313, 141464) +p(42617, 93720) +p(201628, 209876) +p(93825, 92652) +p(42361, 41713) +p(1268, 203285) +p(181381, 167381) +p(62833, 17457) +p(18344, 10273) +p(93949, 45793) +p(68968, 89749) +p(53257, 208525) +p(213912, 36765) +p(16345, 56949) +p(200872, 138461) +p(157893, 63257) +p(77700, 71993) +p(117785, 66269) +p(120656, 204937) +p(207609, 61897) +p(30760, 209693) +p(34165, 179705) +p(45649, 183201) +p(10964, 68205) +p(134597, 190285) +p(83612, 19301) +p(47033, 48797) +p(67276, 197853) +p(123465, 91693) +p(64232, 191545) +p(54145, 113621) +p(73681, 122065) +p(90136, 19493) +p(154777, 174173) +p(24412, 41621) +p(178125, 124585) +p(42328, 79853) +p(152769, 29681) +p(15996, 15029) +p(3973, 24833) +p(14412, 162333) +p(64493, 207165) +p(207876, 116241) +p(181777, 54137) +p(86932, 130893) +p(167677, 186597) +p(109289, 164569) +p(76156, 62581) +p(62581, 62581) +p(165081, 5617) +p(211040, 75097) +p(127493, 4841) +p(138041, 162292) +p(117716, 81264) +p(154989, 12468) +p(181213, 175392) +p(123140, 128624) +p(207281, 148124) +p(89601, 75832) +p(88884, 63024) +p(42601, 101356) +p(110296, 116784) +p(102829, 11400) +p(99492, 116976) +p(148113, 176268) +p(88688, 196744) +p(82873, 53612) +p(189284, 7228) +p(59453, 27120) +p(162952, 168992) +p(100753, 114164) +p(188340, 137644) +p(119645, 93104) +p(203321, 135900) +p(202796, 59236) +p(71121, 67196) +p(49217, 205572) +p(29092, 120080) +p(203089, 14212) +p(61377, 11501) +p(106268, 208301) +p(44365, 136685) +p(171509, 31785) +p(64140, 9949) +p(166137, 122809) +p(152581, 137461) +p(184272, 189861) +p(193985, 54589) +p(150372, 152989) +p(147177, 117469) +p(201480, 5877) +p(30889, 208201) +p(169908, 187049) +p(100337, 81081) +p(158520, 34697) +p(9089, 46437) +p(107056, 127657) +p(157909, 8497) +p(90716, 90785) +p(11057, 16257) +p(156353, 92921) +p(96636, 154149) +p(169713, 11017) +p(43785, 140273) +p(33164, 35181) +p(183489, 180741) +p(214121, 123928) +p(68904, 179824) +p(164985, 108792) +p(160253, 165172) +p(189032, 18936) +p(128581, 139748) +p(135501, 203796) +p(34348, 92196) +p(126349, 103360) +p(122136, 23884) +p(205401, 188268) +p(126368, 147608) +p(200029, 9524) +p(87520, 38828) +p(73845, 110344) +p(64876, 137320) +p(187449, 119372) +p(33596, 180892) +p(159461, 4376) +p(172328, 47656) +p(119353, 44552) +p(188669, 72012) +p(35308, 36400) +p(49869, 48240) +p(10885, 55032) +p(128168, 188752) +p(202605, 118012) +p(109897, 63485) +p(80068, 103853) +p(81629, 9141) +p(163392, 59021) +p(120505, 53197) +p(203436, 212149) +p(28481, 17877) +p(61916, 117921) +p(146349, 54457) +p(71488, 167025) +p(8617, 65521) +p(54960, 131121) +p(81653, 189729) +p(180596, 169937) +p(148773, 132573) +p(192688, 203121) +p(207933, 32529) +p(140740, 9725) +p(1689, 69109) +p(27464, 88617) +p(22133, 201569) +p(133976, 197981) +p(78965, 145773) +p(139576, 116953) +p(182665, 200209) +p(190776, 43785) +p(196217, 176245) +p(141640, 80173) +p(206081, 19913) +p(182460, 24377) +p(142293, 143445) +p(150404, 188469) +p(107233, 8073) +p(199184, 5261) +p(123113, 213409) +p(179352, 37377) +p(183633, 172749) +p(142832, 67849) +p(198253, 152565) +p(94280, 73965) +p(202101, 61057) +p(116468, 77361) +p(17885, 47181) +p(173300, 122093) +p(201837, 36217) +p(65748, 49217) +p(84097, 17293) +p(183424, 196329) +p(33217, 64937) +p(159036, 172265) +p(142057, 3317) +p(29356, 91529) +p(15681, 147225) +p(153824, 157997) +p(127049, 176629) +p(107016, 185949) +p(159817, 213893) +p(150072, 38837) +p(133193, 135485) +p(67944, 76485) +p(158485, 66297) +p(52384, 35341) +p(24833, 2641) +p(15280, 157613) +p(163953, 115109) +p(43968, 141601) +p(141601, 141601) +p(126032, 150429) +p(57045, 137913) +p(4029, 87024) +p(150516, 204148) +p(7393, 177656) +p(198520, 72080) +p(156701, 73148) +p(194892, 30544) +p(191505, 119916) +p(39212, 30936) +p(184681, 211040) +p(214428, 187360) +p(126517, 68876) +p(202072, 167660) +p(203049, 165624) +p(154488, 95660) +p(123641, 192600) +p(150868, 57328) +p(6477, 45588) +p(41564, 164848) +p(21097, 114192) +p(2424, 42192) +p(154785, 154368) +p(72940, 176688) +p(156497, 30352) +p(87076, 196480) +p(80777, 5512) +p(213872, 1048) +p(98693, 125064) +p(147756, 128168) +p(66929, 154660) +p(201576, 196388) +p(212357, 75184) +p(196596, 194928) +p(105289, 55584) +p(131064, 163296) +p(87401, 158248) +p(67760, 83820) +p(78249, 13756) +p(81604, 16184) +p(181365, 60532) +p(67788, 40248) +p(88565, 169312) +p(186240, 68684) +p(134525, 60240) +p(178540, 66064) +p(166709, 45004) +p(77396, 37628) +p(154545, 172708) +p(37864, 157472) +p(183433, 52088) +p(19392, 191340) +p(146329, 104196) +p(62448, 27540) +p(22281, 22200) +p(157028, 33748) +p(71153, 113124) +p(55684, 78772) +p(35217, 130980) +p(108244, 25012) +p(67401, 155336) +p(308, 89544) +p(6133, 14924) +p(183868, 207352) +p(42297, 60140) +p(155600, 143404) +p(51093, 43744) +p(173616, 124480) +p(61057, 10068) +p(10068, 10068) +p(65681, 111864) +p(196457, 212209) +p(143240, 136813) +p(180997, 146809) +p(148348, 12989) +p(202309, 36669) +p(7412, 108477) +p(15573, 26573) +p(65120, 54233) +p(129561, 144381) +p(102836, 156413) +p(6481, 1249) +p(129196, 130505) +p(130173, 106149) +p(156816, 82469) +p(87445, 168929) +p(74496, 16385) +p(174165, 201345) +p(130844, 2509) +p(95141, 161461) +p(203880, 181) +p(53089, 106049) +p(13356, 74125) +p(178817, 153601) +p(36420, 19005) +p(48461, 94309) +p(0, 161845) +p(115581, 160685) +p(24708, 151173) +p(144561, 58789) +p(117060, 144573) +p(96009, 86641) +p(70928, 204641) +p(5729, 200177) +p(127760, 112841) +p(143297, 195421) +p(73000, 51029) +p(207113, 107117) +p(182716, 27641) +p(13877, 141761) +p(38484, 122353) +p(137469, 20949) +p(117636, 35601) +p(3041, 66557) +p(44820, 130797) +p(162053, 177665) +p(169288, 204057) +p(201997, 163497) +p(11372, 205901) +p(127829, 101001) +p(53552, 93049) +p(184177, 106825) +p(209560, 147969) +p(133873, 71697) +p(30100, 95277) +p(139373, 139625) +p(134384, 4545) +p(35701, 164273) +p(138908, 62869) +p(130765, 24537) +p(97832, 9885) +p(24089, 42393) +p(124968, 67817) +p(76065, 198433) +p(36048, 179409) +p(11017, 93825) +p(66872, 104305) +p(9725, 182713) +p(121860, 212793) +p(212793, 212793) diff --git a/src/wasm-lib/tests/executor/main.rs b/src/wasm-lib/tests/executor/main.rs index d82f3095f..33cec2614 100644 --- a/src/wasm-lib/tests/executor/main.rs +++ b/src/wasm-lib/tests/executor/main.rs @@ -542,6 +542,82 @@ const pt2 = b2.value[0] ); } +#[tokio::test(flavor = "multi_thread")] +async fn serial_test_helix_defaults() { + let code = r#"const part001 = startSketchOn('XY') + |> circle([5, 5], 10, %) + |> extrude(10, %) + |> helix({revolutions: 16, angle_start: 0}, %) +"#; + + let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm) + .await + .unwrap(); + twenty_twenty::assert_image("tests/executor/outputs/helix_defaults.png", &result, 1.0); +} + +#[tokio::test(flavor = "multi_thread")] +async fn serial_test_helix_defaults_negative_extrude() { + let code = r#"const part001 = startSketchOn('XY') + |> circle([5, 5], 10, %) + |> extrude(-10, %) + |> helix({revolutions: 16, angle_start: 0}, %) +"#; + + let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm) + .await + .unwrap(); + twenty_twenty::assert_image( + "tests/executor/outputs/helix_defaults_negative_extrude.png", + &result, + 1.0, + ); +} + +#[tokio::test(flavor = "multi_thread")] +async fn serial_test_helix_ccw() { + let code = r#"const part001 = startSketchOn('XY') + |> circle([5, 5], 10, %) + |> extrude(10, %) + |> helix({revolutions: 16, angle_start: 0, ccw: true}, %) +"#; + + let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm) + .await + .unwrap(); + twenty_twenty::assert_image("tests/executor/outputs/helix_ccw.png", &result, 1.0); +} + +#[tokio::test(flavor = "multi_thread")] +async fn serial_test_helix_with_length() { + let code = r#"const part001 = startSketchOn('XY') + |> circle([5, 5], 10, %) + |> extrude(10, %) + |> helix({revolutions: 16, angle_start: 0, length: 3}, %) +"#; + + let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm) + .await + .unwrap(); + twenty_twenty::assert_image("tests/executor/outputs/helix_with_length.png", &result, 1.0); +} + +#[tokio::test(flavor = "multi_thread")] +async fn serial_test_dimensions_match() { + let code = r#"const part001 = startSketchOn('XY') + |> startProfileAt([-10, -10], %) + |> line([20, 0], %) + |> line([0, 20], %) + |> line([-20, 0], %) + |> close(%) +"#; + + let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm) + .await + .unwrap(); + twenty_twenty::assert_image("tests/executor/outputs/dimensions_match.png", &result, 1.0); +} + #[tokio::test(flavor = "multi_thread")] async fn serial_test_close_arc() { let code = r#"const center = [0,0] diff --git a/src/wasm-lib/tests/executor/outputs/dimensions_match.png b/src/wasm-lib/tests/executor/outputs/dimensions_match.png new file mode 100644 index 000000000..02b09535d Binary files /dev/null and b/src/wasm-lib/tests/executor/outputs/dimensions_match.png differ diff --git a/src/wasm-lib/tests/executor/outputs/helix_ccw.png b/src/wasm-lib/tests/executor/outputs/helix_ccw.png new file mode 100644 index 000000000..38c894abc Binary files /dev/null and b/src/wasm-lib/tests/executor/outputs/helix_ccw.png differ diff --git a/src/wasm-lib/tests/executor/outputs/helix_defaults.png b/src/wasm-lib/tests/executor/outputs/helix_defaults.png new file mode 100644 index 000000000..ccd6f0a19 Binary files /dev/null and b/src/wasm-lib/tests/executor/outputs/helix_defaults.png differ diff --git a/src/wasm-lib/tests/executor/outputs/helix_defaults_negative_extrude.png b/src/wasm-lib/tests/executor/outputs/helix_defaults_negative_extrude.png new file mode 100644 index 000000000..ec95f1c3c Binary files /dev/null and b/src/wasm-lib/tests/executor/outputs/helix_defaults_negative_extrude.png differ diff --git a/src/wasm-lib/tests/executor/outputs/helix_with_length.png b/src/wasm-lib/tests/executor/outputs/helix_with_length.png new file mode 100644 index 000000000..b942584a6 Binary files /dev/null and b/src/wasm-lib/tests/executor/outputs/helix_with_length.png differ