Intermediate Representation (IR)

The Pattern is the neutral type every reader produces and every writer consumes. Absolute coordinates in 0.1 mm units, standard orientation (y grows upward; VIP stores y negated, readers normalize it). Every quirk of the source format is boiled away.

Type (TS)

type Command =
  | 'STITCH' | 'JUMP' | 'TRIM'
  | 'COLOR_CHANGE' | 'STOP' | 'END';

interface Stitch {
  x: number;        // absolute, 0.1 mm
  y: number;        // absolute, 0.1 mm
  command: Command;
}

interface Thread {
  rgb: number;             // 24-bit 0xRRGGBB
  description?: string;
  catalog?: string;
  chart?: string;          // e.g. "Brother", "Janome"
}

interface Extents {
  minX: number; minY: number; maxX: number; maxY: number;
}

interface Hoop {
  width: number;            // 0.1 mm
  height: number;
  name?: string;            // e.g. "130x180" or a PES hoop-name
}

interface Pattern {
  stitches: Stitch[];
  threads: Thread[];
  extents: Extents;
  hoop?: Hoop;              // present only if the format carries it
}

Commands

CommandMachine meaning
STITCHThe needle goes down and sews a stitch.
JUMPMove without sewing (for jumps between areas).
TRIMCut the thread.
COLOR_CHANGEStop for a machine color change.
STOPStop for operator intervention.
ENDEnd of the design.

Every reader must emit an END as its last record; every writer must terminate the file with its own END and (for formats that require it) the final checksum.

Extents and Hoop

extents is computed by computeExtents(stitches), ignoring the ENDs. hoop is present only if the source format stores it (PES, JEF, PCS carry it; VIP/ZHS only extents). The writer decides what to do with the hoop when the destination format doesn't support it: usually warn.HOOP_UNSUPPORTED.

Structured warnings

The writer reports unavoidable deviations with a ConversionWarning:

interface ConversionWarning {
  code:
    | 'DELTA_63_SHIFTED' | 'METADATA_0X83_ZEROED'
    | 'FILLER_THREAD' | 'COLOR_QUANTIZED'
    | 'HOOP_FIT_EXCEEDED' | 'HOOP_UNSUPPORTED'
    | 'TRIM_DROPPED';
  message: string;          // human-readable, EN, from the engine
}

The web app maps each code to its i18n key (warn.DELTA_63_SHIFTED, etc.) and shows it in the results list. The IT/EN/FR/DE/ES/PT store lives in apps/web/src/i18n/strings.ts.

UnsupportedDesignError

If a design contains something the destination format simply cannot express (not even with a workaround), the writer throws UnsupportedDesignError with a reason: UnsupportedReason. The UI maps each reason to its i18n key (err.EMPTY, err.MULTI_COLOR, err.TRIM, err.JUMP, err.STOP, err.DELTA_RANGE, err.TOO_MANY_RECORDS, err.TOO_LARGE).

← EXP EmbCompress →