///|
/// Proof of needle/travel geometry only; it does not simulate fabric or thread.
pub fn Plan::svg(self : Plan) -> String {
let palette = [
"#b91c1c", "#1d4ed8", "#15803d", "#a16207", "#7e22ce", "#0f766e", "#be185d",
"#111827",
]
let out : Array[String] = [
"")
out.join("")
}
///|
/// Stable machine-independent JSON command list; positions remain in 0.1 mm.
pub fn Plan::report(self : Plan) -> Json {
let commands = self.moves.map(fn(c) {
(
{
"x": Json(c.position.x),
"y": Json(c.position.y),
"kind": Json(kind_name(c.kind)),
"thread": Json(c.thread),
} : Json)
})
{
"unit": "0.1mm",
"hoop_width": Json(self.width),
"hoop_height": Json(self.height),
"max_step": Json(self.max_step),
"stitches": Json(self.moves.filter(fn(c) { c.kind == Stitch }).length()),
"jumps": Json(self.moves.filter(fn(c) { c.kind == Jump }).length()),
"color_changes": Json(self.moves.filter(fn(c) { c.kind == Color }).length()),
"commands": Json(commands),
}
}