export type MachineCategory = | "Engines" | "Gearboxes & Drives" | "Pumps & Fluid Systems" | "Mechanisms" | "Structural / Other"; export type Difficulty = "Beginner" | "Intermediate" | "Advanced"; export interface MachineFact { label: string; value: string; } export interface MachinePart { id: string; name: string; role: string; description: string; specs?: Record; } export interface GuidedTourStep { id: string; title: string; caption: string; partId?: string; cameraPreset?: string; } export interface MachineDefinition { id: string; title: string; category: MachineCategory; difficulty: Difficulty; complexity: number; dateAdded: string; accentColor: string; description: string; keywords: string[]; facts: MachineFact[]; parts: MachinePart[]; tour: GuidedTourStep[]; relatedIds: string[]; } export const machineCategories: readonly MachineCategory[] = [ "Engines", "Gearboxes & Drives", "Pumps & Fluid Systems", "Mechanisms", "Structural / Other", ]; export const difficultyLevels: readonly Difficulty[] = ["Beginner", "Intermediate", "Advanced"]; function fact(label: string, value: string): MachineFact { return { label, value }; } function part( id: string, name: string, role: string, description: string, specs: Record = {}, ): MachinePart { return { id, name, role, description, specs }; } function step( id: string, title: string, caption: string, partId?: string, cameraPreset: string = "isometric", ): GuidedTourStep { return { id, title, caption, partId, cameraPreset }; } export const coreMachines: readonly MachineDefinition[] = [ { id: "four-stroke-petrol-engine", title: "Four Stroke Petrol Engine", category: "Engines", difficulty: "Beginner", complexity: 4, dateAdded: "2025-01-05", accentColor: "#4C8DFF", description: "A spark-ignition reciprocating engine that converts fuel energy into crankshaft torque through intake, compression, combustion, and exhaust strokes.", keywords: ["petrol", "gasoline", "otto", "piston", "valve", "crankshaft", "camshaft"], facts: [ fact("Cycle", "Intake, compression, power, exhaust"), fact("Typical speed", "800–7,000 RPM"), fact("Invented", "Nikolaus Otto, 1876"), fact("Applications", "Cars, motorcycles, portable power"), ], parts: [ part("cylinder-block", "Cylinder block", "housing", "Rigid casting that locates the cylinder bore, coolant passages, and crankcase."), part("piston", "Piston", "piston", "Reciprocating component that receives combustion pressure and transfers force to the connecting rod."), part("connecting-rod", "Connecting rod", "linkage", "Pinned link that converts piston thrust into crank rotation."), part("crankshaft", "Crankshaft", "crankshaft", "Offset shaft that turns reciprocating force into useful rotary output."), part("camshaft", "Camshaft", "camshaft", "Profiled shaft that opens valves at precise crank angles."), part("intake-valve", "Intake valve", "valve", "Poppet valve admitting the air-fuel charge during the intake stroke."), part("exhaust-valve", "Exhaust valve", "valve", "Heat-resistant valve that releases burned gases after the power stroke."), part("spark-plug", "Spark plug", "injector", "High-voltage electrode that ignites the compressed air-fuel mixture."), ], tour: [ step("stroke-intake", "Intake stroke", "The piston descends while the intake valve opens to draw fresh charge into the cylinder.", "intake-valve", "front"), step("stroke-compression", "Compression stroke", "Both valves close and the rising piston compresses the mixture for efficient combustion.", "piston", "right"), step("stroke-power", "Power stroke", "The spark plug ignites the charge and combustion pressure drives the piston down.", "spark-plug", "isometric"), step("stroke-exhaust", "Exhaust stroke", "The exhaust valve opens as the piston pushes burned gas out of the cylinder.", "exhaust-valve", "left"), ], relatedIds: ["diesel-engine", "two-stroke-engine", "slider-crank"], }, { id: "two-stroke-engine", title: "Two Stroke Engine", category: "Engines", difficulty: "Beginner", complexity: 3, dateAdded: "2025-01-08", accentColor: "#58D68D", description: "A compact reciprocating engine that completes a power cycle every crankshaft revolution using ports uncovered by the piston.", keywords: ["two stroke", "ports", "piston", "crankcase", "scavenging"], facts: [ fact("Cycle", "Compression/power plus scavenging"), fact("Typical speed", "2,000–12,000 RPM"), fact("Power density", "High for size and mass"), fact("Applications", "Chainsaws, scooters, marine outboards"), ], parts: [ part("cylinder", "Cylinder", "housing", "Bore and ported wall guiding piston motion."), part("piston", "Piston", "piston", "Controls port timing while compressing and expanding gas."), part("crankcase", "Crankcase", "housing", "Sealed lower chamber that pre-compresses the fresh charge."), part("transfer-port", "Transfer port", "port", "Passage that feeds fresh mixture from crankcase to cylinder."), part("exhaust-port", "Exhaust port", "port", "Opening uncovered by the piston to release exhaust gas."), part("crankshaft", "Crankshaft", "crankshaft", "Single-revolution output shaft driven once per cycle."), part("spark-plug", "Spark plug", "injector", "Ignition source for the compressed mixture."), ], tour: [ step("compression", "Compression and intake", "The rising piston compresses the cylinder charge while drawing mixture into the crankcase.", "piston", "front"), step("power", "Power stroke", "Combustion drives the piston down and simultaneously pre-compresses charge below it.", "spark-plug", "isometric"), step("scavenge", "Scavenging", "Ports open near bottom dead centre, exhaust exits, and fresh mixture sweeps the cylinder.", "transfer-port", "right"), ], relatedIds: ["four-stroke-petrol-engine", "wankel-rotary-engine", "slider-crank"], }, { id: "diesel-engine", title: "Diesel Engine", category: "Engines", difficulty: "Intermediate", complexity: 5, dateAdded: "2025-01-10", accentColor: "#FFB04C", description: "A compression-ignition engine that injects fuel into hot compressed air, producing strong low-speed torque and high thermal efficiency.", keywords: ["diesel", "compression ignition", "injector", "piston", "torque"], facts: [ fact("Ignition", "Fuel injected into hot compressed air"), fact("Compression ratio", "14:1–22:1 typical"), fact("Invented", "Rudolf Diesel, 1890s"), fact("Applications", "Trucks, ships, generators, heavy equipment"), ], parts: [ part("engine-block", "Engine block", "housing", "Heavy casting designed for high cylinder pressures."), part("piston", "Piston", "piston", "Bowl-shaped crown promotes fuel-air mixing during injection."), part("connecting-rod", "Connecting rod", "linkage", "High-strength link sized for diesel peak pressure."), part("crankshaft", "Crankshaft", "crankshaft", "Robust shaft delivering high torque pulses."), part("injector", "Fuel injector", "injector", "Precision nozzle atomizing diesel fuel into the combustion chamber."), part("intake-valve", "Intake valve", "valve", "Admits fresh air without premixed fuel."), part("exhaust-valve", "Exhaust valve", "valve", "Releases high-temperature exhaust gases."), part("glow-plug", "Glow plug", "injector", "Cold-start heater used on many light-duty diesels."), ], tour: [ step("air", "Air-only intake", "Unlike a petrol engine, only air is inducted before compression.", "intake-valve", "front"), step("compression", "High compression", "The piston compresses air until it is hot enough to ignite injected fuel.", "piston", "right"), step("injection", "Injection event", "Fuel atomizes from the injector and auto-ignites in the hot air.", "injector", "top"), ], relatedIds: ["four-stroke-petrol-engine", "turbocharger", "piston-pump"], }, { id: "v8-engine", title: "V8 Engine", category: "Engines", difficulty: "Advanced", complexity: 8, dateAdded: "2025-01-12", accentColor: "#C084FC", description: "An eight-cylinder engine arranged in two banks sharing a common crankshaft, valued for smooth torque delivery and compact high-output packaging.", keywords: ["v8", "firing order", "banks", "crankshaft", "engine"], facts: [ fact("Layout", "Two banks of four cylinders"), fact("Bank angle", "60°–90° common"), fact("Typical speed", "600–8,000 RPM"), fact("Applications", "Performance cars, trucks, marine power"), ], parts: [ part("left-bank", "Left cylinder bank", "housing", "Four-cylinder bank angled from the crankshaft centreline."), part("right-bank", "Right cylinder bank", "housing", "Opposed bank phasing firing pulses against the left bank."), part("pistons", "Piston set", "piston", "Eight reciprocating pistons animated with a staggered firing order."), part("crankshaft", "Crankshaft", "crankshaft", "Multi-throw shaft coordinating all eight connecting rods."), part("camshafts", "Camshafts", "camshaft", "Valve timing shafts serving the two cylinder banks."), part("intake-manifold", "Intake manifold", "fluid", "Plenum and runners distributing air to each cylinder."), part("exhaust-headers", "Exhaust headers", "fluid", "Tuned pipes carrying exhaust pulses away from each bank."), ], tour: [ step("banks", "V bank packaging", "Two angled cylinder banks shorten the engine while preserving displacement.", "left-bank", "front"), step("firing", "Firing order", "Crank throws and cam timing sequence combustion pulses for smooth output.", "crankshaft", "isometric"), step("breathing", "Air and exhaust paths", "Manifolds distribute intake charge and collect exhaust from each bank.", "intake-manifold", "top"), ], relatedIds: ["four-stroke-petrol-engine", "turbocharger", "disc-brake-caliper"], }, { id: "wankel-rotary-engine", title: "Wankel Rotary Engine", category: "Engines", difficulty: "Advanced", complexity: 7, dateAdded: "2025-01-14", accentColor: "#F97316", description: "A rotary internal-combustion engine where a triangular rotor orbits inside an epitrochoid housing to create changing working chambers.", keywords: ["wankel", "rotary", "epitrochoid", "rotor", "eccentric shaft"], facts: [ fact("Motion", "Eccentric orbital rotor"), fact("Cycle", "Three chambers cycle simultaneously"), fact("Patented", "Felix Wankel, 1929"), fact("Applications", "Mazda rotary cars, UAVs, compact generators"), ], parts: [ part("epitrochoid-housing", "Epitrochoid housing", "housing", "Oval-like chamber profile sealed by the rotor apexes."), part("triangular-rotor", "Triangular rotor", "rotor", "Rounded triangular rotor forming three moving combustion chambers."), part("eccentric-shaft", "Eccentric shaft", "crankshaft", "Offset shaft receiving orbital rotor torque."), part("apex-seals", "Apex seals", "seal", "Sliding seals at rotor tips that separate adjacent chambers."), part("intake-port", "Intake port", "port", "Fixed opening timed by rotor motion."), part("exhaust-port", "Exhaust port", "port", "Outlet uncovered by the rotor during exhaust phase."), part("spark-plugs", "Twin spark plugs", "injector", "Ignition electrodes spanning the elongated chamber."), ], tour: [ step("housing", "Epitrochoid housing", "The housing profile creates three chambers around the moving rotor.", "epitrochoid-housing", "front"), step("rotor", "Orbital rotor", "The rotor spins and orbits on the eccentric shaft, changing chamber volume.", "triangular-rotor", "isometric"), step("ports", "Port timing", "No poppet valves are needed; the rotor itself uncovers intake and exhaust ports.", "intake-port", "right"), ], relatedIds: ["two-stroke-engine", "four-stroke-petrol-engine", "gear-pump"], }, { id: "steam-engine", title: "Steam Engine", category: "Engines", difficulty: "Intermediate", complexity: 5, dateAdded: "2025-01-16", accentColor: "#93C5FD", description: "A reciprocating external-combustion engine that uses pressurized steam, a slide valve, and flywheel inertia to produce continuous rotation.", keywords: ["steam", "slide valve", "flywheel", "governor", "piston"], facts: [ fact("Working fluid", "Pressurized steam"), fact("Control", "Slide valve and centrifugal governor"), fact("Historic era", "18th–19th century industrial power"), fact("Applications", "Locomotives, mills, pumps, marine engines"), ], parts: [ part("steam-cylinder", "Steam cylinder", "housing", "Pressure vessel guiding the power piston."), part("piston", "Piston", "piston", "Alternately driven from each side by steam admission."), part("slide-valve", "Slide valve", "valve", "Shuttles steam to either end of the cylinder while opening exhaust."), part("connecting-rod", "Connecting rod", "linkage", "Links piston rod to crank pin."), part("flywheel", "Flywheel", "wheel", "Stores rotational energy to carry the mechanism through dead centres."), part("crankshaft", "Crankshaft", "crankshaft", "Output shaft driven by the rod and flywheel."), part("governor", "Centrifugal governor", "governor", "Speed-sensitive balls throttle steam admission."), ], tour: [ step("admission", "Steam admission", "The slide valve alternates high-pressure steam to opposite cylinder ends.", "slide-valve", "front"), step("conversion", "Linear to rotary motion", "The rod and crank convert piston motion into flywheel rotation.", "connecting-rod", "isometric"), step("governor", "Speed control", "Governor balls rise with speed and reduce steam flow.", "governor", "top"), ], relatedIds: ["slider-crank", "piston-pump", "centrifugal-pump"], }, { id: "jet-engine-turbojet", title: "Jet Engine (Turbojet)", category: "Engines", difficulty: "Advanced", complexity: 8, dateAdded: "2025-01-18", accentColor: "#38BDF8", description: "A gas turbine engine that accelerates air through compressor, combustor, turbine, and nozzle stages to generate high-velocity thrust.", keywords: ["turbojet", "compressor", "combustion chamber", "turbine", "nozzle", "thrust"], facts: [ fact("Cycle", "Brayton cycle"), fact("Core flow", "All inlet air passes through the gas generator"), fact("Typical speed", "10,000–25,000 RPM core"), fact("Applications", "Early jets, missiles, high-speed demonstrators"), ], parts: [ part("intake", "Intake", "fluid", "Diffuser slowing freestream air before compression."), part("compressor-stages", "Compressor stages", "compressor", "Axial rotor-stator stages increasing air pressure."), part("combustion-chamber", "Combustion chamber", "combustor", "Fuel burns at nearly constant pressure."), part("turbine", "Turbine", "turbine", "Extracts energy to drive the compressor."), part("shaft", "Core shaft", "shaft", "Connects turbine and compressor rotors."), part("exhaust-nozzle", "Exhaust nozzle", "nozzle", "Accelerates hot gas to produce thrust."), part("fuel-injectors", "Fuel injectors", "injector", "Spray fuel into the combustor primary zone."), ], tour: [ step("intake", "Intake and diffusion", "Incoming air slows and pressure recovers before compressor entry.", "intake", "front"), step("compressor", "Compression", "Axial compressor stages progressively raise pressure.", "compressor-stages", "right"), step("combustor", "Combustion", "Fuel burns in a stabilized flame, adding heat to the core flow.", "combustion-chamber", "isometric"), step("nozzle", "Thrust", "The nozzle converts thermal energy into high-speed exhaust momentum.", "exhaust-nozzle", "back"), ], relatedIds: ["turbofan-engine", "turbocharger", "centrifugal-pump"], }, { id: "turbofan-engine", title: "Turbofan Engine", category: "Engines", difficulty: "Advanced", complexity: 9, dateAdded: "2025-01-19", accentColor: "#60A5FA", description: "A modern aircraft gas turbine using a large fan to split air into efficient bypass flow and a high-energy core stream.", keywords: ["turbofan", "bypass", "fan", "compressor", "turbine", "aircraft"], facts: [ fact("Bypass ratio", "2:1 to over 12:1 depending on engine"), fact("Efficiency", "Higher propulsive efficiency than turbojets"), fact("Typical speed", "Fan 2,000–6,000 RPM; core higher"), fact("Applications", "Commercial aircraft, business jets, military transports"), ], parts: [ part("fan", "Fan", "fan", "Large front rotor accelerating bypass and core air."), part("bypass-duct", "Bypass duct", "fluid", "Annular passage carrying air around the core."), part("low-pressure-compressor", "Low-pressure compressor", "compressor", "Boosts core air after the fan."), part("high-pressure-compressor", "High-pressure compressor", "compressor", "Raises core pressure before combustion."), part("combustor", "Combustor", "combustor", "Adds heat energy to the compressed core flow."), part("turbines", "Turbines", "turbine", "Extract energy for fan and compressor spools."), part("core-nozzle", "Core nozzle", "nozzle", "Accelerates core exhaust."), part("bypass-nozzle", "Bypass nozzle", "nozzle", "Turns fan pressure into efficient thrust."), ], tour: [ step("fan", "Fan thrust", "Most air can bypass the hot core, improving propulsive efficiency.", "fan", "front"), step("split", "Flow split", "The bypass duct separates cool fan flow from the hot gas generator.", "bypass-duct", "isometric"), step("core", "Core gas generator", "Compressor, combustor, and turbine sustain the Brayton cycle.", "high-pressure-compressor", "right"), ], relatedIds: ["jet-engine-turbojet", "turbocharger", "centrifugal-pump"], }, { id: "planetary-gearbox", title: "Planetary Gearbox", category: "Gearboxes & Drives", difficulty: "Intermediate", complexity: 6, dateAdded: "2025-01-21", accentColor: "#FACC15", description: "An epicyclic gear train where sun, planet, carrier, and ring members can be selected as input, output, or held reaction elements.", keywords: ["planetary", "epicyclic", "sun gear", "ring gear", "carrier", "ratio"], facts: [ fact("Members", "Sun, planets, carrier, ring"), fact("Advantage", "High torque density and coaxial input/output"), fact("Typical ratios", "3:1–10:1 per stage"), fact("Applications", "Automatics, robotics, wind turbines, drills"), ], parts: [ part("sun-gear", "Sun gear", "gear", "Central gear meshing with every planet."), part("planet-gears", "Planet gears", "gear", "Multiple gears orbiting the sun while spinning on their pins."), part("planet-carrier", "Planet carrier", "planet-carrier", "Armature holding planet pins and delivering combined torque."), part("ring-gear", "Ring gear", "ring-gear", "Internal-tooth annulus enclosing the planet set."), part("input-shaft", "Input shaft", "shaft", "Coaxial shaft driving the selected member."), part("output-shaft", "Output shaft", "shaft", "Coaxial shaft taking reduced or increased speed."), ], tour: [ step("sun", "Sun input", "Driving the sun while holding the ring makes the carrier rotate at reduced speed.", "sun-gear", "front"), step("planets", "Planet motion", "Planets spin and orbit, sharing load across several tooth meshes.", "planet-gears", "isometric"), step("ring", "Reaction member", "Holding or driving the ring changes the speed ratio and direction.", "ring-gear", "top"), ], relatedIds: ["manual-gearbox-5-speed", "differential-gear", "worm-gear-drive"], }, { id: "differential-gear", title: "Differential Gear", category: "Gearboxes & Drives", difficulty: "Intermediate", complexity: 6, dateAdded: "2025-01-22", accentColor: "#FB923C", description: "A bevel gear assembly that splits torque between two axle shafts while allowing different wheel speeds during cornering.", keywords: ["differential", "bevel gears", "torque split", "cornering", "axle"], facts: [ fact("Function", "Equal torque, variable wheel speed"), fact("Core gears", "Ring gear, pinion, spider gears, side gears"), fact("Typical ratio", "2.5:1–4.5:1 final drive"), fact("Applications", "Cars, trucks, mobile robots"), ], parts: [ part("ring-gear", "Ring gear", "gear", "Large bevel ring driven by the input pinion."), part("drive-pinion", "Drive pinion", "gear", "Small bevel gear receiving prop shaft torque."), part("carrier", "Differential carrier", "housing", "Rotating cage carrying spider gears."), part("spider-gears", "Spider gears", "gear", "Small bevel gears that walk around side gears during speed difference."), part("left-side-gear", "Left side gear", "gear", "Bevel gear splined to the left axle shaft."), part("right-side-gear", "Right side gear", "gear", "Bevel gear splined to the right axle shaft."), part("axle-shafts", "Axle shafts", "shaft", "Outputs delivering torque to wheels."), ], tour: [ step("final-drive", "Final drive reduction", "The pinion drives the ring gear and carrier at reduced speed.", "ring-gear", "front"), step("straight", "Straight-line driving", "Spider gears do not spin on their own axes when wheel speeds match.", "spider-gears", "isometric"), step("cornering", "Cornering speed split", "Spider gears rotate to let outer and inner wheels travel different distances.", "left-side-gear", "top"), ], relatedIds: ["bevel-gear-set", "planetary-gearbox", "manual-gearbox-5-speed"], }, { id: "manual-gearbox-5-speed", title: "Manual Gearbox (5-speed)", category: "Gearboxes & Drives", difficulty: "Advanced", complexity: 8, dateAdded: "2025-01-24", accentColor: "#A3E635", description: "A constant-mesh automotive transmission using selectable gear pairs, synchronizers, selector forks, and a layshaft to provide five forward ratios.", keywords: ["manual gearbox", "synchromesh", "selector fork", "layshaft", "gear ratios"], facts: [ fact("Layout", "Input shaft, layshaft, output shaft"), fact("Selection", "Dog clutch through synchronizer hub"), fact("Ratios", "Wide low gear to direct/overdrive top gear"), fact("Applications", "Passenger cars, motorsport, light trucks"), ], parts: [ part("input-shaft", "Input shaft", "shaft", "Receives clutch torque from the engine."), part("layshaft", "Layshaft", "shaft", "Carries fixed gears that drive free gears on the output shaft."), part("output-shaft", "Output shaft", "shaft", "Delivers selected ratio to the final drive."), part("gear-pairs", "Constant-mesh gear pairs", "gear", "Always-engaged gears with different tooth counts."), part("synchronizer-hubs", "Synchronizer hubs", "gear", "Friction cones match gear speeds before engagement."), part("selector-forks", "Selector forks", "linkage", "Move sleeves to engage the chosen gear."), part("shift-rail", "Shift rail", "rack", "Driver-controlled rail coordinating fork positions."), ], tour: [ step("mesh", "Constant mesh", "Gear teeth stay engaged; selection happens with dog clutches and sleeves.", "gear-pairs", "front"), step("sync", "Synchromesh", "Friction cones match speeds to prevent gear clash.", "synchronizer-hubs", "isometric"), step("fork", "Selector mechanism", "Forks slide sleeves along splines to lock a gear to the output shaft.", "selector-forks", "top"), ], relatedIds: ["planetary-gearbox", "differential-gear", "cvt"], }, { id: "cvt", title: "CVT (Continuously Variable Transmission)", category: "Gearboxes & Drives", difficulty: "Intermediate", complexity: 6, dateAdded: "2025-01-26", accentColor: "#2DD4BF", description: "A transmission that varies ratio continuously by changing the effective diameters of two variable pulleys connected by a belt or chain.", keywords: ["cvt", "continuously variable", "belt", "pulley", "ratio"], facts: [ fact("Ratio control", "Variable pulley sheave spacing"), fact("Benefit", "Keeps engine near efficient operating point"), fact("Common types", "Pushbelt, chain, toroidal variants"), fact("Applications", "Scooters, hybrids, compact cars"), ], parts: [ part("primary-pulley", "Primary pulley", "pulley", "Engine-side variable-diameter pulley."), part("secondary-pulley", "Secondary pulley", "pulley", "Output-side pulley changing inversely with primary."), part("steel-belt", "Steel belt", "belt", "Segmented belt transmitting compressive or tensile force."), part("movable-sheaves", "Movable sheaves", "linkage", "Hydraulically positioned cone faces."), part("ratio-actuator", "Ratio actuator", "cylinder", "Control piston adjusting belt radius."), part("output-shaft", "Output shaft", "shaft", "Carries continuously variable speed to final drive."), ], tour: [ step("low", "Low ratio", "Small primary radius and large secondary radius multiply torque.", "primary-pulley", "front"), step("shift", "Continuous ratio sweep", "Sheaves move smoothly so the belt rides at changing pitch radii.", "steel-belt", "isometric"), step("high", "High ratio", "Large primary radius and small secondary radius reduce engine speed at cruise.", "secondary-pulley", "right"), ], relatedIds: ["manual-gearbox-5-speed", "planetary-gearbox", "worm-gear-drive"], }, { id: "worm-gear-drive", title: "Worm Gear Drive", category: "Gearboxes & Drives", difficulty: "Intermediate", complexity: 5, dateAdded: "2025-01-27", accentColor: "#FDE047", description: "A screw-like worm driving a mating wheel at right angles, producing large speed reduction and potential self-locking behavior.", keywords: ["worm gear", "reduction", "self locking", "right angle", "gear"], facts: [ fact("Axes", "Non-intersecting right-angle shafts"), fact("Reduction", "Often 20:1–100:1 in one stage"), fact("Self-locking", "Possible with low lead angle and friction"), fact("Applications", "Hoists, steering boxes, lifts, tuners"), ], parts: [ part("worm", "Worm", "shaft", "Threaded screw gear driven by the input shaft."), part("worm-wheel", "Worm wheel", "gear", "Helical-tooth gear advanced by the worm thread."), part("input-shaft", "Input shaft", "shaft", "High-speed shaft aligned with the worm."), part("output-shaft", "Output shaft", "shaft", "Low-speed shaft perpendicular to the worm."), part("gearbox-housing", "Gearbox housing", "housing", "Rigid enclosure supporting high sliding loads."), part("thrust-bearings", "Thrust bearings", "bearing", "Bearings resisting axial worm loads."), ], tour: [ step("thread", "Screw action", "Each worm revolution advances the wheel by one or more teeth.", "worm", "front"), step("reduction", "High reduction", "A compact stage produces a large decrease in output speed.", "worm-wheel", "isometric"), step("locking", "Self-locking", "Friction can prevent the wheel from back-driving the worm.", "thrust-bearings", "top"), ], relatedIds: ["bevel-gear-set", "planetary-gearbox", "toggle-clamp"], }, { id: "bevel-gear-set", title: "Bevel Gear Set", category: "Gearboxes & Drives", difficulty: "Beginner", complexity: 4, dateAdded: "2025-01-28", accentColor: "#FDBA74", description: "A pair of conical gears transmitting torque between intersecting shafts, commonly at 90 degrees with straight or spiral teeth.", keywords: ["bevel gear", "right angle", "spiral bevel", "gear"], facts: [ fact("Shafts", "Intersecting axes, usually 90°"), fact("Variants", "Straight, spiral, zerol, hypoid"), fact("Benefit", "Compact direction change"), fact("Applications", "Differentials, hand drills, gearboxes"), ], parts: [ part("drive-bevel", "Drive bevel gear", "gear", "Input conical gear."), part("driven-bevel", "Driven bevel gear", "gear", "Output conical gear at right angle."), part("input-shaft", "Input shaft", "shaft", "Shaft supporting the drive bevel."), part("output-shaft", "Output shaft", "shaft", "Perpendicular output shaft."), part("spiral-teeth", "Spiral tooth pattern", "gear", "Curved teeth increasing overlap and smoothness."), ], tour: [ step("geometry", "Pitch cones", "Bevel gears behave like rolling cones meeting at a common apex.", "drive-bevel", "front"), step("angle", "Right-angle drive", "Torque turns through 90 degrees at the tooth mesh.", "driven-bevel", "isometric"), step("spiral", "Spiral variant", "Curved teeth share load gradually and run quieter.", "spiral-teeth", "top"), ], relatedIds: ["differential-gear", "worm-gear-drive", "manual-gearbox-5-speed"], }, { id: "centrifugal-pump", title: "Centrifugal Pump", category: "Pumps & Fluid Systems", difficulty: "Beginner", complexity: 4, dateAdded: "2025-02-01", accentColor: "#22D3EE", description: "A rotodynamic pump that converts impeller kinetic energy into pressure through a volute casing.", keywords: ["centrifugal pump", "impeller", "volute", "cavitation", "fluid"], facts: [ fact("Principle", "Velocity added by impeller, recovered as pressure"), fact("Typical speed", "1,450–3,600 RPM industrial"), fact("Risk", "Cavitation if inlet pressure is too low"), fact("Applications", "Water supply, cooling, chemical transfer"), ], parts: [ part("volute-casing", "Volute casing", "housing", "Spiral chamber collecting and slowing high-velocity flow."), part("impeller", "Impeller", "impeller", "Rotating vaned wheel accelerating fluid outward."), part("inlet-eye", "Inlet eye", "fluid", "Central suction opening feeding the impeller."), part("discharge", "Discharge nozzle", "nozzle", "Outlet where pressure is delivered to piping."), part("shaft", "Shaft", "shaft", "Motor-driven shaft carrying the impeller."), part("mechanical-seal", "Mechanical seal", "seal", "Prevents leakage where the shaft exits the casing."), part("cavitation-zone", "Cavitation indicator", "fluid", "Low-pressure region visualizing vapor bubble risk."), ], tour: [ step("suction", "Suction eye", "Fluid enters axially at the impeller eye.", "inlet-eye", "front"), step("impeller", "Energy transfer", "Rotating vanes fling fluid outward and raise velocity.", "impeller", "isometric"), step("volute", "Pressure recovery", "The volute area increases, converting velocity into static pressure.", "volute-casing", "top"), ], relatedIds: ["gear-pump", "piston-pump", "jet-engine-turbojet"], }, { id: "gear-pump", title: "Gear Pump", category: "Pumps & Fluid Systems", difficulty: "Beginner", complexity: 4, dateAdded: "2025-02-02", accentColor: "#38BDF8", description: "A positive-displacement pump using meshing gears to carry trapped fluid volumes from inlet to outlet.", keywords: ["gear pump", "positive displacement", "hydraulics", "meshing gears"], facts: [ fact("Pump type", "Positive displacement"), fact("Flow", "Nearly proportional to RPM"), fact("Pressure", "Set by downstream resistance and relief valve"), fact("Applications", "Hydraulic power, lubrication, fuel transfer"), ], parts: [ part("pump-housing", "Pump housing", "housing", "Close-clearance body enclosing the gear pair."), part("drive-gear", "Drive gear", "gear", "Powered gear carrying fluid around the housing wall."), part("idler-gear", "Idler gear", "gear", "Mating gear rotating opposite the drive gear."), part("inlet-port", "Inlet port", "fluid", "Low-pressure side where tooth spaces expand."), part("outlet-port", "Outlet port", "nozzle", "High-pressure side where meshing teeth displace fluid."), part("relief-valve", "Relief valve", "valve", "Bypass valve protecting the pump from overpressure."), ], tour: [ step("inlet", "Volume opens", "Unmeshing teeth create expanding cavities at the inlet.", "inlet-port", "front"), step("carry", "Fluid transport", "Fluid rides around the outside in tooth spaces, not through the mesh.", "drive-gear", "isometric"), step("outlet", "Displacement", "Meshing teeth shrink cavities and force fluid into the outlet.", "outlet-port", "right"), ], relatedIds: ["centrifugal-pump", "piston-pump", "wankel-rotary-engine"], }, { id: "piston-pump", title: "Piston Pump", category: "Pumps & Fluid Systems", difficulty: "Intermediate", complexity: 5, dateAdded: "2025-02-03", accentColor: "#67E8F9", description: "A reciprocating positive-displacement pump that alternately draws fluid through an inlet valve and expels it through an outlet valve.", keywords: ["piston pump", "reciprocating", "check valve", "positive displacement"], facts: [ fact("Pump type", "Reciprocating positive displacement"), fact("Valves", "Inlet and outlet check valves"), fact("Pressure", "High pressure possible at low flow"), fact("Applications", "Pressure washers, dosing, hydraulics"), ], parts: [ part("pump-cylinder", "Pump cylinder", "housing", "Bore containing the reciprocating piston."), part("piston", "Piston", "piston", "Changes chamber volume to draw and expel fluid."), part("crank", "Crank", "crankshaft", "Rotary driver creating reciprocating motion."), part("connecting-rod", "Connecting rod", "linkage", "Connects crank throw to piston."), part("inlet-valve", "Inlet check valve", "valve", "Opens when chamber pressure falls below inlet pressure."), part("outlet-valve", "Outlet check valve", "valve", "Opens when chamber pressure exceeds discharge pressure."), part("fluid-chamber", "Fluid chamber", "fluid", "Working volume whose size changes each stroke."), ], tour: [ step("suction", "Suction stroke", "The piston retracts, chamber pressure drops, and the inlet valve opens.", "inlet-valve", "front"), step("discharge", "Discharge stroke", "The piston advances, closing the inlet and opening the outlet valve.", "outlet-valve", "right"), step("drive", "Crank drive", "The crank and rod provide repeatable reciprocating displacement.", "crank", "isometric"), ], relatedIds: ["hydraulic-cylinder", "steam-engine", "gear-pump"], }, { id: "hydraulic-cylinder", title: "Hydraulic Cylinder", category: "Pumps & Fluid Systems", difficulty: "Beginner", complexity: 3, dateAdded: "2025-02-04", accentColor: "#60A5FA", description: "A linear actuator using pressurized hydraulic fluid acting on a piston area to extend or retract a rod.", keywords: ["hydraulic cylinder", "actuator", "pressure", "seal", "piston rod"], facts: [ fact("Force", "Pressure × piston area"), fact("Motion", "Linear extension and retraction"), fact("Sealing", "Rod, piston, and wiper seals are critical"), fact("Applications", "Excavators, presses, aircraft, automation"), ], parts: [ part("barrel", "Cylinder barrel", "housing", "Pressure tube containing the piston."), part("piston", "Piston", "piston", "Separates cap-end and rod-end chambers."), part("rod", "Piston rod", "shaft", "Polished output member transmitting force externally."), part("cap-port", "Cap-end port", "fluid", "Port feeding extension pressure."), part("rod-port", "Rod-end port", "fluid", "Port feeding retraction pressure."), part("rod-seal", "Rod seal", "seal", "Prevents leakage around the moving rod."), part("pressure-indicator", "Pressure indicator", "fluid", "Visual gauge of hydraulic load."), ], tour: [ step("extend", "Extension", "Pressure at the cap end acts on full piston area and pushes the rod out.", "cap-port", "front"), step("retract", "Retraction", "Pressure at the rod end acts on annular area to pull the rod in.", "rod-port", "right"), step("seal", "Sealing", "Rod seals contain pressure while allowing low-friction motion.", "rod-seal", "isometric"), ], relatedIds: ["piston-pump", "toggle-clamp", "disc-brake-caliper"], }, { id: "scotch-yoke", title: "Scotch Yoke", category: "Mechanisms", difficulty: "Beginner", complexity: 3, dateAdded: "2025-02-07", accentColor: "#F472B6", description: "A crank-and-slot mechanism converting rotary motion directly into sinusoidal linear motion.", keywords: ["scotch yoke", "crank", "slot", "linear motion"], facts: [ fact("Motion law", "Nearly perfect sinusoidal displacement"), fact("Advantage", "Compact conversion with few links"), fact("Wear", "Sliding contact can be high"), fact("Applications", "Actuators, pumps, demonstration mechanisms"), ], parts: [ part("crank-disc", "Crank disc", "crankshaft", "Rotating disc carrying an offset pin."), part("crank-pin", "Crank pin", "linkage", "Pin sliding inside the yoke slot."), part("yoke", "Slotted yoke", "slider", "Linear slider with transverse slot."), part("guide-rails", "Guide rails", "housing", "Rails constraining yoke motion."), part("output-rod", "Output rod", "shaft", "Linear member driven by the yoke."), ], tour: [ step("pin", "Offset pin", "The rotating pin imposes horizontal motion on the slotted yoke.", "crank-pin", "front"), step("slider", "Linear output", "Guide rails prevent rotation, leaving pure reciprocating output.", "yoke", "isometric"), step("motion", "Sinusoidal profile", "Displacement follows the crank pin projection.", "output-rod", "top"), ], relatedIds: ["slider-crank", "piston-pump", "cam-and-follower"], }, { id: "geneva-drive", title: "Geneva Drive", category: "Mechanisms", difficulty: "Intermediate", complexity: 5, dateAdded: "2025-02-08", accentColor: "#A78BFA", description: "An intermittent indexing mechanism where a drive pin advances a slotted wheel one step, then a locking surface holds dwell.", keywords: ["geneva drive", "intermittent", "indexing", "dwell"], facts: [ fact("Motion", "Intermittent rotary indexing"), fact("Dwell", "Driven wheel locks between index moves"), fact("Index count", "Usually 4–12 slots"), fact("Applications", "Film projectors, packaging, indexing tables"), ], parts: [ part("drive-wheel", "Drive wheel", "crankshaft", "Continuously rotating wheel carrying the drive pin."), part("drive-pin", "Drive pin", "linkage", "Pin that enters a slot and advances the Geneva wheel."), part("geneva-wheel", "Geneva wheel", "gear", "Slotted wheel indexed by the pin."), part("locking-disc", "Locking disc", "housing", "Circular surface preventing motion during dwell."), part("output-shaft", "Output shaft", "shaft", "Intermittent rotary output."), ], tour: [ step("entry", "Pin entry", "The pin enters a slot and accelerates the Geneva wheel.", "drive-pin", "front"), step("index", "Index step", "The wheel advances by a fixed angle for each driver revolution.", "geneva-wheel", "isometric"), step("dwell", "Dwell lock", "The locking disc holds position while the driver continues rotating.", "locking-disc", "top"), ], relatedIds: ["cam-and-follower", "rack-and-pinion", "scotch-yoke"], }, { id: "cam-and-follower", title: "Cam and Follower", category: "Mechanisms", difficulty: "Beginner", complexity: 4, dateAdded: "2025-02-09", accentColor: "#FB7185", description: "A shaped rotating cam drives a follower through a programmed displacement profile such as eccentric, heart, or snail lift.", keywords: ["cam", "follower", "profile", "lift", "valve train"], facts: [ fact("Function", "Prescribed displacement from rotating profile"), fact("Profiles", "Eccentric, heart, snail, dwell-rise-dwell"), fact("Contact", "Sliding or rolling follower"), fact("Applications", "Engines, automation, textile machinery"), ], parts: [ part("camshaft", "Camshaft", "camshaft", "Rotating shaft carrying the cam lobe."), part("cam-lobe", "Cam lobe", "cam", "Profile determining follower lift."), part("roller-follower", "Roller follower", "follower", "Rolling contact follower reducing friction."), part("return-spring", "Return spring", "spring", "Maintains contact between follower and cam."), part("guide", "Follower guide", "housing", "Linear guide preventing follower rotation."), part("profile-selector", "Profile selector", "cam", "Reference profiles for eccentric, heart, and snail cams."), ], tour: [ step("profile", "Cam profile", "The lobe radius at each angle defines follower lift.", "cam-lobe", "front"), step("contact", "Follower contact", "A roller lowers friction and surface stress.", "roller-follower", "isometric"), step("spring", "Return force", "The spring keeps the follower seated against the cam.", "return-spring", "right"), ], relatedIds: ["four-stroke-petrol-engine", "geneva-drive", "scotch-yoke"], }, { id: "rack-and-pinion", title: "Rack and Pinion", category: "Mechanisms", difficulty: "Beginner", complexity: 2, dateAdded: "2025-02-10", accentColor: "#34D399", description: "A circular pinion gear meshing with a straight rack to convert rotation into linear motion or the reverse.", keywords: ["rack", "pinion", "linear", "steering", "gear"], facts: [ fact("Conversion", "Rotary to linear motion"), fact("Displacement", "Pinion pitch radius × rotation angle"), fact("Backlash", "Tooth clearance affects precision"), fact("Applications", "Steering, CNC axes, actuators"), ], parts: [ part("pinion", "Pinion gear", "gear", "Circular gear driving or driven by the rack."), part("rack", "Rack", "rack", "Straight toothed bar translating along guides."), part("guide", "Linear guide", "housing", "Maintains rack alignment under tooth loads."), part("input-shaft", "Input shaft", "shaft", "Rotates the pinion."), part("load", "Linear load", "slider", "Mass or actuator load attached to the rack."), ], tour: [ step("mesh", "Tooth mesh", "Pinion teeth engage the rack one pitch at a time.", "pinion", "front"), step("linear", "Linear travel", "Rack displacement equals pinion pitch radius times angular travel.", "rack", "isometric"), step("guide", "Guidance", "A guide resists separating force and keeps tooth contact aligned.", "guide", "top"), ], relatedIds: ["geneva-drive", "slider-crank", "manual-gearbox-5-speed"], }, { id: "slider-crank", title: "Slider Crank", category: "Mechanisms", difficulty: "Beginner", complexity: 3, dateAdded: "2025-02-11", accentColor: "#4ADE80", description: "A four-link mechanism converting rotary crank motion and connecting-rod geometry into reciprocating slider travel.", keywords: ["slider crank", "dead centre", "connecting rod", "piston"], facts: [ fact("Links", "Frame, crank, connecting rod, slider"), fact("Dead centres", "Top and bottom dead centre alignment"), fact("Use", "Core geometry of piston engines and pumps"), fact("Motion", "Approximately sinusoidal with rod-angle effects"), ], parts: [ part("crank", "Crank", "crankshaft", "Rotating link with fixed radius."), part("crank-pin", "Crank pin", "linkage", "Joint between crank and connecting rod."), part("connecting-rod", "Connecting rod", "linkage", "Coupler transmitting force between crank and slider."), part("slider", "Slider", "slider", "Linear block constrained in the guide."), part("guide", "Guide", "housing", "Frame slot or cylinder bore constraining the slider."), part("dead-centre-markers", "Dead-centre markers", "generic", "References showing top and bottom dead centre positions."), ], tour: [ step("crank", "Crank radius", "The crank radius sets half the nominal stroke.", "crank", "front"), step("rod", "Rod angle", "Finite rod length slightly skews piston motion from a pure sine wave.", "connecting-rod", "isometric"), step("dead-centre", "Dead centres", "When crank and rod align, torque leverage approaches zero.", "dead-centre-markers", "top"), ], relatedIds: ["four-stroke-petrol-engine", "scotch-yoke", "piston-pump"], }, { id: "toggle-clamp", title: "Toggle Clamp", category: "Mechanisms", difficulty: "Intermediate", complexity: 4, dateAdded: "2025-02-12", accentColor: "#F59E0B", description: "A linkage clamp that passes slightly over centre so load force increases mechanical advantage and resists reopening.", keywords: ["toggle clamp", "over centre", "mechanical advantage", "linkage"], facts: [ fact("Principle", "Over-centre locking linkage"), fact("Advantage", "High holding force near toggle position"), fact("Release", "Handle moves linkage back through centre"), fact("Applications", "Fixtures, woodworking, welding jigs"), ], parts: [ part("base", "Base", "housing", "Mounting frame carrying the pivots."), part("handle", "Handle", "linkage", "Operator input lever."), part("toggle-links", "Toggle links", "linkage", "Pair of links approaching straight-line lock."), part("clamp-arm", "Clamp arm", "linkage", "Output lever applying force to the workpiece."), part("pressure-pad", "Pressure pad", "slider", "Adjustable contact pad at the clamp end."), part("over-centre-stop", "Over-centre stop", "generic", "Stop that places the linkage just beyond centre."), ], tour: [ step("approach", "Mechanical advantage", "As the toggle links straighten, small handle motion creates high clamp force.", "toggle-links", "front"), step("lock", "Over-centre lock", "The linkage passes centre so load tends to keep it shut.", "over-centre-stop", "isometric"), step("pad", "Work contact", "The pressure pad spreads force and adjusts for part thickness.", "pressure-pad", "right"), ], relatedIds: ["hydraulic-cylinder", "worm-gear-drive", "slider-crank"], }, { id: "ball-bearing", title: "Ball Bearing", category: "Structural / Other", difficulty: "Beginner", complexity: 3, dateAdded: "2025-02-15", accentColor: "#CBD5E1", description: "A rolling-element bearing using balls between inner and outer races to reduce friction while supporting radial and axial loads.", keywords: ["bearing", "ball", "race", "cage", "load distribution"], facts: [ fact("Elements", "Inner race, outer race, balls, cage"), fact("Load", "Point contact, moderate radial/axial capacity"), fact("Benefit", "Low rolling friction"), fact("Applications", "Motors, wheels, fans, tools"), ], parts: [ part("outer-race", "Outer race", "bearing", "Stationary or housing-mounted raceway."), part("inner-race", "Inner race", "bearing", "Shaft-mounted raceway rotating relative to outer race."), part("balls", "Balls", "ball", "Rolling elements carrying load through point contact."), part("cage", "Cage", "cage", "Separator keeping balls evenly spaced."), part("load-zone", "Load distribution", "fluid", "Highlighted arc where rolling elements carry highest load."), part("seal", "Seal", "seal", "Keeps lubricant in and contaminants out."), ], tour: [ step("races", "Raceways", "Hardened race grooves guide each ball around the bearing.", "outer-race", "front"), step("balls", "Rolling contact", "Balls replace sliding friction with rolling contact.", "balls", "isometric"), step("load", "Load zone", "Only a portion of the rolling elements carry the peak radial load.", "load-zone", "top"), ], relatedIds: ["roller-bearing", "worm-gear-drive", "disc-brake-caliper"], }, { id: "roller-bearing", title: "Roller Bearing", category: "Structural / Other", difficulty: "Intermediate", complexity: 4, dateAdded: "2025-02-16", accentColor: "#94A3B8", description: "A rolling bearing using cylindrical or tapered rollers for higher load capacity through line contact.", keywords: ["roller bearing", "tapered roller", "race", "line contact"], facts: [ fact("Contact", "Line contact for high radial load"), fact("Tapered variant", "Supports combined radial and axial load"), fact("Alignment", "Sensitive to misalignment"), fact("Applications", "Wheel hubs, gearboxes, conveyors"), ], parts: [ part("outer-race", "Outer race", "bearing", "Conical or cylindrical outer raceway."), part("inner-race", "Inner race", "bearing", "Inner raceway mounted to the shaft."), part("rollers", "Tapered rollers", "roller", "Rolling elements carrying load along a line."), part("cage", "Cage", "cage", "Controls roller spacing and skew."), part("thrust-line", "Thrust line", "fluid", "Reference showing how tapered geometry resolves axial force."), part("lubrication-film", "Lubrication film", "fluid", "Thin oil film separating rolling contacts."), ], tour: [ step("rollers", "Line contact", "Rollers spread load over a line instead of a point.", "rollers", "front"), step("taper", "Tapered geometry", "Taper apexes meet on the bearing axis to avoid sliding.", "inner-race", "isometric"), step("thrust", "Combined load", "Tapered rollers can react radial and axial components together.", "thrust-line", "top"), ], relatedIds: ["ball-bearing", "differential-gear", "manual-gearbox-5-speed"], }, { id: "disc-brake-caliper", title: "Disc Brake Caliper", category: "Structural / Other", difficulty: "Intermediate", complexity: 5, dateAdded: "2025-02-18", accentColor: "#EF4444", description: "A hydraulic brake assembly that clamps friction pads onto a rotating disc, converting kinetic energy into heat.", keywords: ["disc brake", "caliper", "pad", "rotor", "hydraulic piston"], facts: [ fact("Force source", "Hydraulic pressure on caliper pistons"), fact("Energy", "Kinetic energy converted to heat"), fact("Materials", "Cast iron, steel, carbon ceramic, friction composite"), fact("Applications", "Cars, motorcycles, bicycles, aircraft"), ], parts: [ part("rotor", "Brake rotor", "brake-disc", "Rotating disc attached to the wheel hub."), part("caliper-body", "Caliper body", "caliper", "Rigid bridge reacting clamp force."), part("pistons", "Hydraulic pistons", "piston", "Pistons pushing brake pads against the rotor."), part("inner-pad", "Inner pad", "pad", "Friction material contacting one side of the rotor."), part("outer-pad", "Outer pad", "pad", "Friction material contacting the opposite side."), part("brake-line", "Brake line", "fluid", "Hydraulic line transmitting pedal pressure."), part("heat-vanes", "Cooling vanes", "fan", "Rotor passages increasing convective cooling."), ], tour: [ step("pressure", "Hydraulic actuation", "Fluid pressure pushes pistons outward with controllable clamp force.", "pistons", "front"), step("friction", "Pad contact", "Pads squeeze the rotor and generate braking torque.", "inner-pad", "isometric"), step("heat", "Heat rejection", "Rotor mass and vanes absorb and reject thermal energy.", "heat-vanes", "top"), ], relatedIds: ["hydraulic-cylinder", "ball-bearing", "v8-engine"], }, { id: "turbocharger", title: "Turbocharger", category: "Structural / Other", difficulty: "Advanced", complexity: 7, dateAdded: "2025-02-20", accentColor: "#38BDF8", description: "An exhaust-driven compressor that increases engine air mass flow using a turbine, shared shaft, compressor wheel, and wastegate control.", keywords: ["turbocharger", "compressor", "turbine", "wastegate", "boost"], facts: [ fact("Energy source", "Exhaust enthalpy drives turbine"), fact("Speed", "80,000–250,000 RPM common"), fact("Control", "Wastegate or variable turbine geometry"), fact("Applications", "Diesel engines, performance petrol engines, aviation"), ], parts: [ part("compressor-wheel", "Compressor wheel", "compressor", "Cold-side wheel raising intake air pressure."), part("compressor-housing", "Compressor housing", "housing", "Volute casing diffusing compressor flow."), part("turbine-wheel", "Turbine wheel", "turbine", "Hot-side wheel extracting exhaust energy."), part("turbine-housing", "Turbine housing", "housing", "Scroll housing accelerating exhaust onto turbine blades."), part("shaft", "Common shaft", "shaft", "High-speed shaft coupling turbine and compressor."), part("bearing-cartridge", "Bearing cartridge", "bearing", "Journal or ball bearing centre section with oil cooling."), part("wastegate", "Wastegate", "valve", "Bypass valve limiting turbine power and boost pressure."), part("boost-flow", "Boost flow", "fluid", "Compressed intake path feeding the engine."), ], tour: [ step("turbine", "Exhaust energy", "Exhaust gas spins the turbine wheel at very high speed.", "turbine-wheel", "right"), step("shaft", "Shared shaft", "The shaft transmits turbine power to the compressor wheel.", "shaft", "isometric"), step("compressor", "Boost production", "The compressor raises intake pressure and engine air mass.", "compressor-wheel", "front"), step("wastegate", "Boost control", "The wastegate bypasses exhaust to regulate turbine speed.", "wastegate", "top"), ], relatedIds: ["diesel-engine", "turbofan-engine", "centrifugal-pump"], }, ]; export const defaultMachineId = coreMachines[0].id; export const machinesById: Readonly> = coreMachines.reduce< Record >((registry, machine) => { registry[machine.id] = machine; return registry; }, {}); export function getMachineById(machineId: string | undefined | null): MachineDefinition | undefined { if (!machineId) { return undefined; } return machinesById[machineId]; } export function getRelatedMachines(machine: MachineDefinition): MachineDefinition[] { return machine.relatedIds .map((relatedId) => machinesById[relatedId]) .filter((relatedMachine): relatedMachine is MachineDefinition => Boolean(relatedMachine)); } export function searchMachines(query: string): MachineDefinition[] { const normalizedQuery = query.trim().toLowerCase(); if (!normalizedQuery) { return [...coreMachines]; } return coreMachines.filter((machine) => { const searchable = [ machine.title, machine.category, machine.difficulty, machine.description, ...machine.keywords, ...machine.parts.map((machinePart) => machinePart.name), ...machine.parts.map((machinePart) => machinePart.description), ] .join(" ") .toLowerCase(); return searchable.includes(normalizedQuery); }); }