Ship the 47-exercise library in-app: export, fixtures, tests, docs
render.py --export bundles the 25 new motion rigs and info pages; figure-fixtures.json regenerated for all 47 (the Swift solver reproduces every new motion, including negative-y pins and the new prop uses). The fixture count assertion moves to 47, and the no-bundled-motion test now uses Treadmill - a permanent COVERAGE.md exclusion - since Bench Press exists. 48 tests green; watch target builds. Coverage handoff complete - TODO-coverage.md retired. Claude-Session: https://claude.ai/code/session_01HJDQQDA9QdP8zByg43H5v3
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
**July 2026**
|
||||
|
||||
The exercise library more than doubles — deadlifts, squats, lunges, bench presses, dumbbell work, pull-ups, and the cable stations — each with its own animated form guide.
|
||||
|
||||
Machine form guides now slowly circle around the figure too — seats, cables, and pads turn with the body, showing every exercise from all sides.
|
||||
|
||||
Form guides are now viewed from a slight elevation, with an exercise mat under the figure that turns with the camera.
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
# Handoff: right-size the exercise library by functional coverage
|
||||
|
||||
Repo: `~/Documents/indie/Workouts`. Read `Exercise Library/SYSTEM.md` first
|
||||
(motion format, props, visual language), then one machine motion
|
||||
(`Leg Press/motion.json`) and one bodyweight motion (`Bird Dog/motion.json`)
|
||||
as templates, one `info.md` (`Leg Press/info.md`) plus its parser
|
||||
(`Workouts/ExerciseFigure/ExerciseInfo.swift` — it parses a fixed shape, not
|
||||
general Markdown), and `render.py` (`--sheet`, `--strict`, `--orbit`,
|
||||
`--export`, `--fixtures`).
|
||||
|
||||
## The question this session answers
|
||||
|
||||
Not "how many exercises" but "which movement patterns can a user not log?"
|
||||
The picker (`ExercisePickerView`) lists exactly the bundled library names and
|
||||
there is no free-text fallback — the library is the app's **closed catalog**.
|
||||
A missing pattern is a hard wall, not a cosmetic gap. Build the coverage
|
||||
model, audit against it, then author the gap-fillers in priority order.
|
||||
|
||||
## The coverage model (starting point — refine it, don't rubber-stamp it)
|
||||
|
||||
Two axes, and the target list is their **union**:
|
||||
|
||||
1. **Function — a movement-pattern × modality matrix.** Patterns: squat,
|
||||
hinge, lunge, horizontal push, vertical push, horizontal pull, vertical
|
||||
pull, elbow flexion, elbow extension, shoulder raise (lateral/rear), hip
|
||||
ab/adduction, calf, core anti-extension, core rotation, core lateral,
|
||||
core flexion, mobility/warm-up. Modalities: machine, free weight
|
||||
(barbell/dumbbell), bodyweight/floor. A cell needs an exercise only if
|
||||
real programs train that pattern that way.
|
||||
2. **Equipment — a gym-floor census.** Walk a typical commercial gym
|
||||
(Planet Fitness / Golds tier): every common machine and free-weight
|
||||
station should have at least one library entry, because users log by
|
||||
station name, not by pattern — the matrix calls horizontal push "covered"
|
||||
by Chest Press, but Bench Press, Dumbbell Bench Press, and Pec Deck are
|
||||
distinct stations people expect to find in the picker. Inclusion test:
|
||||
"found in most gyms," not "exists somewhere."
|
||||
|
||||
The test for "done": a typical gym-goer — machine circuit, free-weight
|
||||
lifter, or home/bodyweight — can build their whole program from the picker
|
||||
without a missing pattern *or* a missing station. Write both filled tables
|
||||
into SYSTEM.md (or a COVERAGE.md beside it) so future additions are judged
|
||||
the same way.
|
||||
|
||||
## What a rough audit already shows (verify, then prioritize)
|
||||
|
||||
- **Hinge: zero coverage in any modality** — no Deadlift, Romanian Deadlift,
|
||||
Glute Bridge, or Hip Thrust. The single biggest hole; glutes are basically
|
||||
untrained by the current catalog.
|
||||
- **No lunge pattern** (Lunge / Split Squat).
|
||||
- **Bodyweight column missing its canon**: Squat, Push-Up, Pull-Up.
|
||||
- **Free-weight column completely empty** — zero barbell/dumbbell exercises.
|
||||
The `dumbbell` prop type exists in both renderers but has never been used
|
||||
by a motion; its first real use may shake out bugs.
|
||||
- **Shoulder raise**: no Lateral Raise (machine Shoulder Press only).
|
||||
- **Core flexion**: no plain Crunch (machine Abdominal only).
|
||||
- **Census gaps** — the current 14 machines are the standard selectorized
|
||||
circuit (good coverage there), but common stations are absent: bench
|
||||
press / incline bench (barbell + dumbbell), squat rack / Smith machine,
|
||||
pec deck (+ rear-delt fly), the cable station's staples (triceps
|
||||
pushdown, cable curl, cable crossover, face pull), assisted dip /
|
||||
pull-up, hack squat, back extension (roman chair), hip thrust, and the
|
||||
whole dumbbell rack (rows, shoulder press, flys, lateral raises, curls,
|
||||
RDLs, lunges, goblet squat).
|
||||
- Memory notes a desired "morning wake-up" mobility set (Cat-Cow exists;
|
||||
neck rolls, arm circles, etc.) — decide whether it's this session or the
|
||||
next phase.
|
||||
|
||||
The pattern matrix alone lands around 40–46 total (currently 22); the union
|
||||
with the gym-floor census pushes it to roughly 50–60. The tables decide
|
||||
which ones and in what order: hinge first, then the bench/rack/dumbbell
|
||||
free-weight canon and bodyweight staples, then the remaining stations
|
||||
(cables, pec deck, assisted machines), then isolation/mobility.
|
||||
|
||||
## Authoring workflow, per exercise
|
||||
|
||||
- New folder `<Name>/` with `motion.json` + `info.md`. The folder/`name`
|
||||
string is user-facing (picker + run screen) — match the existing naming
|
||||
register.
|
||||
- Pose keyframes in anatomical angles per SYSTEM.md; run
|
||||
`python3 render.py --strict "<Name>"` (ROM violations are data bugs; a few
|
||||
legacy warnings exist in old motions, add none), eyeball `preview.gif` AND
|
||||
`orbit.gif` — every exercise orbits in-app now, so check ±45°/90°/180°,
|
||||
not just the authored view.
|
||||
- Machines need props: scene slabs carry `z`/`depth` (see SYSTEM.md props
|
||||
section), `bar`/`pad`/`roller`/`cable` ride joints. Free weights are
|
||||
usually just a `bar` (with `plateR`) or `dumbbell` at the hands.
|
||||
- `info.md` must follow the parsed shape: `# Title`, summary paragraph,
|
||||
the `**Category:** / **Type:** / **Targets:** / **Prescription:**` bullets,
|
||||
then `## Setup / Execution / Cues / Common Mistakes / Progression`.
|
||||
**Machine exercises' `Type:` must start "Machine-based"** — that prefix is
|
||||
what shows the machine-settings UI (`ExerciseInfo.isMachineBased`).
|
||||
|
||||
## Invariants — do not break
|
||||
|
||||
- **Data-only expansion.** New exercises need zero Swift changes; if you find
|
||||
yourself touching the schema or solver, stop and re-read SYSTEM.md — and
|
||||
any schema change must land in `render.py`/`kinematics.py` and the Swift
|
||||
port in lockstep, fixtures regenerated.
|
||||
- `WorkoutsTests/ExerciseMotionTests.swift` asserts
|
||||
`fixtures.exercises.count == 22` — bump it to the new count and regenerate
|
||||
with `python3 render.py --fixtures`. `allBundledMotionsBuildTimelines`
|
||||
covers new motions automatically.
|
||||
- Starter splits and their fixed-ULID seeds are frozen — adding library
|
||||
exercises must not touch `StarterSplits/` or `Workouts/Seed/`.
|
||||
- Every exercise ships both files: a motion with no `info.md` renders a blank
|
||||
reference page in Settings → Library.
|
||||
|
||||
## Verification workflow
|
||||
|
||||
`python3 render.py --strict` (whole library) + `--sheet` and eyeball;
|
||||
`--orbit` for each new machine; `python3 render.py --export` then
|
||||
`python3 render.py --fixtures`; `xcodebuild test -scheme Workouts
|
||||
-destination 'platform=iOS Simulator,name=iPhone 17 Pro'
|
||||
-only-testing:WorkoutsTests` (48 green today; count assertion updated);
|
||||
`xcodebuild build -scheme "Workouts Watch App" -destination
|
||||
'generic/platform=watchOS Simulator'`. If test results ever contradict the
|
||||
source, suspect a stale incremental build — nuke DerivedData and rerun.
|
||||
One end-user CHANGELOG.md sentence per the app-changelog skill (e.g. the
|
||||
library doubles with deadlifts, lunges, push-ups, dumbbells…), README
|
||||
key-features line if it names library scope. Commit in reviewable batches
|
||||
(the coverage model + audit first, then exercises by pattern group), push,
|
||||
delete this file in the final commit.
|
||||
|
||||
## Judgment calls you're empowered to make
|
||||
|
||||
The final matrix rows and which cells count as "required"; where the census
|
||||
draws its "most gyms" line (kettlebells, T-bar row, pullover machine, and
|
||||
cardio equipment are likely out; Smith machine is borderline); whether the
|
||||
cable station gets one entry per exercise or per pattern; the exact
|
||||
exercise picks and their names; whether the mobility/"morning wake-up" set
|
||||
is in scope or explicitly deferred to the next phase; per-exercise camera
|
||||
yaw and prop minimalism (schematic silhouettes, never scale models).
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 303 KiB After Width: | Height: | Size: 622 KiB |
@@ -12,11 +12,14 @@ your own iCloud Drive.
|
||||
machine routines, plus an equipment-free **Bodyweight Core** circuit with its
|
||||
own warm-up) appear automatically on first launch; editing one makes it your
|
||||
own copy, and deleted starters can be restored from Settings.
|
||||
- **Exercise library** — a bundled library of exercises to populate your splits,
|
||||
authored in `Exercise Library/` with per-exercise setup, cues, mistakes,
|
||||
progressions, and an anatomically-rigged 3D stick-figure visual system — covering the
|
||||
bodyweight core moves plus the full Planet Fitness–style machine circuit
|
||||
(presses, rows, pulldowns, curls, leg and hip machines).
|
||||
- **Exercise library** — a bundled library of 47 exercises to populate your
|
||||
splits, authored in `Exercise Library/` with per-exercise setup, cues,
|
||||
mistakes, progressions, and an anatomically-rigged 3D stick-figure visual
|
||||
system — covering every common movement pattern and gym station (see the
|
||||
library's `COVERAGE.md`): the full machine circuit, the barbell and dumbbell
|
||||
free-weight canon (deadlifts, squats, benches, rows, curls, raises), the
|
||||
cable staples, and the bodyweight staples (push-ups, pull-ups, dips,
|
||||
lunges, and the floor core set).
|
||||
- **Run a workout** — start a session from a split, then tap an exercise to run it
|
||||
as a paged flow: a **Ready?** lead-in, count-up work phases, count-down rests, and
|
||||
a **Finish** page — mirroring the Apple Watch. Swipe a row to mark it complete, or
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# Back Extension
|
||||
|
||||
The roman-chair hinge — hips anchored on the pad, fold forward, then raise
|
||||
the trunk back in line with the legs.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Machine-based back extension (hip hinge)
|
||||
- **Targets:** Spinal erectors, glutes, hamstrings
|
||||
- **Prescription:** 3 × 10–15
|
||||
|
||||
## Setup
|
||||
|
||||
Set the pad so its top edge sits at the crease of your hips — you must be
|
||||
able to fold freely over it. Hook your heels under the ankle rollers,
|
||||
cross your arms over your chest.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Fold forward over the pad with a controlled, mostly-flat back.
|
||||
2. Lower until the hamstrings stop you, without going slack.
|
||||
3. Squeeze glutes and back to raise the trunk until it lines up with the
|
||||
legs — no higher.
|
||||
|
||||
## Cues
|
||||
|
||||
- Movement comes from the hips with the back held long.
|
||||
- Rise to a straight body line, not into an arch.
|
||||
- Slow down; momentum does nothing here.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Pad set too high, blocking the hinge.
|
||||
- Hyperextending past the body line at the top.
|
||||
- Swinging up with momentum.
|
||||
|
||||
## Progression
|
||||
|
||||
Slow the lowering phase, add a pause at the top, then hold a plate to the
|
||||
chest for load.
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "Back Extension",
|
||||
"primary": 2,
|
||||
"working": ["spine"],
|
||||
"props": [
|
||||
{"type": "scene", "shapes": [
|
||||
{"kind": "line", "pts": [[102, 124], [154, 106]], "w": 9, "depth": 8},
|
||||
{"kind": "line", "pts": [[130, 122], [130, 150]], "w": 5},
|
||||
{"kind": "line", "pts": [[58, 142], [88, 142]], "w": 5, "depth": 6}
|
||||
]},
|
||||
{"type": "roller", "at": ["foot_r", "foot_l"], "r": 4.5, "side": 1, "back": 4}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 1.0,
|
||||
"root": {"pos": [150, 102], "pitch": 112},
|
||||
"spine": [0, 12],
|
||||
"neck": 10, "head": -30,
|
||||
"shoulder_r": 30, "elbow_r": 140,
|
||||
"shoulder_l": 30, "elbow_l": 140,
|
||||
"hip_r": 48, "knee_r": 12, "ankle_r": 12,
|
||||
"hip_l": 48, "knee_l": 12, "ankle_l": 12,
|
||||
"pins": {"foot_r": [72, 136], "foot_l": [76, 138]}
|
||||
},
|
||||
{
|
||||
"hold": 0.6, "tween": 1.1,
|
||||
"root": {"pos": [150, 102], "pitch": 65},
|
||||
"spine": [0, -6],
|
||||
"neck": 5, "head": -55,
|
||||
"shoulder_r": 30, "elbow_r": 140,
|
||||
"shoulder_l": 30, "elbow_l": 140,
|
||||
"hip_r": 2, "knee_r": 12, "ankle_r": 12,
|
||||
"hip_l": 2, "knee_l": 12, "ankle_l": 12,
|
||||
"pins": {"foot_r": [72, 136], "foot_l": [76, 138]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
# Barbell Squat
|
||||
|
||||
The barbell back squat — bar across the upper back, sit down between the
|
||||
heels, stand back up.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Free-weight compound squat
|
||||
- **Targets:** Quadriceps, glutes, adductors, trunk
|
||||
- **Prescription:** 4 × 6–8
|
||||
|
||||
## Setup
|
||||
|
||||
Set the bar on your upper traps (not the neck), hands just outside the
|
||||
shoulders, and step back from the rack. Feet shoulder-width, toes slightly
|
||||
out, brace before every rep.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Sit down and back — hips and knees bend together, chest stays up.
|
||||
2. Descend until the thighs reach at least parallel, knees tracking over
|
||||
the toes.
|
||||
3. Drive the floor apart and stand back up to full lockout.
|
||||
|
||||
## Cues
|
||||
|
||||
- Big breath and brace at the top; exhale at the finish.
|
||||
- The bar stays over mid-foot — watch the sideways bar path, not the mirror.
|
||||
- Elbows down under the bar, not flared behind it.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Knees caving inward out of the bottom.
|
||||
- Heels lifting — weight drifting onto the toes.
|
||||
- Chest collapsing forward into a good-morning.
|
||||
|
||||
## Progression
|
||||
|
||||
Master the Bodyweight Squat and Goblet Squat first; add weight in small
|
||||
jumps only while depth and knee tracking hold.
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "Barbell Squat",
|
||||
"primary": 2,
|
||||
"camera": {"zoom": 0.7},
|
||||
"working": ["leg_r", "leg_l"],
|
||||
"props": [
|
||||
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 14}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 1.1,
|
||||
"root": {"pos": [160, 64], "pitch": 6},
|
||||
"spine": [0, 0],
|
||||
"neck": 2, "head": -6,
|
||||
"shoulder_r": 28, "elbow_r": 140,
|
||||
"shoulder_l": 28, "elbow_l": 140,
|
||||
"hip_r": 5, "knee_r": 4, "ankle_r": 0,
|
||||
"hip_l": 5, "knee_l": 4, "ankle_l": 0,
|
||||
"pins": {"foot_r": [160, 148], "foot_l": [164, 150],
|
||||
"hand_r": [166, -16], "hand_l": [170, -14]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 1.1,
|
||||
"root": {"pos": [117, 108], "pitch": 35},
|
||||
"spine": [0, -4],
|
||||
"neck": 5, "head": -28,
|
||||
"shoulder_r": 55, "elbow_r": 140,
|
||||
"shoulder_l": 55, "elbow_l": 140,
|
||||
"hip_r": 100, "knee_r": 118, "ankle_r": 22,
|
||||
"hip_l": 100, "knee_l": 118, "ankle_l": 22,
|
||||
"pins": {"foot_r": [160, 148], "foot_l": [164, 150],
|
||||
"hand_r": [163, 30], "hand_l": [167, 32]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
# Bench Press
|
||||
|
||||
The barbell press — lying on the flat bench, lower the bar to the chest
|
||||
and press it back to straight arms.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Free-weight horizontal press
|
||||
- **Targets:** Chest, front delts, triceps
|
||||
- **Prescription:** 4 × 6–8
|
||||
|
||||
## Setup
|
||||
|
||||
Lie with eyes under the bar, feet flat on the floor, shoulder blades
|
||||
pinched back and down. Grip a little wider than shoulder-width and
|
||||
unrack to straight arms over the shoulders.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Lower the bar under control to the mid-chest, elbows about 45° from
|
||||
the body.
|
||||
2. Touch lightly — no bounce.
|
||||
3. Press back up and slightly toward the face to lockout over the
|
||||
shoulders.
|
||||
|
||||
## Cues
|
||||
|
||||
- Shoulder blades stay pinched against the bench the whole set.
|
||||
- Wrists stacked over elbows; bar sits low in the palm.
|
||||
- Feet drive quietly into the floor.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Bouncing the bar off the chest.
|
||||
- Elbows flared straight out at 90°.
|
||||
- Hips lifting off the bench.
|
||||
|
||||
## Progression
|
||||
|
||||
Add small plates while every rep touches and locks out; a spotter or
|
||||
safety pins once the loads get honest.
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "Bench Press",
|
||||
"primary": 1,
|
||||
"working": ["arm_r", "arm_l"],
|
||||
"props": [
|
||||
{"type": "scene", "shapes": [
|
||||
{"kind": "line", "pts": [[58, 124], [162, 124]], "w": 9, "depth": 8},
|
||||
{"kind": "line", "pts": [[78, 129], [78, 150]], "w": 4},
|
||||
{"kind": "line", "pts": [[144, 129], [144, 150]], "w": 4}
|
||||
]},
|
||||
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 12}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 0.9,
|
||||
"root": {"pos": [150, 116], "pitch": -90},
|
||||
"spine": [0, 0],
|
||||
"neck": 8, "head": 0,
|
||||
"shoulder_r": 15, "elbow_r": 100,
|
||||
"shoulder_l": 15, "elbow_l": 100,
|
||||
"hip_r": 78, "knee_r": 82, "ankle_r": 5,
|
||||
"hip_l": 78, "knee_l": 82, "ankle_l": 5,
|
||||
"pins": {"foot_r": [196, 148], "foot_l": [200, 150],
|
||||
"hand_r": [93, 100], "hand_l": [97, 102]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 1.2,
|
||||
"root": {"pos": [150, 116], "pitch": -90},
|
||||
"spine": [0, 0],
|
||||
"neck": 8, "head": 0,
|
||||
"shoulder_r": 90, "elbow_r": 5,
|
||||
"shoulder_l": 90, "elbow_l": 5,
|
||||
"hip_r": 78, "knee_r": 82, "ankle_r": 5,
|
||||
"hip_l": 78, "knee_l": 82, "ankle_l": 5,
|
||||
"pins": {"foot_r": [196, 148], "foot_l": [200, 150],
|
||||
"hand_r": [67, 57], "hand_l": [71, 59]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# Bodyweight Squat
|
||||
|
||||
The unloaded squat — arms reach forward as a counterbalance while the hips
|
||||
sit down between the heels. The pattern every loaded squat is built on.
|
||||
|
||||
- **Category:** Warm-up and main circuit
|
||||
- **Type:** Bodyweight squat
|
||||
- **Targets:** Quadriceps, glutes, mobility
|
||||
- **Prescription:** 3 × 15–20, or 10 slow reps as a warm-up
|
||||
|
||||
## Setup
|
||||
|
||||
Stand with feet shoulder-width, toes slightly turned out, arms relaxed at
|
||||
your sides.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Reach the arms forward as the hips sit down and back.
|
||||
2. Descend as deep as comfortable — thighs at least parallel — heels flat.
|
||||
3. Stand back up tall and let the arms drop.
|
||||
|
||||
## Cues
|
||||
|
||||
- Knees track over the toes the whole way down and up.
|
||||
- Chest up; the arms reaching forward keep you from tipping.
|
||||
- Slow down — a three-second descent teaches control.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Heels lifting at the bottom.
|
||||
- Knees diving inward.
|
||||
- Shallow, quick bouncing instead of full, controlled reps.
|
||||
|
||||
## Progression
|
||||
|
||||
Slow the tempo, pause at the bottom, then load the pattern with the
|
||||
Goblet Squat.
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "Bodyweight Squat",
|
||||
"primary": 2,
|
||||
"camera": {"zoom": 0.7},
|
||||
"working": ["leg_r", "leg_l"],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 0.9,
|
||||
"root": {"pos": [160, 64], "pitch": 4},
|
||||
"spine": [0, 0],
|
||||
"neck": 2, "head": -6,
|
||||
"shoulder_r": 6, "elbow_r": 5,
|
||||
"shoulder_l": 6, "elbow_l": 5,
|
||||
"hip_r": 4, "knee_r": 3, "ankle_r": 0,
|
||||
"hip_l": 4, "knee_l": 3, "ankle_l": 0,
|
||||
"pins": {"foot_r": [160, 148], "foot_l": [164, 150]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 0.9,
|
||||
"root": {"pos": [146, 106], "pitch": 30},
|
||||
"spine": [0, -4],
|
||||
"neck": 5, "head": -24,
|
||||
"shoulder_r": 118, "elbow_r": 8,
|
||||
"shoulder_l": 118, "elbow_l": 8,
|
||||
"hip_r": 98, "knee_r": 118, "ankle_r": 22,
|
||||
"hip_l": 98, "knee_l": 118, "ankle_l": 22,
|
||||
"pins": {"foot_r": [160, 148], "foot_l": [164, 150]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
# Crunch
|
||||
|
||||
The floor ab curl — peel the shoulder blades off the mat, squeeze, and
|
||||
lower. Short range, all abs.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Spinal flexion (upper)
|
||||
- **Targets:** Rectus abdominis
|
||||
- **Prescription:** 3 × 15–20, slow
|
||||
|
||||
## Setup
|
||||
|
||||
Lie on your back, knees bent, feet flat. Fingertips lightly behind the
|
||||
ears, elbows wide.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Exhale and curl the ribs toward the pelvis until the shoulder blades
|
||||
leave the floor.
|
||||
2. Squeeze the abs hard at the top for a beat.
|
||||
3. Lower the shoulders back down without letting the head rest.
|
||||
|
||||
## Cues
|
||||
|
||||
- It's a curl, not a sit-up — the lower back stays on the mat.
|
||||
- Chin off the chest; the hands never pull the head.
|
||||
- Exhale on the way up to deepen the contraction.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Yanking the neck with the hands.
|
||||
- Sitting all the way up with the hip flexors.
|
||||
- Racing through reps with momentum.
|
||||
|
||||
## Progression
|
||||
|
||||
Slow the tempo and add a pause at the top; hold a small plate on the
|
||||
chest, or move to the Abdominal machine for stack-loaded flexion.
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "Crunch",
|
||||
"primary": 2,
|
||||
"working": ["spine"],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 0.8,
|
||||
"root": {"pos": [166, 146], "pitch": -90},
|
||||
"spine": [0, 0],
|
||||
"neck": 12, "head": 0,
|
||||
"shoulder_r": 155, "elbow_r": 140,
|
||||
"shoulder_l": 155, "elbow_l": 140,
|
||||
"hip_r": 75, "knee_r": 85, "ankle_r": 5,
|
||||
"hip_l": 75, "knee_l": 85, "ankle_l": 5,
|
||||
"pins": {"foot_r": [205, 148], "foot_l": [209, 150]}
|
||||
},
|
||||
{
|
||||
"hold": 0.6, "tween": 1.0,
|
||||
"root": {"pos": [166, 144], "pitch": -90},
|
||||
"spine": [14, 34],
|
||||
"neck": 30, "head": 0,
|
||||
"shoulder_r": 150, "elbow_r": 140,
|
||||
"shoulder_l": 150, "elbow_l": 140,
|
||||
"hip_r": 75, "knee_r": 85, "ankle_r": 5,
|
||||
"hip_l": 75, "knee_l": 85, "ankle_l": 5,
|
||||
"pins": {"foot_r": [205, 148], "foot_l": [209, 150]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
# Deadlift
|
||||
|
||||
The barbell hip hinge — brace hard, then stand up with the bar by driving
|
||||
the hips through.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Free-weight compound hinge
|
||||
- **Targets:** Glutes, hamstrings, spinal erectors, grip
|
||||
- **Prescription:** 4 × 6–8
|
||||
|
||||
## Setup
|
||||
|
||||
Stand with the bar over mid-foot, feet hip-width. Hinge down with a flat
|
||||
back and grip the bar just outside your legs. Shoulders slightly ahead of
|
||||
the bar, hips higher than knees, chest up.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Take the slack out of the bar, brace your trunk, then push the floor
|
||||
away — hips and shoulders rise together.
|
||||
2. Once the bar passes the knees, drive the hips forward to stand tall.
|
||||
3. Lower under control by hinging at the hips first, then bending the
|
||||
knees once the bar clears them.
|
||||
|
||||
## Cues
|
||||
|
||||
- Flat back from setup to lockout — the spine never rounds or overarches.
|
||||
- Keep the bar dragging close to the legs the whole way.
|
||||
- Finish with glutes, not by leaning back.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Squatting the weight up — hips too low, knees pushed forward.
|
||||
- Rounding the lower back off the floor.
|
||||
- Jerking the bar off the ground instead of pushing through the legs.
|
||||
|
||||
## Progression
|
||||
|
||||
Add weight in small jumps while all reps stay flat-backed; start from
|
||||
blocks or a rack if floor mobility isn't there yet.
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "Deadlift",
|
||||
"primary": 1,
|
||||
"camera": {"zoom": 0.7},
|
||||
"working": ["leg_r", "leg_l", "spine"],
|
||||
"props": [
|
||||
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 16}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 1.0,
|
||||
"root": {"pos": [92, 90], "pitch": 78},
|
||||
"spine": [0, -6],
|
||||
"neck": 5, "head": -70,
|
||||
"shoulder_r": 75, "elbow_r": 5,
|
||||
"shoulder_l": 75, "elbow_l": 5,
|
||||
"hip_r": 115, "knee_r": 30, "ankle_r": 15,
|
||||
"hip_l": 115, "knee_l": 30, "ankle_l": 15,
|
||||
"pins": {"foot_r": [150, 147], "foot_l": [154, 149],
|
||||
"hand_r": [156, 130], "hand_l": [160, 132]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 1.2,
|
||||
"root": {"pos": [150, 64], "pitch": 10},
|
||||
"spine": [0, 0],
|
||||
"neck": 2, "head": -8,
|
||||
"shoulder_r": 10, "elbow_r": 3,
|
||||
"shoulder_l": 10, "elbow_l": 3,
|
||||
"hip_r": 8, "knee_r": 5, "ankle_r": 0,
|
||||
"hip_l": 8, "knee_l": 5, "ankle_l": 0,
|
||||
"pins": {"foot_r": [150, 147], "foot_l": [154, 149],
|
||||
"hand_r": [161, 38], "hand_l": [165, 40]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# Dip
|
||||
|
||||
The bodyweight press on parallel bars — lower until the shoulders reach
|
||||
elbow depth, then press back to straight arms.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Bodyweight elbow extension (chest/triceps press)
|
||||
- **Targets:** Triceps, chest, front delts
|
||||
- **Prescription:** 3 × 6–12
|
||||
|
||||
## Setup
|
||||
|
||||
Support yourself on the parallel bars with straight arms, shoulders
|
||||
pressed down, slight forward lean, knees bent behind.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Bend the elbows and lower until the upper arms reach parallel.
|
||||
2. Keep the elbows tracking back, body leaning slightly forward.
|
||||
3. Press back up to full lockout without the shoulders shrugging.
|
||||
|
||||
## Cues
|
||||
|
||||
- Shoulders stay down away from the ears at every depth.
|
||||
- More forward lean hits chest; upright hits triceps.
|
||||
- Depth to parallel — a shaky bottom inch isn't worth the shoulder.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Sinking the shoulders into the ears at the bottom.
|
||||
- Flaring the elbows straight out.
|
||||
- Bouncing out of the deep position.
|
||||
|
||||
## Progression
|
||||
|
||||
Use the assisted dip machine or bands until full-range reps are smooth;
|
||||
then add reps, then hang weight from a belt.
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "Dip",
|
||||
"primary": 2,
|
||||
"camera": {"zoom": 0.78},
|
||||
"working": ["arm_r", "arm_l"],
|
||||
"props": [
|
||||
{"type": "scene", "shapes": [
|
||||
{"kind": "line", "pts": [[176, 66], [176, 150]], "w": 5},
|
||||
{"kind": "circle", "c": [176, 61], "r": 3.5, "fill": true, "color": "prop"}
|
||||
]}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 1.1,
|
||||
"root": {"pos": [160, 86], "pitch": 8},
|
||||
"spine": [0, 0],
|
||||
"neck": 5, "head": -10,
|
||||
"shoulder_r": 2, "elbow_r": 8,
|
||||
"shoulder_l": 2, "elbow_l": 8,
|
||||
"hip_r": 45, "knee_r": 130, "ankle_r": -20,
|
||||
"hip_l": 45, "knee_l": 130, "ankle_l": -20,
|
||||
"pins": {"hand_r": [174, 60], "hand_l": [178, 62]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 1.0,
|
||||
"root": {"pos": [160, 116], "pitch": 18},
|
||||
"spine": [0, 4],
|
||||
"neck": 8, "head": -15,
|
||||
"shoulder_r": -30, "elbow_r": 110,
|
||||
"shoulder_l": -30, "elbow_l": 110,
|
||||
"hip_r": 78, "knee_r": 148, "ankle_r": -20,
|
||||
"hip_l": 78, "knee_l": 148, "ankle_l": -20,
|
||||
"pins": {"hand_r": [174, 60], "hand_l": [178, 62]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
# Dumbbell Bench Press
|
||||
|
||||
The dumbbell press on the flat bench — a deeper, freer pressing arc than
|
||||
the bar, one weight in each hand.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Free-weight horizontal press (dumbbells)
|
||||
- **Targets:** Chest, front delts, triceps
|
||||
- **Prescription:** 3 × 8–12
|
||||
|
||||
## Setup
|
||||
|
||||
Sit with the dumbbells on your thighs, then lie back and kick them up to
|
||||
straight arms over the shoulders. Feet flat, shoulder blades pinched.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Lower both dumbbells to the outside of the chest, elbows about 45°
|
||||
from the body.
|
||||
2. Reach a comfortable stretch — deeper than a bar allows.
|
||||
3. Press back up and slightly together to lockout.
|
||||
|
||||
## Cues
|
||||
|
||||
- The dumbbells travel in a shallow A-shape, not straight lines.
|
||||
- Keep the wrists neutral and stacked over the elbows.
|
||||
- Lower slowly; the stretch is where dumbbells earn their keep.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Clanging the weights together at the top.
|
||||
- Uneven pressing — one side racing ahead.
|
||||
- Dropping the dumbbells from lockout instead of walking them down.
|
||||
|
||||
## Progression
|
||||
|
||||
Add weight while both sides press evenly; pause reps in the stretch
|
||||
position.
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "Dumbbell Bench Press",
|
||||
"primary": 1,
|
||||
"working": ["arm_r", "arm_l"],
|
||||
"props": [
|
||||
{"type": "scene", "shapes": [
|
||||
{"kind": "line", "pts": [[58, 124], [162, 124]], "w": 9, "depth": 8},
|
||||
{"kind": "line", "pts": [[78, 129], [78, 150]], "w": 4},
|
||||
{"kind": "line", "pts": [[144, 129], [144, 150]], "w": 4}
|
||||
]},
|
||||
{"type": "dumbbell", "at": "hand_r"},
|
||||
{"type": "dumbbell", "at": "hand_l"}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 0.9,
|
||||
"root": {"pos": [150, 116], "pitch": -90},
|
||||
"spine": [0, 0],
|
||||
"neck": 8, "head": 0,
|
||||
"shoulder_r": 12, "elbow_r": 105,
|
||||
"shoulder_l": 12, "elbow_l": 105,
|
||||
"hip_r": 78, "knee_r": 82, "ankle_r": 5,
|
||||
"hip_l": 78, "knee_l": 82, "ankle_l": 5,
|
||||
"pins": {"foot_r": [196, 148], "foot_l": [200, 150],
|
||||
"hand_r": [90, 104], "hand_l": [98, 106]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 1.2,
|
||||
"root": {"pos": [150, 116], "pitch": -90},
|
||||
"spine": [0, 0],
|
||||
"neck": 8, "head": 0,
|
||||
"shoulder_r": 90, "elbow_r": 5,
|
||||
"shoulder_l": 90, "elbow_l": 5,
|
||||
"hip_r": 78, "knee_r": 82, "ankle_r": 5,
|
||||
"hip_l": 78, "knee_l": 82, "ankle_l": 5,
|
||||
"pins": {"foot_r": [196, 148], "foot_l": [200, 150],
|
||||
"hand_r": [66, 57], "hand_l": [72, 59]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# Dumbbell Curl
|
||||
|
||||
The free-weight biceps curl — elbows pinned to the sides, curl both
|
||||
dumbbells from a full hang to the shoulders.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Free-weight elbow flexion (dumbbells)
|
||||
- **Targets:** Biceps, forearms
|
||||
- **Prescription:** 3 × 10–12
|
||||
|
||||
## Setup
|
||||
|
||||
Stand tall with a dumbbell in each hand at your sides, palms forward (or
|
||||
turning as you curl), elbows lightly touching the ribs.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Curl both weights up in an arc until the forearms reach the biceps.
|
||||
2. Keep the elbows fixed in place at your sides.
|
||||
3. Lower all the way to straight arms — the stretch counts.
|
||||
|
||||
## Cues
|
||||
|
||||
- Elbows are hinges, not swings — they never travel forward or back.
|
||||
- Wrists stay neutral; no flicking at the top.
|
||||
- Stand tall; the trunk does not rock.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Swinging the hips to start the rep.
|
||||
- Half reps that skip the bottom stretch.
|
||||
- Elbows drifting forward, turning it into a front raise.
|
||||
|
||||
## Progression
|
||||
|
||||
Add weight only while the torso stays statue-still; alternate arms or
|
||||
curl seated to remove all momentum.
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "Dumbbell Curl",
|
||||
"primary": 2,
|
||||
"camera": {"zoom": 0.7},
|
||||
"working": ["arm_r", "arm_l"],
|
||||
"props": [
|
||||
{"type": "dumbbell", "at": "hand_r"},
|
||||
{"type": "dumbbell", "at": "hand_l"}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 1.0,
|
||||
"root": {"pos": [160, 64], "pitch": 3},
|
||||
"spine": [0, 0],
|
||||
"neck": 2, "head": -4,
|
||||
"shoulder_r": 3, "elbow_r": 10,
|
||||
"shoulder_l": 3, "elbow_l": 10,
|
||||
"hip_r": 3, "knee_r": 2, "ankle_r": 0,
|
||||
"hip_l": 3, "knee_l": 2, "ankle_l": 0,
|
||||
"pins": {"foot_r": [158, 148], "foot_l": [162, 150]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 1.2,
|
||||
"root": {"pos": [160, 64], "pitch": 3},
|
||||
"spine": [0, 0],
|
||||
"neck": 2, "head": -4,
|
||||
"shoulder_r": 6, "elbow_r": 128,
|
||||
"shoulder_l": 6, "elbow_l": 128,
|
||||
"hip_r": 3, "knee_r": 2, "ankle_r": 0,
|
||||
"hip_l": 3, "knee_l": 2, "ankle_l": 0,
|
||||
"pins": {"foot_r": [158, 148], "foot_l": [162, 150]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
# Dumbbell Fly
|
||||
|
||||
The chest isolation — arms sweep from wide open to over the chest in a
|
||||
hugging arc, elbows softly fixed.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Free-weight chest fly (dumbbells)
|
||||
- **Targets:** Chest, front delts
|
||||
- **Prescription:** 3 × 10–15, light and controlled
|
||||
|
||||
## Setup
|
||||
|
||||
Lie on the flat bench with light dumbbells pressed over the chest, palms
|
||||
facing each other, a slight fixed bend in the elbows.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Open the arms in a wide arc until you feel a full chest stretch —
|
||||
hands about level with the chest, never below the shoulders' comfort.
|
||||
2. Keep the elbow angle unchanged the entire way.
|
||||
3. Sweep back up as if hugging a barrel, squeezing the chest together.
|
||||
|
||||
## Cues
|
||||
|
||||
- It's an arc, not a press — the elbows never bend and extend.
|
||||
- Go light; the stretch does the work, not the load.
|
||||
- Stop the descent the moment the chest stretch peaks.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Bending the elbows on the way down and pressing back up.
|
||||
- Dropping too deep and straining the shoulders.
|
||||
- Using bench-press weights.
|
||||
|
||||
## Progression
|
||||
|
||||
Slow the lowering phase and pause in the stretch; the Pec Deck offers
|
||||
the same motion with the path guided.
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "Dumbbell Fly",
|
||||
"primary": 2,
|
||||
"camera": {"yaw": 90},
|
||||
"working": ["arm_r", "arm_l"],
|
||||
"props": [
|
||||
{"type": "scene", "shapes": [
|
||||
{"kind": "line", "pts": [[148, 124], [172, 124]], "w": 8, "depth": 40},
|
||||
{"kind": "line", "pts": [[154, 129], [154, 150]], "w": 4},
|
||||
{"kind": "line", "pts": [[166, 129], [166, 150]], "w": 4}
|
||||
]},
|
||||
{"type": "dumbbell", "at": "hand_r"},
|
||||
{"type": "dumbbell", "at": "hand_l"}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.5, "tween": 1.0,
|
||||
"root": {"pos": [160, 116], "pitch": -90},
|
||||
"spine": [0, 0],
|
||||
"neck": 8, "head": 0,
|
||||
"shoulder_r": 88, "elbow_r": 12,
|
||||
"shoulder_l": 88, "elbow_l": 12,
|
||||
"hip_r": {"flexion": 78, "abduction": 10}, "knee_r": 82, "ankle_r": 5,
|
||||
"hip_l": {"flexion": 78, "abduction": 10}, "knee_l": 82, "ankle_l": 5,
|
||||
"pins": {"foot_r": [142, 148], "foot_l": [178, 150]}
|
||||
},
|
||||
{
|
||||
"hold": 0.5, "tween": 1.3,
|
||||
"root": {"pos": [160, 116], "pitch": -90},
|
||||
"spine": [0, 0],
|
||||
"neck": 8, "head": 0,
|
||||
"shoulder_r": {"flexion": 16, "abduction": 84}, "elbow_r": 22,
|
||||
"shoulder_l": {"flexion": 16, "abduction": 84}, "elbow_l": 22,
|
||||
"hip_r": {"flexion": 78, "abduction": 10}, "knee_r": 82, "ankle_r": 5,
|
||||
"hip_l": {"flexion": 78, "abduction": 10}, "knee_l": 82, "ankle_l": 5,
|
||||
"pins": {"foot_r": [142, 148], "foot_l": [178, 150]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
# Dumbbell Row
|
||||
|
||||
The one-arm row — knee and hand braced on the bench, pull the dumbbell
|
||||
from a dead hang to the ribs.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Free-weight horizontal pull (dumbbell)
|
||||
- **Targets:** Lats, mid-back, biceps
|
||||
- **Prescription:** 3 × 8–12 per side
|
||||
|
||||
## Setup
|
||||
|
||||
Put the same-side knee and hand on a bench, the other foot planted on
|
||||
the floor. Back flat and parallel to the ground, dumbbell hanging
|
||||
straight down from the shoulder.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Pull the dumbbell up and back toward the hip until the elbow passes
|
||||
the ribs.
|
||||
2. Squeeze the shoulder blade at the top.
|
||||
3. Lower to a full hang and stretch. Finish the set, then switch sides.
|
||||
|
||||
## Cues
|
||||
|
||||
- The elbow leads; the hand just holds on.
|
||||
- Shoulders stay square to the floor — no twisting to hoist the weight.
|
||||
- Long neck, eyes down; the back stays flat.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Rotating the torso open at the top of each rep.
|
||||
- Pulling with the biceps instead of driving the elbow back.
|
||||
- Cutting the stretch short at the bottom.
|
||||
|
||||
## Progression
|
||||
|
||||
Heavier dumbbells while the torso stays quiet; pause each rep at the top
|
||||
for a stricter mid-back stimulus.
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "Dumbbell Row",
|
||||
"primary": 2,
|
||||
"working": ["arm_r"],
|
||||
"props": [
|
||||
{"type": "scene", "shapes": [
|
||||
{"kind": "line", "pts": [[100, 124], [215, 124]], "w": 9, "depth": 8},
|
||||
{"kind": "line", "pts": [[118, 129], [118, 150]], "w": 4},
|
||||
{"kind": "line", "pts": [[196, 129], [196, 150]], "w": 4}
|
||||
]},
|
||||
{"type": "dumbbell", "at": "hand_r"}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 0.9,
|
||||
"root": {"pos": [168, 82], "yaw": 180, "pitch": 80},
|
||||
"spine": [0, 0],
|
||||
"neck": 10, "head": -50,
|
||||
"shoulder_r": 75, "elbow_r": 8,
|
||||
"shoulder_l": 72, "elbow_l": 5,
|
||||
"hip_r": 25, "knee_r": 25, "ankle_r": 10,
|
||||
"hip_l": 80, "knee_l": 95, "ankle_l": -50,
|
||||
"pins": {"foot_r": [196, 148], "foot_l": [202, 122],
|
||||
"hand_l": [66, 120], "hand_r": [92, 125]}
|
||||
},
|
||||
{
|
||||
"hold": 0.5, "tween": 1.1,
|
||||
"root": {"pos": [168, 82], "yaw": 180, "pitch": 80},
|
||||
"spine": [0, 0],
|
||||
"neck": 10, "head": -50,
|
||||
"shoulder_r": 40, "elbow_r": 115,
|
||||
"shoulder_l": 72, "elbow_l": 5,
|
||||
"hip_r": 25, "knee_r": 25, "ankle_r": 10,
|
||||
"hip_l": 80, "knee_l": 95, "ankle_l": -50,
|
||||
"pins": {"foot_r": [196, 148], "foot_l": [202, 122],
|
||||
"hand_l": [66, 120], "hand_r": [100, 86]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# Dumbbell Shoulder Press
|
||||
|
||||
The overhead press with dumbbells — seated against an upright bench,
|
||||
press from the shoulders to lockout overhead.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Free-weight vertical press (dumbbells)
|
||||
- **Targets:** Shoulders, triceps, upper chest
|
||||
- **Prescription:** 3 × 8–12
|
||||
|
||||
## Setup
|
||||
|
||||
Set the bench back upright. Sit with the dumbbells at shoulder height,
|
||||
palms forward, forearms vertical, feet planted.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Press both dumbbells straight up until the arms lock out overhead.
|
||||
2. Keep the weights over the shoulders — not drifting forward.
|
||||
3. Lower under control back to shoulder height.
|
||||
|
||||
## Cues
|
||||
|
||||
- Forearms vertical from every angle, wrists stacked over elbows.
|
||||
- Ribs down; the back stays on the pad, not arching off it.
|
||||
- The head moves slightly through at the top — bar path stays vertical.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Overarching the lower back to press bigger weights.
|
||||
- Stopping short of lockout.
|
||||
- Letting the dumbbells drift out sideways on the way up.
|
||||
|
||||
## Progression
|
||||
|
||||
Add weight while the back stays quiet on the pad; standing presses
|
||||
recruit more trunk once the seated pattern is strong.
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "Dumbbell Shoulder Press",
|
||||
"primary": 2,
|
||||
"camera": {"zoom": 0.82},
|
||||
"working": ["arm_r", "arm_l"],
|
||||
"props": [
|
||||
{"type": "scene", "shapes": [
|
||||
{"kind": "line", "pts": [[117, 128], [113, 58]], "w": 8, "depth": 8},
|
||||
{"kind": "line", "pts": [[114, 134], [150, 134]], "w": 8, "depth": 8},
|
||||
{"kind": "line", "pts": [[132, 136], [132, 150]], "w": 5}
|
||||
]},
|
||||
{"type": "dumbbell", "at": "hand_r"},
|
||||
{"type": "dumbbell", "at": "hand_l"}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 1.0,
|
||||
"root": {"pos": [130, 124], "pitch": 2},
|
||||
"spine": [0, 2],
|
||||
"neck": 4, "head": -6,
|
||||
"shoulder_r": 35, "elbow_r": 145,
|
||||
"shoulder_l": 35, "elbow_l": 145,
|
||||
"hip_r": 84, "knee_r": 64,
|
||||
"hip_l": 84, "knee_l": 64,
|
||||
"pins": {"foot_r": [176, 150], "foot_l": [180, 151],
|
||||
"hand_r": [146, 30], "hand_l": [150, 32]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 1.2,
|
||||
"root": {"pos": [130, 124], "pitch": 2},
|
||||
"spine": [0, 2],
|
||||
"neck": 4, "head": -6,
|
||||
"shoulder_r": 168, "elbow_r": 8,
|
||||
"shoulder_l": 168, "elbow_l": 8,
|
||||
"hip_r": 84, "knee_r": 64,
|
||||
"hip_l": 84, "knee_l": 64,
|
||||
"pins": {"foot_r": [176, 150], "foot_l": [180, 151],
|
||||
"hand_r": [138, -19], "hand_l": [142, -17]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
# Face Pull
|
||||
|
||||
The cable pull to the face — elbows high and wide, rope to the bridge of
|
||||
the nose. Small weight, big shoulders-health payoff.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Machine-based cable pull (rear delts)
|
||||
- **Targets:** Rear delts, mid-back, rotator cuff
|
||||
- **Prescription:** 3 × 12–15, light
|
||||
|
||||
## Setup
|
||||
|
||||
Set a rope attachment at face height (or slightly above). Grip with
|
||||
thumbs toward you, step back until the arms are straight, and stand
|
||||
tall with a slight stagger if needed.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Pull the rope straight toward the bridge of your nose.
|
||||
2. Elbows travel high and wide; at the end the knuckles point back
|
||||
beside the ears.
|
||||
3. Pause, then let the arms straighten slowly forward.
|
||||
|
||||
## Cues
|
||||
|
||||
- Elbows lead and stay at shoulder height the whole pull.
|
||||
- Pull the rope apart as it reaches the face.
|
||||
- Ribs down; the trunk doesn't lean back to finish the rep.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Turning it into a row with elbows dropping to the ribs.
|
||||
- Too much weight — the shoulders shrug and the trunk sways.
|
||||
- Anchor set too low, dragging the pull toward the chest.
|
||||
|
||||
## Progression
|
||||
|
||||
Add reps and pause length before weight; the Rear Delt Fly machine
|
||||
covers the same muscles with chest support.
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "Face Pull",
|
||||
"primary": 2,
|
||||
"camera": {"zoom": 0.7},
|
||||
"working": ["arm_r", "arm_l"],
|
||||
"props": [
|
||||
{"type": "scene", "shapes": [
|
||||
{"kind": "circle", "c": [242, -30], "r": 4, "fill": true, "color": "prop"}
|
||||
]},
|
||||
{"type": "cable", "from": [242, -30], "to": ["hand_r", "hand_l"], "w": 3}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 1.0,
|
||||
"root": {"pos": [150, 66], "pitch": 5},
|
||||
"spine": [0, 2],
|
||||
"neck": 4, "head": -6,
|
||||
"shoulder_r": 95, "elbow_r": 10,
|
||||
"shoulder_l": 95, "elbow_l": 10,
|
||||
"hip_r": 6, "knee_r": 8, "ankle_r": 0,
|
||||
"hip_l": 6, "knee_l": 8, "ankle_l": 0,
|
||||
"pins": {"foot_r": [146, 148], "foot_l": [150, 150],
|
||||
"hand_r": [214, -24], "hand_l": [218, -22]}
|
||||
},
|
||||
{
|
||||
"hold": 0.5, "tween": 1.1,
|
||||
"root": {"pos": [150, 66], "pitch": 5},
|
||||
"spine": [0, 2],
|
||||
"neck": 4, "head": -6,
|
||||
"shoulder_r": {"flexion": 95, "abduction": 15}, "elbow_r": 140,
|
||||
"shoulder_l": {"flexion": 95, "abduction": 15}, "elbow_l": 140,
|
||||
"hip_r": 6, "knee_r": 8, "ankle_r": 0,
|
||||
"hip_l": 6, "knee_l": 8, "ankle_l": 0,
|
||||
"pins": {"foot_r": [146, 148], "foot_l": [150, 150],
|
||||
"hand_r": [170, -26], "hand_l": [174, -24]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
# Glute Bridge
|
||||
|
||||
The floor hip hinge — drive through the heels and lift the hips until the
|
||||
body is a straight line from shoulders to knees.
|
||||
|
||||
- **Category:** Warm-up and main circuit
|
||||
- **Type:** Hip extension (floor)
|
||||
- **Targets:** Glutes, hamstrings
|
||||
- **Prescription:** 3 × 12–15, squeeze at the top
|
||||
|
||||
## Setup
|
||||
|
||||
Lie on your back, knees bent, feet flat on the floor about hip-width and
|
||||
close enough that your fingertips can graze your heels. Arms rest at your
|
||||
sides.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Press through the heels and squeeze the glutes to lift the hips.
|
||||
2. Stop when shoulders, hips and knees form a straight line — no arching
|
||||
past it.
|
||||
3. Hold the squeeze for a beat, then lower with control.
|
||||
|
||||
## Cues
|
||||
|
||||
- The glutes lift the hips; the lower back just comes along.
|
||||
- Ribs stay down — finish with the glutes, not by overarching.
|
||||
- Knees track over the feet, never falling inward or out.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Pushing through the toes instead of the heels.
|
||||
- Overarching the lower back at the top.
|
||||
- Bouncing reps off the floor.
|
||||
|
||||
## Progression
|
||||
|
||||
Pause holds at the top, then single-leg bridges; graduate to the barbell
|
||||
Hip Thrust for load.
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "Glute Bridge",
|
||||
"primary": 2,
|
||||
"working": ["leg_r", "leg_l"],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 0.8,
|
||||
"root": {"pos": [168, 144], "pitch": -90},
|
||||
"spine": [0, 0],
|
||||
"neck": 20, "head": -6,
|
||||
"shoulder_r": -4, "elbow_r": 0,
|
||||
"shoulder_l": -4, "elbow_l": 0,
|
||||
"hip_r": 72, "knee_r": 82, "ankle_r": 5,
|
||||
"hip_l": 72, "knee_l": 82, "ankle_l": 5,
|
||||
"pins": {"foot_r": [205, 148], "foot_l": [209, 150]}
|
||||
},
|
||||
{
|
||||
"hold": 0.9, "tween": 1.0,
|
||||
"root": {"pos": [172, 116], "pitch": -110},
|
||||
"spine": [0, -4],
|
||||
"neck": 48, "head": -6,
|
||||
"shoulder_r": -14, "elbow_r": 0,
|
||||
"shoulder_l": -14, "elbow_l": 0,
|
||||
"hip_r": 16, "knee_r": 92, "ankle_r": 5,
|
||||
"hip_l": 16, "knee_l": 92, "ankle_l": 5,
|
||||
"pins": {"foot_r": [205, 148], "foot_l": [209, 150]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# Goblet Squat
|
||||
|
||||
The dumbbell squat — hold one dumbbell vertically at the chest and squat
|
||||
between the heels. The friendliest way to load a squat.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Free-weight squat (dumbbell)
|
||||
- **Targets:** Quadriceps, glutes, trunk
|
||||
- **Prescription:** 3 × 10–12
|
||||
|
||||
## Setup
|
||||
|
||||
Hold a dumbbell vertically against your chest, both palms cupping the top
|
||||
end, elbows pointing down. Feet shoulder-width, toes slightly out.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Squat down between the heels, keeping the dumbbell glued to the chest.
|
||||
2. Reach full depth — elbows travel inside the knees.
|
||||
3. Stand back up tall without letting the weight tip you forward.
|
||||
|
||||
## Cues
|
||||
|
||||
- The counterweight in front lets the torso stay very upright — use it.
|
||||
- Elbows brush the inside of the knees at the bottom.
|
||||
- Whole foot planted; drive through the heels.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Letting the dumbbell drift away from the chest.
|
||||
- Cutting depth short.
|
||||
- Collapsing the upper back as the weight gets heavy.
|
||||
|
||||
## Progression
|
||||
|
||||
Heavier dumbbells until they're awkward to hold — then move to the
|
||||
Barbell Squat.
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "Goblet Squat",
|
||||
"primary": 2,
|
||||
"camera": {"zoom": 0.72},
|
||||
"working": ["leg_r", "leg_l"],
|
||||
"props": [
|
||||
{"type": "dumbbell", "at": ["hand_r", "hand_l"], "angle": 90, "halfLen": 8, "plateR": 5}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 1.0,
|
||||
"root": {"pos": [160, 66], "pitch": 5},
|
||||
"spine": [0, 0],
|
||||
"neck": 2, "head": -6,
|
||||
"shoulder_r": 38, "elbow_r": 125,
|
||||
"shoulder_l": 38, "elbow_l": 125,
|
||||
"hip_r": 5, "knee_r": 4, "ankle_r": 0,
|
||||
"hip_l": 5, "knee_l": 4, "ankle_l": 0,
|
||||
"pins": {"foot_r": [162, 148], "foot_l": [166, 150],
|
||||
"hand_r": [176, -2], "hand_l": [180, 0]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 1.0,
|
||||
"root": {"pos": [150, 104], "pitch": 22},
|
||||
"spine": [0, -4],
|
||||
"neck": 4, "head": -18,
|
||||
"shoulder_r": 46, "elbow_r": 120,
|
||||
"shoulder_l": 46, "elbow_l": 120,
|
||||
"hip_r": 96, "knee_r": 116, "ankle_r": 20,
|
||||
"hip_l": 96, "knee_l": 116, "ankle_l": 20,
|
||||
"pins": {"foot_r": [162, 148], "foot_l": [166, 150],
|
||||
"hand_r": [190, 40], "hand_l": [194, 42]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
# Hip Thrust
|
||||
|
||||
The loaded glute bridge — shoulders on a bench, barbell across the hips,
|
||||
drive the hips up to a straight line.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Free-weight hip extension
|
||||
- **Targets:** Glutes, hamstrings
|
||||
- **Prescription:** 4 × 8–10
|
||||
|
||||
## Setup
|
||||
|
||||
Sit on the floor with your upper back against a bench, the bar (padded)
|
||||
across your hips, hands steadying it. Feet flat, hip-width, heels under
|
||||
the knees.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Brace, tuck the chin, and drive through the heels to lift the hips.
|
||||
2. Stop when shoulders, hips and knees are level — a flat tabletop.
|
||||
3. Squeeze the glutes at the top, then lower the hips under control.
|
||||
|
||||
## Cues
|
||||
|
||||
- Chin tucked, ribs down — the body hinges around the bench edge.
|
||||
- Full lockout comes from the glutes, not from arching the back.
|
||||
- Shins vertical at the top; adjust foot distance until they are.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Overarching the lower back instead of finishing with the glutes.
|
||||
- Feet too far forward, turning it into a hamstring exercise.
|
||||
- Cutting the range short at the top.
|
||||
|
||||
## Progression
|
||||
|
||||
Start with the bar alone to groove the pattern, then add plates; pause
|
||||
reps at the top for extra glute work.
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "Hip Thrust",
|
||||
"primary": 2,
|
||||
"working": ["leg_r", "leg_l"],
|
||||
"props": [
|
||||
{"type": "scene", "shapes": [
|
||||
{"kind": "line", "pts": [[50, 122], [88, 122]], "w": 9, "depth": 8},
|
||||
{"kind": "line", "pts": [[68, 127], [68, 150]], "w": 5}
|
||||
]},
|
||||
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 13}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 0.8,
|
||||
"root": {"pos": [150, 136], "pitch": -75},
|
||||
"spine": [0, 6],
|
||||
"neck": 42, "head": -4,
|
||||
"shoulder_r": 4, "elbow_r": 8,
|
||||
"shoulder_l": 4, "elbow_l": 8,
|
||||
"hip_r": 78, "knee_r": 88, "ankle_r": 5,
|
||||
"hip_l": 78, "knee_l": 88, "ankle_l": 5,
|
||||
"pins": {"foot_r": [203, 147], "foot_l": [207, 149],
|
||||
"hand_r": [124, 127], "hand_l": [128, 129]}
|
||||
},
|
||||
{
|
||||
"hold": 0.9, "tween": 1.0,
|
||||
"root": {"pos": [152, 114], "pitch": -89},
|
||||
"spine": [0, 2],
|
||||
"neck": 48, "head": -4,
|
||||
"shoulder_r": 4, "elbow_r": 8,
|
||||
"shoulder_l": 4, "elbow_l": 8,
|
||||
"hip_r": 24, "knee_r": 92, "ankle_r": 5,
|
||||
"hip_l": 24, "knee_l": 92, "ankle_l": 5,
|
||||
"pins": {"foot_r": [203, 147], "foot_l": [207, 149],
|
||||
"hand_r": [126, 111], "hand_l": [130, 113]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# Incline Bench Press
|
||||
|
||||
The barbell press on the tilted bench — same press, aimed at the upper
|
||||
chest.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Free-weight incline press
|
||||
- **Targets:** Upper chest, front delts, triceps
|
||||
- **Prescription:** 3 × 8–10
|
||||
|
||||
## Setup
|
||||
|
||||
Set the bench to a moderate incline (around 30–45°). Lie back with the
|
||||
bar over the eyes, shoulder blades set, feet planted.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Lower the bar to the upper chest, just below the collarbones.
|
||||
2. Touch lightly, keeping the forearms vertical.
|
||||
3. Press straight up to lockout above the shoulders.
|
||||
|
||||
## Cues
|
||||
|
||||
- The steeper the bench, the more shoulder and less chest.
|
||||
- Ribcage up, but hips stay on the pad.
|
||||
- Bar path is a straight vertical line on the incline.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Sliding the bar path out over the belly.
|
||||
- Overarching to turn it back into a flat press.
|
||||
- Grip too wide for the shorter incline stroke.
|
||||
|
||||
## Progression
|
||||
|
||||
Work up in weight after the flat Bench Press, not before it; dumbbells
|
||||
on the same bench trade load for range.
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "Incline Bench Press",
|
||||
"primary": 1,
|
||||
"camera": {"zoom": 0.85},
|
||||
"working": ["arm_r", "arm_l"],
|
||||
"props": [
|
||||
{"type": "scene", "shapes": [
|
||||
{"kind": "line", "pts": [[142, 127], [86, 60]], "w": 9, "depth": 8},
|
||||
{"kind": "line", "pts": [[140, 130], [166, 127]], "w": 8, "depth": 8},
|
||||
{"kind": "line", "pts": [[152, 133], [152, 150]], "w": 5}
|
||||
]},
|
||||
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 12}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 0.9,
|
||||
"root": {"pos": [148, 122], "pitch": -38},
|
||||
"spine": [0, 0],
|
||||
"neck": 18, "head": -4,
|
||||
"shoulder_r": 30, "elbow_r": 115,
|
||||
"shoulder_l": 30, "elbow_l": 115,
|
||||
"hip_r": 85, "knee_r": 75, "ankle_r": 5,
|
||||
"hip_l": 85, "knee_l": 75, "ankle_l": 5,
|
||||
"pins": {"foot_r": [198, 148], "foot_l": [202, 150],
|
||||
"hand_r": [106, 38], "hand_l": [110, 40]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 1.2,
|
||||
"root": {"pos": [148, 122], "pitch": -38},
|
||||
"spine": [0, 0],
|
||||
"neck": 18, "head": -4,
|
||||
"shoulder_r": 118, "elbow_r": 5,
|
||||
"shoulder_l": 118, "elbow_l": 5,
|
||||
"hip_r": 85, "knee_r": 75, "ankle_r": 5,
|
||||
"hip_l": 85, "knee_l": 75, "ankle_l": 5,
|
||||
"pins": {"foot_r": [198, 148], "foot_l": [202, 150],
|
||||
"hand_r": [98, -3], "hand_l": [102, -1]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# Lateral Raise
|
||||
|
||||
The side-delt isolation — raise light dumbbells out to the sides until
|
||||
the arms are level with the shoulders.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Free-weight lateral raise (dumbbells)
|
||||
- **Targets:** Side delts
|
||||
- **Prescription:** 3 × 12–15, light
|
||||
|
||||
## Setup
|
||||
|
||||
Stand tall with light dumbbells at your sides, a slight fixed bend in
|
||||
the elbows, shoulders relaxed down.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Raise both arms out to the sides, leading with the elbows.
|
||||
2. Stop at shoulder height — arms level, pinkies no higher than thumbs.
|
||||
3. Lower slowly back to the sides.
|
||||
|
||||
## Cues
|
||||
|
||||
- Pour-the-jug: elbows stay just above the hands.
|
||||
- Shoulders stay down away from the ears — no shrugging.
|
||||
- The weights float up; the trunk never sways.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Going too heavy and swinging the weights up.
|
||||
- Shrugging the traps into the raise.
|
||||
- Raising past shoulder height.
|
||||
|
||||
## Progression
|
||||
|
||||
More reps before more weight; slow negatives and pauses at the top beat
|
||||
bigger dumbbells here.
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "Lateral Raise",
|
||||
"primary": 2,
|
||||
"camera": {"yaw": 90, "zoom": 0.7},
|
||||
"working": ["arm_r", "arm_l"],
|
||||
"props": [
|
||||
{"type": "dumbbell", "at": "hand_r"},
|
||||
{"type": "dumbbell", "at": "hand_l"}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 1.0,
|
||||
"root": {"pos": [160, 64]},
|
||||
"spine": [0, 0],
|
||||
"neck": 0, "head": 0,
|
||||
"shoulder_r": {"flexion": 4, "abduction": 8}, "elbow_r": 10,
|
||||
"shoulder_l": {"flexion": 4, "abduction": 8}, "elbow_l": 10,
|
||||
"hip_r": {"flexion": 0, "abduction": 6}, "knee_r": 0,
|
||||
"hip_l": {"flexion": 0, "abduction": 6}, "knee_l": 0
|
||||
},
|
||||
{
|
||||
"hold": 0.5, "tween": 1.3,
|
||||
"root": {"pos": [160, 64]},
|
||||
"spine": [0, 0],
|
||||
"neck": 0, "head": 0,
|
||||
"shoulder_r": {"flexion": 4, "abduction": 88}, "elbow_r": 12,
|
||||
"shoulder_l": {"flexion": 4, "abduction": 88}, "elbow_l": 12,
|
||||
"hip_r": {"flexion": 0, "abduction": 6}, "knee_r": 0,
|
||||
"hip_l": {"flexion": 0, "abduction": 6}, "knee_l": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
# Lunge
|
||||
|
||||
The split-stance squat — drop the back knee toward the floor, then drive
|
||||
back up through the front heel. Bodyweight first, dumbbells in hand later.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Split-stance squat (bodyweight or dumbbells)
|
||||
- **Targets:** Quadriceps, glutes, balance
|
||||
- **Prescription:** 3 × 8–10 per side
|
||||
|
||||
## Setup
|
||||
|
||||
Take a long step so both knees can bend to 90° — front shin vertical,
|
||||
back heel up. Hips square to the front, hands at your sides or on hips.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Lower straight down until the back knee hovers just above the floor.
|
||||
2. The front knee stays over the mid-foot, torso upright.
|
||||
3. Drive through the front heel to come back up. Finish the set, then
|
||||
switch sides.
|
||||
|
||||
## Cues
|
||||
|
||||
- Down like an elevator, not forward like a slide.
|
||||
- Front heel carries the work; the back leg balances.
|
||||
- Squeeze the front glute to stand up.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Stance too short — the front knee shoots past the toes.
|
||||
- Torso pitching forward on the way up.
|
||||
- Pushing off the back foot instead of the front heel.
|
||||
|
||||
## Progression
|
||||
|
||||
Hold a dumbbell in each hand; step backward into each rep (reverse lunge)
|
||||
or elevate the back foot for a split squat.
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "Lunge",
|
||||
"primary": 2,
|
||||
"camera": {"zoom": 0.7},
|
||||
"working": ["leg_r", "leg_l"],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 1.0,
|
||||
"root": {"pos": [160, 68], "pitch": 6},
|
||||
"spine": [0, 0],
|
||||
"neck": 2, "head": -6,
|
||||
"shoulder_r": 5, "elbow_r": 8,
|
||||
"shoulder_l": 5, "elbow_l": 8,
|
||||
"hip_r": 25, "knee_r": 10, "ankle_r": 5,
|
||||
"hip_l": -25, "knee_l": 10, "ankle_l": -12,
|
||||
"pins": {"foot_r": [196, 148], "foot_l": [124, 147]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 1.0,
|
||||
"root": {"pos": [160, 106], "pitch": 8},
|
||||
"spine": [0, 0],
|
||||
"neck": 2, "head": -6,
|
||||
"shoulder_r": 5, "elbow_r": 8,
|
||||
"shoulder_l": 5, "elbow_l": 8,
|
||||
"hip_r": 80, "knee_r": 95, "ankle_r": 15,
|
||||
"hip_l": -12, "knee_l": 100, "ankle_l": -42,
|
||||
"pins": {"foot_r": [196, 148], "foot_l": [124, 147]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
# Pec Deck
|
||||
|
||||
The machine chest fly — arms sweep together in front of the chest along
|
||||
the machine's fixed arc.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Machine-based chest fly
|
||||
- **Targets:** Chest, front delts
|
||||
- **Prescription:** 4 × 10
|
||||
|
||||
## Setup
|
||||
|
||||
Adjust the seat so the handles sit at chest height with your upper arms
|
||||
level. Back flat on the pad, feet planted, a soft bend fixed in the
|
||||
elbows.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Sweep both arms together in a wide arc until the handles meet in
|
||||
front of the chest.
|
||||
2. Squeeze the chest hard for a beat at the middle.
|
||||
3. Open back up with control until you feel a full chest stretch.
|
||||
|
||||
## Cues
|
||||
|
||||
- Elbow angle never changes — the chest swings the arms.
|
||||
- Shoulders stay back against the pad; they don't roll forward at the
|
||||
squeeze.
|
||||
- Slow the return; the stretch half of the rep counts.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Setting the seat so low the handles sit at the shoulders.
|
||||
- Shoulders rounding forward to chase extra range.
|
||||
- Letting the stack yank the arms open.
|
||||
|
||||
## Progression
|
||||
|
||||
Add a plate once every rep meets in the middle with a one-second
|
||||
squeeze; the Dumbbell Fly trades the guided path for free control.
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "Pec Deck",
|
||||
"primary": 2,
|
||||
"camera": {"yaw": 90},
|
||||
"working": ["arm_r", "arm_l"],
|
||||
"props": [
|
||||
{"type": "scene", "shapes": [
|
||||
{"kind": "line", "pts": [[160, 64], [160, 120]], "w": 16, "z": -14, "depth": 6},
|
||||
{"kind": "line", "pts": [[135, 131], [185, 131]], "w": 10, "depth": 12},
|
||||
{"kind": "line", "pts": [[160, 136], [160, 150]], "w": 6}
|
||||
]},
|
||||
{"type": "pad", "at": "hand_r", "angle": 90, "halfLen": 9, "w": 5},
|
||||
{"type": "pad", "at": "hand_l", "angle": 90, "halfLen": 9, "w": 5}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.5, "tween": 1.1,
|
||||
"root": {"pos": [160, 116]},
|
||||
"spine": [0, 0],
|
||||
"neck": 0,
|
||||
"shoulder_r": {"flexion": 18, "abduction": 82}, "elbow_r": 25,
|
||||
"shoulder_l": {"flexion": 18, "abduction": 82}, "elbow_l": 25,
|
||||
"hip_r": 78, "knee_r": 62,
|
||||
"hip_l": 78, "knee_l": 62
|
||||
},
|
||||
{
|
||||
"hold": 0.5, "tween": 1.2,
|
||||
"root": {"pos": [160, 116]},
|
||||
"spine": [0, 0],
|
||||
"neck": 0,
|
||||
"shoulder_r": {"flexion": 86, "abduction": 6}, "elbow_r": 25,
|
||||
"shoulder_l": {"flexion": 86, "abduction": 6}, "elbow_l": 25,
|
||||
"hip_r": 78, "knee_r": 62,
|
||||
"hip_l": 78, "knee_l": 62
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# Pull-Up
|
||||
|
||||
The vertical pull — from a dead hang, pull the chin over the bar and
|
||||
lower all the way back down.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Bodyweight vertical pull
|
||||
- **Targets:** Lats, biceps, mid-back, grip
|
||||
- **Prescription:** 3 × as many strict reps as possible
|
||||
|
||||
## Setup
|
||||
|
||||
Grip the bar just outside shoulder-width, palms away. Hang with straight
|
||||
arms, shoulders active (pulled slightly down), knees bent or legs long.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Drive the elbows down toward the ribs to pull the body up.
|
||||
2. Chin clears the bar — chest toward it, not chin poking over.
|
||||
3. Lower with control to a full dead hang every rep.
|
||||
|
||||
## Cues
|
||||
|
||||
- Start every rep from straight arms; half hangs don't count.
|
||||
- Think "elbows to pockets", not "chin to bar".
|
||||
- Quiet body — no swinging or kicking.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Kipping and swinging for extra reps.
|
||||
- Stopping the descent halfway.
|
||||
- Shrugging the shoulders to the ears at the top.
|
||||
|
||||
## Progression
|
||||
|
||||
Use the assisted pull-up machine or a band until 5 strict reps come
|
||||
easily; then add reps, then hang weight from a belt.
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "Pull-Up",
|
||||
"primary": 2,
|
||||
"camera": {"zoom": 0.7},
|
||||
"working": ["arm_r", "arm_l"],
|
||||
"props": [
|
||||
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 24}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.5, "tween": 1.0,
|
||||
"root": {"pos": [156, 99]},
|
||||
"spine": [0, 0],
|
||||
"neck": 2, "head": -6,
|
||||
"shoulder_r": 182, "elbow_r": 5,
|
||||
"shoulder_l": 182, "elbow_l": 5,
|
||||
"hip_r": 35, "knee_r": 120, "ankle_r": -30,
|
||||
"hip_l": 35, "knee_l": 120, "ankle_l": -30,
|
||||
"pins": {"hand_r": [154, -46], "hand_l": [158, -44]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 1.3,
|
||||
"root": {"pos": [156, 67]},
|
||||
"spine": [0, 0],
|
||||
"neck": 4, "head": -10,
|
||||
"shoulder_r": 150, "elbow_r": 125,
|
||||
"shoulder_l": 150, "elbow_l": 125,
|
||||
"hip_r": 35, "knee_r": 120, "ankle_r": -30,
|
||||
"hip_l": 35, "knee_l": 120, "ankle_l": -30,
|
||||
"pins": {"hand_r": [154, -46], "hand_l": [158, -44]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
# Push-Up
|
||||
|
||||
The bodyweight press — a moving plank: lower the chest to the floor and
|
||||
press back up without the hips sagging.
|
||||
|
||||
- **Category:** Warm-up and main circuit
|
||||
- **Type:** Bodyweight horizontal press
|
||||
- **Targets:** Chest, front delts, triceps, trunk
|
||||
- **Prescription:** 3 × 8–15
|
||||
|
||||
## Setup
|
||||
|
||||
Hands under the shoulders, legs long, toes tucked. Squeeze the glutes
|
||||
and brace so the body is one straight line from head to heels.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Bend the elbows about 45° from the body and lower the chest toward
|
||||
the floor.
|
||||
2. Stop a fist's height off the ground, body still one line.
|
||||
3. Press the floor away to straight arms.
|
||||
|
||||
## Cues
|
||||
|
||||
- The plank never breaks — hips neither sag nor pike.
|
||||
- Screw the hands into the floor to keep the elbows tracking.
|
||||
- Chest leads the descent, not the chin or the hips.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Hips sagging into a banana shape.
|
||||
- Flaring the elbows to 90°.
|
||||
- Craning the neck at the floor.
|
||||
|
||||
## Progression
|
||||
|
||||
Start from an incline (hands on a bench) if reps stall; graduate to feet
|
||||
elevated, then slow negatives.
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "Push-Up",
|
||||
"primary": 1,
|
||||
"working": ["arm_r", "arm_l"],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 0.9,
|
||||
"root": {"pos": [180, 115], "yaw": 180, "pitch": 73},
|
||||
"spine": [0, 0],
|
||||
"neck": 0, "head": -60,
|
||||
"shoulder_r": 90, "elbow_r": 8,
|
||||
"shoulder_l": 90, "elbow_l": 8,
|
||||
"hip_r": 5, "knee_r": 3, "ankle_r": 25,
|
||||
"hip_l": 5, "knee_l": 3, "ankle_l": 25,
|
||||
"pins": {"hand_r": [97, 148], "hand_l": [101, 150],
|
||||
"foot_r": [256, 143], "foot_l": [260, 145]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 0.9,
|
||||
"root": {"pos": [180, 132], "yaw": 180, "pitch": 85},
|
||||
"spine": [0, 0],
|
||||
"neck": 0, "head": -55,
|
||||
"shoulder_r": 60, "elbow_r": 110,
|
||||
"shoulder_l": 60, "elbow_l": 110,
|
||||
"hip_r": 5, "knee_r": 3, "ankle_r": 25,
|
||||
"hip_l": 5, "knee_l": 3, "ankle_l": 25,
|
||||
"pins": {"hand_r": [97, 148], "hand_l": [101, 150],
|
||||
"foot_r": [256, 143], "foot_l": [260, 145]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
# Rear Delt Fly
|
||||
|
||||
The reverse pec deck — facing the pad, arms sweep from the front out
|
||||
wide and back, hitting what pressing never touches.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Machine-based reverse fly
|
||||
- **Targets:** Rear delts, mid-back
|
||||
- **Prescription:** 3 × 12–15, light
|
||||
|
||||
## Setup
|
||||
|
||||
Set the handles to the rear-fly position and sit facing the pad, chest
|
||||
supported, handles together in front at shoulder height, arms long with
|
||||
soft elbows.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Sweep both arms out and back as far as the shoulder blades allow.
|
||||
2. Pause with the arms wide, squeezing between the shoulder blades.
|
||||
3. Return forward under control without the stack touching down.
|
||||
|
||||
## Cues
|
||||
|
||||
- Lead with the knuckles, arms long — it's a sweep, not a row.
|
||||
- Chest glued to the pad; no leaning back for leverage.
|
||||
- Light weight, full arc — momentum defeats the rear delts instantly.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Bending the elbows into a rowing motion.
|
||||
- Loading too heavy and shortening the arc.
|
||||
- Shrugging the traps into the sweep.
|
||||
|
||||
## Progression
|
||||
|
||||
More reps and a longer pause out wide before more weight; the Face Pull
|
||||
covers the same territory from the cable stack.
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "Rear Delt Fly",
|
||||
"primary": 2,
|
||||
"camera": {"yaw": 270},
|
||||
"working": ["arm_r", "arm_l"],
|
||||
"props": [
|
||||
{"type": "scene", "shapes": [
|
||||
{"kind": "line", "pts": [[160, 64], [160, 120]], "w": 16, "z": -14, "depth": 6},
|
||||
{"kind": "line", "pts": [[135, 131], [185, 131]], "w": 10, "depth": 12},
|
||||
{"kind": "line", "pts": [[160, 136], [160, 150]], "w": 6}
|
||||
]},
|
||||
{"type": "pad", "at": "hand_r", "angle": 90, "halfLen": 9, "w": 5},
|
||||
{"type": "pad", "at": "hand_l", "angle": 90, "halfLen": 9, "w": 5}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.5, "tween": 1.1,
|
||||
"root": {"pos": [160, 116]},
|
||||
"spine": [0, 0],
|
||||
"neck": 0,
|
||||
"shoulder_r": {"flexion": 85, "abduction": 6}, "elbow_r": 15,
|
||||
"shoulder_l": {"flexion": 85, "abduction": 6}, "elbow_l": 15,
|
||||
"hip_r": 78, "knee_r": 62,
|
||||
"hip_l": 78, "knee_l": 62
|
||||
},
|
||||
{
|
||||
"hold": 0.5, "tween": 1.2,
|
||||
"root": {"pos": [160, 116]},
|
||||
"spine": [0, 0],
|
||||
"neck": 0,
|
||||
"shoulder_r": {"flexion": 12, "abduction": 84}, "elbow_r": 15,
|
||||
"shoulder_l": {"flexion": 12, "abduction": 84}, "elbow_l": 15,
|
||||
"hip_r": 78, "knee_r": 62,
|
||||
"hip_l": 78, "knee_l": 62
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
# Romanian Deadlift
|
||||
|
||||
The stretch-focused hip hinge — push the hips back with soft knees until
|
||||
the hamstrings stop you, then stand back up. Barbell or dumbbells.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Free-weight hinge (barbell or dumbbells)
|
||||
- **Targets:** Hamstrings, glutes, spinal erectors
|
||||
- **Prescription:** 3 × 8–10
|
||||
|
||||
## Setup
|
||||
|
||||
Stand tall holding the bar (or dumbbells) at the hips, feet hip-width,
|
||||
knees unlocked. Set your shoulders back and brace.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Push the hips straight back and let the weight slide down the thighs,
|
||||
back flat, knees only slightly bent.
|
||||
2. Stop when the hamstrings are fully stretched — usually just below the
|
||||
knees — without the back rounding.
|
||||
3. Drive the hips forward to stand tall again.
|
||||
|
||||
## Cues
|
||||
|
||||
- The hips travel backward, not down — this is not a squat.
|
||||
- Weight stays close to the legs the whole rep.
|
||||
- Feel the hamstrings load on the way down; that stretch is the exercise.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Bending the knees more as the weight lowers, turning it into a deadlift.
|
||||
- Rounding the back to reach the floor — depth comes from the hips.
|
||||
- Rushing the lowering phase.
|
||||
|
||||
## Progression
|
||||
|
||||
Add weight once the full stretch is reached with a flat back every rep;
|
||||
single-leg RDLs for balance and asymmetry work.
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "Romanian Deadlift",
|
||||
"primary": 1,
|
||||
"camera": {"zoom": 0.7},
|
||||
"working": ["leg_r", "leg_l", "spine"],
|
||||
"props": [
|
||||
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 26, "plateR": 13}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 0.9,
|
||||
"root": {"pos": [90, 92], "pitch": 68},
|
||||
"spine": [0, -6],
|
||||
"neck": 5, "head": -62,
|
||||
"shoulder_r": 66, "elbow_r": 4,
|
||||
"shoulder_l": 66, "elbow_l": 4,
|
||||
"hip_r": 112, "knee_r": 12, "ankle_r": 12,
|
||||
"hip_l": 112, "knee_l": 12, "ankle_l": 12,
|
||||
"pins": {"foot_r": [158, 147], "foot_l": [162, 149],
|
||||
"hand_r": [167, 120], "hand_l": [171, 122]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 1.4,
|
||||
"root": {"pos": [158, 64], "pitch": 10},
|
||||
"spine": [0, 0],
|
||||
"neck": 2, "head": -8,
|
||||
"shoulder_r": 10, "elbow_r": 3,
|
||||
"shoulder_l": 10, "elbow_l": 3,
|
||||
"hip_r": 8, "knee_r": 8, "ankle_r": 0,
|
||||
"hip_l": 8, "knee_l": 8, "ankle_l": 0,
|
||||
"pins": {"foot_r": [158, 147], "foot_l": [162, 149],
|
||||
"hand_r": [169, 38], "hand_l": [173, 40]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
# Triceps Pushdown
|
||||
|
||||
The cable triceps staple — elbows pinned to the sides, push the bar from
|
||||
chest height down to straight arms.
|
||||
|
||||
- **Category:** Main circuit
|
||||
- **Type:** Machine-based cable elbow extension
|
||||
- **Targets:** Triceps
|
||||
- **Prescription:** 3 × 10–12
|
||||
|
||||
## Setup
|
||||
|
||||
Stand at the high pulley with a bar or rope attachment, feet under the
|
||||
hips, slight forward lean. Grip with the elbows bent past 90° and tucked
|
||||
to the ribs.
|
||||
|
||||
## Execution
|
||||
|
||||
1. Push the handle down until the arms are completely straight.
|
||||
2. Squeeze the triceps at the bottom for a beat.
|
||||
3. Let the forearms ride back up until they pass 90°, elbows never
|
||||
leaving the sides.
|
||||
|
||||
## Cues
|
||||
|
||||
- Elbows are bolted to the ribs — only the forearms move.
|
||||
- Stand tall-ish; don't lean your bodyweight onto the bar.
|
||||
- Full lockout every rep; the last few degrees are the exercise.
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
- Elbows drifting forward and up on the way down.
|
||||
- Shoulders and back pressing the weight instead of the triceps.
|
||||
- Cutting the top of the rep short.
|
||||
|
||||
## Progression
|
||||
|
||||
Add a plate when every rep locks out with quiet elbows; a rope
|
||||
attachment adds a harder finish at the bottom.
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "Triceps Pushdown",
|
||||
"primary": 2,
|
||||
"camera": {"zoom": 0.7},
|
||||
"working": ["arm_r", "arm_l"],
|
||||
"props": [
|
||||
{"type": "scene", "shapes": [
|
||||
{"kind": "circle", "c": [186, -58], "r": 4, "fill": true, "color": "prop"}
|
||||
]},
|
||||
{"type": "cable", "from": [186, -58], "to": ["hand_r", "hand_l"], "w": 3},
|
||||
{"type": "bar", "at": ["hand_r", "hand_l"], "halfLen": 10}
|
||||
],
|
||||
"frames": [
|
||||
{
|
||||
"hold": 0.4, "tween": 1.0,
|
||||
"root": {"pos": [150, 66], "pitch": 8},
|
||||
"spine": [0, 2],
|
||||
"neck": 6, "head": -8,
|
||||
"shoulder_r": 15, "elbow_r": 130,
|
||||
"shoulder_l": 15, "elbow_l": 130,
|
||||
"hip_r": 6, "knee_r": 5, "ankle_r": 0,
|
||||
"hip_l": 6, "knee_l": 5, "ankle_l": 0,
|
||||
"pins": {"foot_r": [146, 148], "foot_l": [150, 150],
|
||||
"hand_r": [172, -10], "hand_l": [176, -8]}
|
||||
},
|
||||
{
|
||||
"hold": 0.4, "tween": 1.1,
|
||||
"root": {"pos": [150, 66], "pitch": 8},
|
||||
"spine": [0, 2],
|
||||
"neck": 6, "head": -8,
|
||||
"shoulder_r": 8, "elbow_r": 10,
|
||||
"shoulder_l": 8, "elbow_l": 10,
|
||||
"hip_r": 6, "knee_r": 5, "ankle_r": 0,
|
||||
"hip_l": 6, "knee_l": 5, "ankle_l": 0,
|
||||
"pins": {"foot_r": [146, 148], "foot_l": [150, 150],
|
||||
"hand_r": [168, 40], "hand_l": [172, 42]}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -21,8 +21,9 @@ struct ExerciseMotionTests {
|
||||
}
|
||||
|
||||
@Test func exerciseWithoutBundledMotionLoadsNothing() {
|
||||
#expect(ExerciseMotionLibrary.resources(for: "Bench Press") == nil)
|
||||
#expect(FigureAnimation(exerciseName: "Bench Press") == nil)
|
||||
// Cardio equipment is a permanent library exclusion (see COVERAGE.md).
|
||||
#expect(ExerciseMotionLibrary.resources(for: "Treadmill") == nil)
|
||||
#expect(FigureAnimation(exerciseName: "Treadmill") == nil)
|
||||
}
|
||||
|
||||
/// Resolving Bird Dog's first key frame must reproduce the reference IK: both
|
||||
@@ -130,7 +131,7 @@ struct ExerciseMotionTests {
|
||||
bundle.url(forResource: "figure-fixtures", withExtension: "json"),
|
||||
"figure-fixtures.json must be bundled as a WorkoutsTests resource (see project.yml)")
|
||||
let fixtures = try JSONDecoder().decode(FigureFixtures.self, from: Data(contentsOf: url))
|
||||
#expect(fixtures.exercises.count == 22)
|
||||
#expect(fixtures.exercises.count == 47)
|
||||
|
||||
for exercise in fixtures.exercises {
|
||||
let resources = try #require(ExerciseMotionLibrary.resources(for: exercise.name),
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user