601 lines
16 KiB
TypeScript
601 lines
16 KiB
TypeScript
import libfigure from "./libfigure/libfigure.js";
|
|
|
|
|
|
export interface LibFigureMove {
|
|
move: string,
|
|
parameter_values: any[],
|
|
progression?: 1,
|
|
note?: string,
|
|
}
|
|
export type LibFigureDance = LibFigureMove[];
|
|
|
|
type chooser_text = string;
|
|
type chooser_revolutions = number;
|
|
type chooser_places = number;
|
|
|
|
type chooser_boolean = true | false;
|
|
type chooser_spin = true | false;
|
|
type chooser_left_right_spin = true | false;
|
|
type chooser_right_left_hand = false | true;
|
|
type chooser_right_left_shoulder = false | true;
|
|
type chooser_slide = true | false;
|
|
type chooser_slice_increment = "couple" | "dancer";
|
|
type chooser_go_back = true | false;
|
|
type chooser_give = true | false;
|
|
type chooser_half_or_full = 0.5 | 1;
|
|
type chooser_star_grip = "" | "wrist grip" | "hands across";
|
|
type chooser_march_facing = "forward" | "backward" | "forward then backward";
|
|
type chooser_set_direction = "along" | "across" | "right diagonal" | "left diagonal";
|
|
type chooser_set_direction_acrossish = "across" | "right diagonal" | "left diagonal";
|
|
type chooser_set_direction_grid = "along" | "across";
|
|
type chooser_set_direction_figure_8 = "" | "above" | "below" | "across";
|
|
type chooser_gate_direction = "up" | "down" | "in" | "out";
|
|
type chooser_slice_return = "straight" | "diagonal" | "none";
|
|
type chooser_all_or_center_or_outsides = "all" | "center" | "outsides";
|
|
type chooser_down_the_hall_ender = "turn-alone" | "turn-couple" | "circle" | "cozy" | "cloverleaf" | "thread-needle" | "right-high" | "sliding-doors" | "";
|
|
type chooser_zig_zag_ender = "" | "ring" | "allemande";
|
|
type chooser_hey_length = "full" | "half" | "less than half" | "between half and full" | { dancer: chooser_pairz, time: 1 | 2};
|
|
type chooser_swing_prefix = "none" | "balance" | "meltdown";
|
|
type chooser_dancers = "everyone" | "gentlespoon" | "gentlespoons" | "ladle" | "ladles" | "partners" | "neighbors" | "ones" | "twos" | "same roles" | "first corners" | "second corners" | "first gentlespoon" | "first ladle" | "second gentlespoon" | "second ladle" | "shadows";
|
|
type chooser_pair = "gentlespoons" | "ladles" | "ones" | "twos" | "first corners" | "second corners";
|
|
type chooser_pair_or_everyone = "everyone" | "gentlespoons" | "ladles" | "ones" | "twos" | "first corners" | "second corners";
|
|
type chooser_pairc_or_everyone = "everyone" | "gentlespoons" | "ladles" | "centers" | "ones" | "twos";
|
|
export type chooser_pairz = "gentlespoons" | "ladles" | "partners" | "neighbors" | "next neighbors" | "3rd neighbors" | "ones" | "twos" | "same roles" | "first corners" | "second corners" | "shadows";
|
|
type chooser_pairz_or_unspecified = "" | "gentlespoons" | "ladles" | "partners" | "neighbors" | "ones" | "twos" | "same roles" | "first corners" | "second corners" | "shadows";
|
|
type chooser_pairs = "partners" | "neighbors" | "same roles" | "shadows";
|
|
type chooser_pairs_or_ones_or_twos = "partners" | "neighbors" | "same roles" | "ones" | "twos" | "shadows";
|
|
type chooser_pairs_or_everyone = "everyone" | "partners" | "neighbors" | "same roles" | "shadows";
|
|
type chooser_dancer = "first gentlespoon" | "first ladle" | "second gentlespoon" | "second ladle";
|
|
type chooser_role = "gentlespoons" | "ladles";
|
|
type chooser_hetero = "partners" | "neighbors" | "shadows";
|
|
|
|
|
|
export type Move = {
|
|
beats: number,
|
|
note?: string,
|
|
progression: boolean,
|
|
} & ({
|
|
move: "allemande",
|
|
parameters: {
|
|
who: chooser_pairz,
|
|
hand: chooser_right_left_hand,
|
|
circling: chooser_revolutions,
|
|
},
|
|
} | {
|
|
move: "allemande orbit",
|
|
parameters: {
|
|
who: chooser_pair,
|
|
hand: chooser_right_left_hand,
|
|
circling1: chooser_revolutions, // for allemande
|
|
circling2: chooser_revolutions, // for orbit
|
|
},
|
|
} | {
|
|
move: "arch & dive",
|
|
parameters: {
|
|
who: chooser_pair,
|
|
},
|
|
} | {
|
|
move: "balance",
|
|
parameters: {
|
|
who: chooser_pairs_or_everyone,
|
|
},
|
|
} | {
|
|
move: "balance the ring",
|
|
parameters: {
|
|
},
|
|
} | {
|
|
move: "box circulate",
|
|
parameters: {
|
|
who: chooser_pair,
|
|
bal: chooser_boolean,
|
|
hand: chooser_right_left_hand,
|
|
},
|
|
} | {
|
|
move: "box the gnat",
|
|
parameters: {
|
|
who: chooser_pairz,
|
|
bal: chooser_boolean,
|
|
hand: chooser_right_left_hand,
|
|
},
|
|
} | {
|
|
move: "swat the flea",
|
|
parameters: {
|
|
who: chooser_pairz,
|
|
bal: chooser_boolean,
|
|
hand: chooser_right_left_hand,
|
|
},
|
|
} | {
|
|
move: "butterfly whirl",
|
|
parameters: {
|
|
},
|
|
} | {
|
|
move: "California twirl",
|
|
parameters: {
|
|
who: chooser_pairz,
|
|
},
|
|
} | {
|
|
move: "chain",
|
|
parameters: {
|
|
who: chooser_role,
|
|
hand: chooser_right_left_hand,
|
|
dir: chooser_set_direction,
|
|
},
|
|
} | {
|
|
move: "circle",
|
|
parameters: {
|
|
turn: chooser_left_right_spin,
|
|
places: chooser_places,
|
|
},
|
|
} | {
|
|
move: "contra corners",
|
|
parameters: {
|
|
who: chooser_pair,
|
|
custom: chooser_text,
|
|
},
|
|
} | {
|
|
move: "cross trails",
|
|
parameters: {
|
|
who: chooser_pairs,
|
|
dir: chooser_set_direction_grid,
|
|
shoulder: chooser_right_left_shoulder,
|
|
who2: chooser_pairs,
|
|
},
|
|
} | {
|
|
move: "custom",
|
|
parameters: {
|
|
custom: chooser_text,
|
|
},
|
|
} | {
|
|
move: "do si do",
|
|
parameters: {
|
|
who: chooser_pairz,
|
|
shoulder: chooser_right_left_shoulder,
|
|
circling: chooser_revolutions,
|
|
},
|
|
} | {
|
|
move: "see saw",
|
|
parameters: {
|
|
who: chooser_pairz,
|
|
shoulder: chooser_right_left_shoulder,
|
|
circling: chooser_revolutions,
|
|
},
|
|
} | {
|
|
move: "dolphin hey",
|
|
parameters: {
|
|
who: chooser_pair,
|
|
whom: chooser_dancer,
|
|
shoulder: chooser_right_left_shoulder,
|
|
},
|
|
} | {
|
|
move: "down the hall",
|
|
parameters: {
|
|
who: chooser_pair_or_everyone,
|
|
moving: chooser_all_or_center_or_outsides,
|
|
facing: chooser_march_facing,
|
|
ender: chooser_down_the_hall_ender,
|
|
},
|
|
} | {
|
|
move: "up the hall",
|
|
parameters: {
|
|
who: chooser_pair_or_everyone,
|
|
moving: chooser_all_or_center_or_outsides,
|
|
facing: chooser_march_facing,
|
|
ender: chooser_down_the_hall_ender,
|
|
},
|
|
} | {
|
|
move: "figure 8",
|
|
parameters: {
|
|
who: chooser_pair,
|
|
dir: chooser_set_direction_figure_8,
|
|
lead: chooser_dancer,
|
|
half: chooser_half_or_full,
|
|
},
|
|
} | {
|
|
move: "form long waves",
|
|
parameters: {
|
|
who: chooser_pair,
|
|
},
|
|
} | {
|
|
move: "form a long wave",
|
|
parameters: {
|
|
who: chooser_pair,
|
|
in: chooser_boolean,
|
|
out: chooser_boolean,
|
|
bal: chooser_boolean,
|
|
},
|
|
} | {
|
|
move: "form an ocean wave",
|
|
parameters: {
|
|
"pass thru": chooser_boolean,
|
|
dir: chooser_set_direction_acrossish,
|
|
bal: chooser_boolean,
|
|
center: chooser_pair,
|
|
"c.hand": chooser_right_left_hand,
|
|
sides: chooser_pairs,
|
|
},
|
|
} | {
|
|
move: "gate",
|
|
parameters: {
|
|
who: chooser_pair,
|
|
whom: chooser_pairs_or_ones_or_twos,
|
|
face: chooser_gate_direction,
|
|
},
|
|
} | {
|
|
move: "give & take",
|
|
parameters: {
|
|
who: chooser_role,
|
|
whom: chooser_hetero,
|
|
give: chooser_give,
|
|
},
|
|
} | {
|
|
move: "facing star",
|
|
parameters: {
|
|
who: chooser_pair,
|
|
turn: chooser_spin,
|
|
places: chooser_places,
|
|
},
|
|
} | {
|
|
move: "gyre",
|
|
parameters: {
|
|
who: chooser_pairz,
|
|
shoulder: chooser_right_left_shoulder,
|
|
circling: chooser_revolutions,
|
|
},
|
|
} | {
|
|
move: "hey",
|
|
parameters: {
|
|
who: chooser_pairz,
|
|
who2: chooser_pairz_or_unspecified,
|
|
shoulder: chooser_right_left_shoulder,
|
|
until: chooser_hey_length,
|
|
dir: chooser_set_direction,
|
|
rico1: chooser_boolean,
|
|
rico2: chooser_boolean,
|
|
rico3: chooser_boolean,
|
|
rico4: chooser_boolean,
|
|
},
|
|
} | {
|
|
move: "long lines",
|
|
parameters: {
|
|
go: chooser_go_back,
|
|
},
|
|
} | {
|
|
move: "mad robin",
|
|
parameters: {
|
|
who: chooser_pair,
|
|
circling: chooser_revolutions,
|
|
},
|
|
} | {
|
|
move: "pass by",
|
|
parameters: {
|
|
who: chooser_pairz,
|
|
shoulder: chooser_right_left_shoulder,
|
|
},
|
|
} | {
|
|
move: "pass through",
|
|
parameters: {
|
|
dir: chooser_set_direction,
|
|
shoulder: chooser_right_left_shoulder,
|
|
},
|
|
} | {
|
|
move: "petronella",
|
|
parameters: {
|
|
bal: chooser_boolean,
|
|
},
|
|
} | {
|
|
move: "poussette",
|
|
parameters: {
|
|
half: chooser_half_or_full,
|
|
who: chooser_pair,
|
|
whom: chooser_pairs_or_ones_or_twos,
|
|
turn: chooser_spin,
|
|
},
|
|
} | {
|
|
move: "promenade",
|
|
parameters: {
|
|
who: chooser_pairs,
|
|
dir: chooser_set_direction,
|
|
turn: chooser_left_right_spin,
|
|
},
|
|
} | {
|
|
move: "pull by dancers",
|
|
parameters: {
|
|
who: chooser_pairz,
|
|
bal: chooser_boolean,
|
|
hand: chooser_right_left_hand,
|
|
},
|
|
} | {
|
|
move: "pull by direction",
|
|
parameters: {
|
|
bal: chooser_boolean,
|
|
dir: chooser_set_direction,
|
|
hand: chooser_right_left_hand,
|
|
},
|
|
} | {
|
|
move: "revolving door",
|
|
parameters: {
|
|
who: chooser_pair,
|
|
hand: chooser_right_left_hand,
|
|
whom: chooser_pairs,
|
|
},
|
|
} | {
|
|
move: "right left through",
|
|
parameters: {
|
|
dir: chooser_set_direction,
|
|
},
|
|
} | {
|
|
move: "roll away",
|
|
parameters: {
|
|
who: chooser_pair,
|
|
whom: chooser_pairs_or_ones_or_twos,
|
|
"½sash": chooser_boolean,
|
|
},
|
|
} | {
|
|
move: "Rory O'More",
|
|
parameters: {
|
|
who: chooser_pairc_or_everyone,
|
|
bal: chooser_boolean,
|
|
slide: chooser_slide,
|
|
},
|
|
} | {
|
|
move: "slice",
|
|
parameters: {
|
|
slide: chooser_slide,
|
|
"slice increment": chooser_slice_increment,
|
|
"slice return": chooser_slice_return,
|
|
},
|
|
} | {
|
|
move: "slide along set",
|
|
parameters: {
|
|
slide: chooser_slide,
|
|
},
|
|
} | {
|
|
move: "square through",
|
|
parameters: {
|
|
who: chooser_pairs,
|
|
who2: chooser_pairs,
|
|
bal: chooser_boolean,
|
|
hand: chooser_right_left_hand,
|
|
places: chooser_places,
|
|
},
|
|
} | {
|
|
move: "stand still",
|
|
parameters: {
|
|
},
|
|
} | {
|
|
move: "star",
|
|
parameters: {
|
|
hand: chooser_right_left_hand,
|
|
places: chooser_places,
|
|
grip: chooser_star_grip,
|
|
},
|
|
} | {
|
|
move: "star promenade",
|
|
parameters: {
|
|
who: chooser_pair,
|
|
hand: chooser_right_left_hand,
|
|
circling: chooser_revolutions,
|
|
},
|
|
} | {
|
|
move: "swing",
|
|
parameters: {
|
|
who: chooser_pairz,
|
|
prefix: chooser_swing_prefix,
|
|
},
|
|
} | {
|
|
move: "meltdown swing",
|
|
parameters: {
|
|
who: chooser_pairz,
|
|
prefix: chooser_swing_prefix,
|
|
},
|
|
} | {
|
|
move: "turn alone",
|
|
parameters: {
|
|
who: chooser_pair_or_everyone,
|
|
custom: chooser_text,
|
|
},
|
|
} | {
|
|
move: "zig zag",
|
|
parameters: {
|
|
who: chooser_pairs,
|
|
turn: chooser_left_right_spin,
|
|
ender: chooser_zig_zag_ender,
|
|
},
|
|
});
|
|
|
|
export function nameLibFigureParameters(move: LibFigureMove): Move {
|
|
const libfigureParameters: { name: string }[] = libfigure.formalParameters(move.move);
|
|
const parameterNames: string[] = libfigureParameters.map(p => p.name)
|
|
// Some moves have repeat parameter names, rename them to name1, name2, etc.
|
|
.map((v, i, a) => a.indexOf(v) === i && a.lastIndexOf(v) === i ? v : v + (a.slice(0, i).filter(el => el === v).length + 1));
|
|
const parameters = {};
|
|
for (let i = 0; i < parameterNames.length; i++) {
|
|
if (parameterNames[i] === "until") {
|
|
// parse chooser_hey_length
|
|
const hey_length: string = move.parameter_values[i];
|
|
if (hey_length.includes('%%')) {
|
|
parameters[parameterNames[i]] = {
|
|
dancer: hey_length.slice(0, -3),
|
|
time: parseInt(hey_length.at(-1)!),
|
|
};
|
|
} else {
|
|
parameters[parameterNames[i]] = hey_length;
|
|
}
|
|
} else {
|
|
parameters[parameterNames[i]] = move.parameter_values[i];
|
|
}
|
|
}
|
|
const beats: number = parameters["beats"];
|
|
parameters["beats"] = undefined;
|
|
return {
|
|
move: move.move,
|
|
beats,
|
|
progression: move.progression === 1,
|
|
note: move.note,
|
|
parameters,
|
|
} as Move;
|
|
}
|
|
|
|
// Helper for building the types above.
|
|
export function asTypeDefinitions(): string {
|
|
type Dialect = any;
|
|
const choosers: { [key: string]: (string | [any, string])[] } = {
|
|
chooser_boolean: [["*", "*"], [true, "yes"], [false, "no"]],
|
|
chooser_spin: [["*", "*"], [true, "clockwise"], [false, "ccw"]],
|
|
chooser_left_right_spin: [["*", "*"], [true, "left"], [false, "right"]],
|
|
chooser_right_left_hand: [["*", "*"], [false, "left"], [true, "right"]],
|
|
chooser_right_left_shoulder: [["*", "*"], [false, "left"], [true, "right"]],
|
|
chooser_slide: [["*", "*"], [true, "left"], [false, "right"]],
|
|
chooser_slice_increment: [
|
|
["*", "*"],
|
|
["couple", "couple"],
|
|
["dancer", "dancer"],
|
|
],
|
|
chooser_go_back: [["*", "*"], [true, "forward & back"], [false, "forward"]],
|
|
chooser_give: [["*", "*"], [true, "give & take"], [false, "take"]],
|
|
chooser_half_or_full: [["*", "*"], [0.5, "half"], [1.0, "full"]],
|
|
chooser_beats: [
|
|
"*",
|
|
8,
|
|
16,
|
|
0,
|
|
1,
|
|
2,
|
|
3,
|
|
4,
|
|
6,
|
|
8,
|
|
10,
|
|
12,
|
|
14,
|
|
16,
|
|
20,
|
|
24,
|
|
32,
|
|
48,
|
|
64,
|
|
],
|
|
chooser_star_grip:
|
|
["*"].concat(
|
|
libfigure.wristGrips.map(function (grip: any) {
|
|
return grip === "" ? ["", "unspecified"] : grip
|
|
})
|
|
),
|
|
chooser_march_facing: [
|
|
"*",
|
|
"forward",
|
|
"backward",
|
|
"forward then backward",
|
|
],
|
|
chooser_set_direction: [
|
|
"*",
|
|
["along", "along the set"],
|
|
["across", "across the set"],
|
|
"right diagonal",
|
|
"left diagonal",
|
|
],
|
|
chooser_set_direction_acrossish: [
|
|
"*",
|
|
["across", "across the set"],
|
|
"right diagonal",
|
|
"left diagonal",
|
|
],
|
|
chooser_set_direction_grid: [
|
|
"*",
|
|
["along", "along the set"],
|
|
["across", "across the set"],
|
|
],
|
|
chooser_set_direction_figure_8: [
|
|
"*",
|
|
"",
|
|
"above",
|
|
"below",
|
|
"across",
|
|
],
|
|
chooser_gate_direction: [
|
|
"*",
|
|
["up", "up the set"],
|
|
["down", "down the set"],
|
|
["in", "into the set"],
|
|
["out", "out of the set"],
|
|
],
|
|
chooser_slice_return: [
|
|
"*",
|
|
["straight", "straight back"],
|
|
["diagonal", "diagonal back"],
|
|
"none",
|
|
],
|
|
chooser_all_or_center_or_outsides: [
|
|
"*",
|
|
"all",
|
|
"center",
|
|
"outsides",
|
|
],
|
|
chooser_down_the_hall_ender: [
|
|
"*",
|
|
["turn-alone", "turn alone"],
|
|
["turn-couple", "turn as a couple"],
|
|
["circle", "bend into a ring"],
|
|
["cozy", "form a cozy line"],
|
|
["cloverleaf", "bend into a cloverleaf"],
|
|
["thread-needle", "thread the needle"],
|
|
["right-high", "right hand high, left hand low"],
|
|
["sliding-doors", "sliding doors"],
|
|
["", "unspecified"],
|
|
],
|
|
chooser_zig_zag_ender: [
|
|
"*",
|
|
["", "none"],
|
|
["ring", "into a ring"],
|
|
["allemande", "training two catch hands"],
|
|
],
|
|
chooser_hey_length: [
|
|
"*",
|
|
"full",
|
|
"half",
|
|
"less than half",
|
|
"between half and full",
|
|
],
|
|
chooser_swing_prefix: [
|
|
"*",
|
|
"none",
|
|
"balance",
|
|
"meltdown",
|
|
],
|
|
...libfigure.dancerChooserNames().reduce(
|
|
(acc: any, chooserName: string) => {
|
|
acc[chooserName] =
|
|
["*"].concat(
|
|
libfigure.dancerCategoryMenuForChooser(
|
|
libfigure.chooser(chooserName)
|
|
).map((dancers: string) => [
|
|
dancers,
|
|
libfigure.dancerMenuLabel(dancers, libfigure.defaultDialect),
|
|
])
|
|
)
|
|
return acc
|
|
},
|
|
{}
|
|
),
|
|
}
|
|
|
|
const chooserDefs = Object.keys(choosers).map(name => {
|
|
let c = choosers[name];
|
|
if (c instanceof Function) c = c(name);
|
|
function onlyUnique(value, index, array) {
|
|
return array.indexOf(value) === index;
|
|
}
|
|
c = c.map(el => (el instanceof String || typeof el === 'string') ? el : el[0]).filter(el => el != "*").filter(onlyUnique);
|
|
return "type " + name + " = " + c.map(el => JSON.stringify(el)).join(" | ") + ";"
|
|
}).join("\n");
|
|
|
|
const moveDefs = libfigure.moves().map(m => {
|
|
const params = libfigure.formalParameters(m);
|
|
return "{\n move: " + JSON.stringify(m)
|
|
+ ",\n parameters: {\n"
|
|
+ params.map(p => " " + p.name + ": " + p.ui.name + ",").join("\n")
|
|
+ "\n },\n }";
|
|
}).join(" | ");
|
|
|
|
return chooserDefs + "\n\n" + moveDefs;
|
|
} |