dingbatch 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/generators/utils/svg.ts","../src/presets/boomerang.ts","../src/generators/curved/boomerang.ts"],"sourcesContent":["// src/generators/utils/svg.ts\n\ninterface BaseResult {\n path: string;\n width: number;\n height: number;\n centerX: number;\n centerY: number;\n}\n\nexport function wrapPath(path: string, width: number, height: number): string {\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" width=\"${width}\" height=\"${height}\"><path d=\"${path}\" fill=\"currentColor\"/></svg>`;\n}\n\nexport function addSvgFields<T extends BaseResult>(result: T): T & { viewBox: string; svg: string } {\n const viewBox = `0 0 ${result.width} ${result.height}`;\n const svg = wrapPath(result.path, result.width, result.height);\n return { ...result, viewBox, svg };\n}\n","import type { BoomerangParams } from '../generators/curved/boomerang';\n\nexport const crescent: BoomerangParams = {\n style: 'crescent',\n armLength: 50,\n bendAngle: 160,\n thickness: 35,\n taper: 0.5,\n tipRoundness: 0.2,\n armCurvature: 0,\n bendSharpness: 0,\n};\n\nexport const fatMoon: BoomerangParams = {\n style: 'crescent',\n armLength: 45,\n bendAngle: 180,\n thickness: 50,\n taper: 0.3,\n tipRoundness: 0.6,\n armCurvature: 0,\n bendSharpness: 0,\n};\n\nexport const sharpChevron: BoomerangParams = {\n style: 'chevron',\n armLength: 55,\n bendAngle: 60,\n thickness: 40,\n taper: 1,\n tipRoundness: 0,\n armCurvature: 0,\n bendSharpness: 0,\n};\n\nexport const thinArc: BoomerangParams = {\n style: 'crescent',\n armLength: 60,\n bendAngle: 140,\n thickness: 20,\n taper: 0.7,\n tipRoundness: 0.1,\n armCurvature: 0,\n bendSharpness: 0,\n};\n\nexport const horseshoe: BoomerangParams = {\n style: 'horseshoe',\n armLength: 80,\n bendAngle: 50,\n thickness: 18,\n taper: 0.2,\n tipRoundness: 0.3,\n armCurvature: 0.4,\n bendSharpness: 0,\n};\n","import { GeneratorResult } from '../types';\nimport { addSvgFields } from '../utils/svg';\nimport * as presets from '../../presets/boomerang';\n\nexport type BoomerangStyle = 'classic' | 'crescent' | 'horseshoe' | 'chevron';\n\nexport interface BoomerangParams {\n // Style selection\n style?: BoomerangStyle; // 'classic' (outline V), 'crescent' (arc), 'horseshoe' (U), 'chevron' (solid V)\n\n // Core shape - interpreted based on style\n armLength: number; // Length of arms (classic/horseshoe) or arc radius (crescent)\n bendAngle: number; // Angle between arms (classic), arc span (crescent), arm spacing (horseshoe)\n armCurvature: number; // How curved: 0-1 (classic: arm bow, crescent: unused, horseshoe: bottom curve)\n bendSharpness: number; // Bend smoothness: 0-1\n\n // Thickness\n thickness: number; // Max thickness at widest point\n taper: number; // Tip thickness ratio: 0-1 (0 = pointed, 1 = uniform)\n tipRoundness: number; // How rounded the tips are: 0-1\n\n // Asymmetry (optional)\n armBalance?: number; // Ratio of arm1/arm2 length: 0.5-2 (default 1)\n thicknessBalance?: number; // Thickness bias: -1 to 1 (default 0)\n\n // Orientation\n rotation?: number; // Rotation in degrees (default 0)\n}\n\n/**\n * Boomerang function with preset methods attached.\n */\ninterface BoomerangFunction {\n (params: BoomerangParams): GeneratorResult;\n crescent: (overrides?: Partial<BoomerangParams>) => GeneratorResult;\n fatMoon: (overrides?: Partial<BoomerangParams>) => GeneratorResult;\n sharpChevron: (overrides?: Partial<BoomerangParams>) => GeneratorResult;\n thinArc: (overrides?: Partial<BoomerangParams>) => GeneratorResult;\n horseshoe: (overrides?: Partial<BoomerangParams>) => GeneratorResult;\n}\n\n/**\n * Unified boomerang generator with multiple geometry modes:\n * - 'classic': Two arms diverging from a central bend (V-shape, traditional boomerang)\n * - 'crescent': Single curved arc with thickness (moon-like, thick C-curve)\n * - 'horseshoe': Two parallel arms connected by curved bottom (U-shape)\n */\nfunction boomerangBase(params: BoomerangParams): GeneratorResult {\n const style = params.style || 'classic';\n\n switch (style) {\n case 'crescent':\n return generateCrescent(params);\n case 'horseshoe':\n return generateHorseshoe(params);\n case 'chevron':\n return generateChevron(params);\n case 'classic':\n default:\n return generateClassic(params);\n }\n}\n\nexport const boomerang: BoomerangFunction = Object.assign(boomerangBase, {\n crescent: (overrides?: Partial<BoomerangParams>) =>\n boomerangBase({ ...presets.crescent, ...overrides }),\n fatMoon: (overrides?: Partial<BoomerangParams>) =>\n boomerangBase({ ...presets.fatMoon, ...overrides }),\n sharpChevron: (overrides?: Partial<BoomerangParams>) =>\n boomerangBase({ ...presets.sharpChevron, ...overrides }),\n thinArc: (overrides?: Partial<BoomerangParams>) =>\n boomerangBase({ ...presets.thinArc, ...overrides }),\n horseshoe: (overrides?: Partial<BoomerangParams>) =>\n boomerangBase({ ...presets.horseshoe, ...overrides }),\n});\n\n// ============================================================================\n// CLASSIC STYLE - Two arms diverging from bend point (V-shape)\n// ============================================================================\n\nfunction generateClassic(params: BoomerangParams): GeneratorResult {\n const {\n armLength,\n bendAngle,\n armCurvature,\n bendSharpness,\n thickness,\n taper,\n tipRoundness,\n armBalance = 1,\n thicknessBalance = 0,\n rotation = 0,\n } = params;\n\n const clampedBendAngle = Math.max(30, Math.min(180, bendAngle));\n const clampedArmCurvature = Math.max(0, Math.min(1, armCurvature));\n const clampedBendSharpness = Math.max(0, Math.min(1, bendSharpness));\n const clampedTaper = Math.max(0, Math.min(1, taper));\n const clampedTipRoundness = Math.max(0, Math.min(1, tipRoundness));\n const clampedArmBalance = Math.max(0.5, Math.min(2, armBalance));\n const clampedThicknessBalance = Math.max(-1, Math.min(1, thicknessBalance));\n\n const arm1Length = armLength * (2 / (1 + clampedArmBalance));\n const arm2Length = armLength * (2 * clampedArmBalance / (1 + clampedArmBalance));\n\n const halfAngle = (clampedBendAngle / 2) * Math.PI / 180;\n\n const arm1Dir = { x: -Math.sin(halfAngle), y: -Math.cos(halfAngle) };\n const arm2Dir = { x: Math.sin(halfAngle), y: -Math.cos(halfAngle) };\n\n const tip1 = { x: arm1Dir.x * arm1Length, y: arm1Dir.y * arm1Length };\n const tip2 = { x: arm2Dir.x * arm2Length, y: arm2Dir.y * arm2Length };\n const bendPoint = { x: 0, y: 0 };\n\n const numSamples = 20;\n\n const arm1Spine = generateArmSpine(tip1, bendPoint, arm1Dir, arm1Length, clampedArmCurvature, numSamples);\n const arm2Spine = generateArmSpine(bendPoint, tip2, arm2Dir, arm2Length, clampedArmCurvature, numSamples);\n\n const minThickness = thickness * clampedTaper;\n\n function getThicknessAlongArm(t: number, isArm1: boolean): number {\n const tipFade = Math.sin(t * Math.PI / 2);\n const baseThickness = minThickness + (thickness - minThickness) * tipFade;\n const balanceFactor = isArm1\n ? 1 - clampedThicknessBalance * 0.3\n : 1 + clampedThicknessBalance * 0.3;\n return baseThickness * balanceFactor;\n }\n\n const arm1Outer: Point[] = [];\n const arm1Inner: Point[] = [];\n const arm2Outer: Point[] = [];\n const arm2Inner: Point[] = [];\n\n for (let i = 0; i < arm1Spine.length; i++) {\n const t = i / (arm1Spine.length - 1);\n const point = arm1Spine[i];\n const tangent = getSpineTangent(arm1Spine, i);\n const normal = { x: -tangent.y, y: tangent.x };\n const halfThick = getThicknessAlongArm(t, true) / 2;\n\n arm1Outer.push({ x: point.x + normal.x * halfThick, y: point.y + normal.y * halfThick });\n arm1Inner.push({ x: point.x - normal.x * halfThick, y: point.y - normal.y * halfThick });\n }\n\n for (let i = 0; i < arm2Spine.length; i++) {\n const t = 1 - i / (arm2Spine.length - 1);\n const point = arm2Spine[i];\n const tangent = getSpineTangent(arm2Spine, i);\n const normal = { x: -tangent.y, y: tangent.x };\n const halfThick = getThicknessAlongArm(t, false) / 2;\n\n arm2Outer.push({ x: point.x + normal.x * halfThick, y: point.y + normal.y * halfThick });\n arm2Inner.push({ x: point.x - normal.x * halfThick, y: point.y - normal.y * halfThick });\n }\n\n const pathParts: string[] = [];\n\n pathParts.push(`M ${arm1Outer[0].x.toFixed(2)},${arm1Outer[0].y.toFixed(2)}`);\n\n const tip1Curve = clampedTipRoundness * thickness * 0.3;\n pathParts.push(`Q ${(tip1.x + arm1Dir.x * tip1Curve).toFixed(2)},${(tip1.y + arm1Dir.y * tip1Curve).toFixed(2)} ${arm1Inner[0].x.toFixed(2)},${arm1Inner[0].y.toFixed(2)}`);\n\n pathParts.push(smoothCurveThroughPoints(arm1Inner));\n\n const bendInner2 = arm2Inner[0];\n\n if (clampedBendSharpness < 0.3) {\n pathParts.push(`L ${bendInner2.x.toFixed(2)},${bendInner2.y.toFixed(2)}`);\n } else {\n const bendInnerOffset = thickness * 0.2 * clampedBendSharpness;\n const bendInnerCtrl = { x: 0, y: bendInnerOffset };\n pathParts.push(`Q ${bendInnerCtrl.x.toFixed(2)},${bendInnerCtrl.y.toFixed(2)} ${bendInner2.x.toFixed(2)},${bendInner2.y.toFixed(2)}`);\n }\n\n pathParts.push(smoothCurveThroughPoints(arm2Inner));\n\n const tip2Curve = clampedTipRoundness * thickness * 0.3;\n pathParts.push(`Q ${(tip2.x + arm2Dir.x * tip2Curve).toFixed(2)},${(tip2.y + arm2Dir.y * tip2Curve).toFixed(2)} ${arm2Outer[arm2Outer.length - 1].x.toFixed(2)},${arm2Outer[arm2Outer.length - 1].y.toFixed(2)}`);\n\n const arm2OuterReversed = [...arm2Outer].reverse();\n pathParts.push(smoothCurveThroughPoints(arm2OuterReversed));\n\n const bendOuter1 = arm1Outer[arm1Outer.length - 1];\n\n if (clampedBendSharpness < 0.3) {\n pathParts.push(`L ${bendOuter1.x.toFixed(2)},${bendOuter1.y.toFixed(2)}`);\n } else {\n const bendOuterOffset = -thickness * 0.4 * clampedBendSharpness;\n const bendOuterCtrl = { x: 0, y: bendOuterOffset };\n pathParts.push(`Q ${bendOuterCtrl.x.toFixed(2)},${bendOuterCtrl.y.toFixed(2)} ${bendOuter1.x.toFixed(2)},${bendOuter1.y.toFixed(2)}`);\n }\n\n const arm1OuterReversed = [...arm1Outer].reverse();\n pathParts.push(smoothCurveThroughPoints(arm1OuterReversed));\n\n pathParts.push('Z');\n\n let path = pathParts.join(' ');\n\n const allPoints = [...arm1Outer, ...arm1Inner, ...arm2Outer, ...arm2Inner];\n let minX = Math.min(...allPoints.map(p => p.x));\n let maxX = Math.max(...allPoints.map(p => p.x));\n let minY = Math.min(...allPoints.map(p => p.y));\n let maxY = Math.max(...allPoints.map(p => p.y));\n\n const padding = thickness * 0.3 * clampedTipRoundness;\n minX -= padding;\n maxX += padding;\n minY -= padding;\n\n const width = maxX - minX;\n const height = maxY - minY;\n\n path = normalizePath(path, minX, minY);\n\n if (rotation !== 0) {\n path = rotatePath(path, rotation, width, height);\n }\n\n return addSvgFields({ path, width, height, centerX: width / 2, centerY: height / 2 });\n}\n\n// ============================================================================\n// CRESCENT STYLE - Single curved arc with thickness (moon-like shape)\n// ============================================================================\n\nfunction generateCrescent(params: BoomerangParams): GeneratorResult {\n const {\n armLength, // Used as arc radius\n bendAngle, // Used as arc span (degrees, 30-300)\n thickness,\n taper,\n tipRoundness,\n armBalance = 1, // Asymmetric arc thickness along length\n rotation = 0,\n } = params;\n\n const radius = Math.max(20, armLength);\n const arcSpan = Math.max(30, Math.min(300, bendAngle)) * Math.PI / 180;\n const clampedTaper = Math.max(0, Math.min(1, taper));\n const clampedTipRoundness = Math.max(0, Math.min(1, tipRoundness));\n const clampedArmBalance = Math.max(0.5, Math.min(2, armBalance));\n\n const numSamples = 30;\n const startAngle = -arcSpan / 2;\n const endAngle = arcSpan / 2;\n\n // Generate spine points along the arc\n const spine: Point[] = [];\n for (let i = 0; i <= numSamples; i++) {\n const t = i / numSamples;\n const angle = startAngle + (endAngle - startAngle) * t;\n spine.push({\n x: Math.sin(angle) * radius,\n y: -Math.cos(angle) * radius + radius, // Shift so bottom of arc is at y=0\n });\n }\n\n // Calculate thickness at each point\n const minThickness = thickness * clampedTaper;\n\n function getThicknessAtT(t: number): number {\n // Taper at both ends, thickest in middle\n // Apply balance (shift where thickness is max)\n const balanceShift = (t - 0.5) * (clampedArmBalance - 1) * 0.5;\n const adjustedT = Math.max(0, Math.min(1, t + balanceShift));\n const adjustedDist = Math.min(adjustedT, 1 - adjustedT) * 2;\n const adjustedFactor = Math.sin(adjustedDist * Math.PI / 2);\n\n return minThickness + (thickness - minThickness) * adjustedFactor;\n }\n\n // Build inner and outer edges\n const outer: Point[] = [];\n const inner: Point[] = [];\n\n for (let i = 0; i < spine.length; i++) {\n const t = i / (spine.length - 1);\n const point = spine[i];\n const tangent = getSpineTangent(spine, i);\n const normal = { x: -tangent.y, y: tangent.x };\n const halfThick = getThicknessAtT(t) / 2;\n\n outer.push({ x: point.x + normal.x * halfThick, y: point.y + normal.y * halfThick });\n inner.push({ x: point.x - normal.x * halfThick, y: point.y - normal.y * halfThick });\n }\n\n // Build path\n const pathParts: string[] = [];\n\n // Start at first outer point\n pathParts.push(`M ${outer[0].x.toFixed(2)},${outer[0].y.toFixed(2)}`);\n\n // Rounded start tip\n const startTipCurve = clampedTipRoundness * thickness * 0.4;\n const startTangent = getSpineTangent(spine, 0);\n pathParts.push(`Q ${(spine[0].x - startTangent.x * startTipCurve).toFixed(2)},${(spine[0].y - startTangent.y * startTipCurve).toFixed(2)} ${inner[0].x.toFixed(2)},${inner[0].y.toFixed(2)}`);\n\n // Inner edge (start to end)\n pathParts.push(smoothCurveThroughPoints(inner));\n\n // Rounded end tip\n const endTipCurve = clampedTipRoundness * thickness * 0.4;\n const endTangent = getSpineTangent(spine, spine.length - 1);\n pathParts.push(`Q ${(spine[spine.length - 1].x + endTangent.x * endTipCurve).toFixed(2)},${(spine[spine.length - 1].y + endTangent.y * endTipCurve).toFixed(2)} ${outer[outer.length - 1].x.toFixed(2)},${outer[outer.length - 1].y.toFixed(2)}`);\n\n // Outer edge (end back to start)\n const outerReversed = [...outer].reverse();\n pathParts.push(smoothCurveThroughPoints(outerReversed));\n\n pathParts.push('Z');\n\n let path = pathParts.join(' ');\n\n // Calculate bounds\n const allPoints = [...outer, ...inner];\n let minX = Math.min(...allPoints.map(p => p.x));\n let maxX = Math.max(...allPoints.map(p => p.x));\n let minY = Math.min(...allPoints.map(p => p.y));\n let maxY = Math.max(...allPoints.map(p => p.y));\n\n const padding = thickness * 0.3 * clampedTipRoundness;\n minX -= padding;\n maxX += padding;\n minY -= padding;\n maxY += padding;\n\n const width = maxX - minX;\n const height = maxY - minY;\n\n path = normalizePath(path, minX, minY);\n\n if (rotation !== 0) {\n path = rotatePath(path, rotation, width, height);\n }\n\n return addSvgFields({ path, width, height, centerX: width / 2, centerY: height / 2 });\n}\n\n// ============================================================================\n// HORSESHOE STYLE - Two parallel arms connected by curved bottom (U-shape)\n// ============================================================================\n\nfunction generateHorseshoe(params: BoomerangParams): GeneratorResult {\n const {\n armLength, // Length of the vertical arms\n bendAngle, // Spacing between arms (width at top)\n armCurvature, // How curved the bottom connection is\n thickness,\n taper,\n tipRoundness,\n armBalance = 1, // Asymmetric arm lengths\n rotation = 0,\n } = params;\n\n const spacing = Math.max(20, bendAngle);\n const clampedArmCurvature = Math.max(0, Math.min(1, armCurvature));\n const clampedTaper = Math.max(0, Math.min(1, taper));\n const clampedTipRoundness = Math.max(0, Math.min(1, tipRoundness));\n const clampedArmBalance = Math.max(0.5, Math.min(2, armBalance));\n\n const arm1Len = armLength * (2 / (1 + clampedArmBalance));\n const arm2Len = armLength * (2 * clampedArmBalance / (1 + clampedArmBalance));\n\n const halfSpacing = spacing / 2;\n const halfThick = thickness / 2;\n const tipThick = thickness * clampedTaper / 2;\n\n // Use explicit geometry for straight parallel arms\n // Left arm outer/inner x-coordinates\n const leftOuterX = -halfSpacing - halfThick;\n const leftInnerX = -halfSpacing + halfThick;\n // Right arm outer/inner x-coordinates\n const rightInnerX = halfSpacing - halfThick;\n const rightOuterX = halfSpacing + halfThick;\n\n // Arm y-coordinates (with taper at tips)\n const leftTopY = 0;\n const leftBottomY = arm1Len;\n const rightBottomY = arm2Len;\n const rightTopY = 0;\n\n // Bottom curve parameters\n const bottomY = Math.max(arm1Len, arm2Len);\n const curveDepth = halfSpacing * clampedArmCurvature;\n\n // Build path directly with explicit coordinates\n const pathParts: string[] = [];\n\n // Start at left arm outer top (with tip width adjustment)\n const leftTipOuterX = -halfSpacing - tipThick;\n const leftTipInnerX = -halfSpacing + tipThick;\n const rightTipInnerX = halfSpacing - tipThick;\n const rightTipOuterX = halfSpacing + tipThick;\n\n pathParts.push(`M ${leftTipOuterX.toFixed(2)},${leftTopY.toFixed(2)}`);\n\n // Rounded left tip\n if (clampedTipRoundness > 0) {\n const tipCurve = clampedTipRoundness * thickness * 0.3;\n pathParts.push(`Q ${(-halfSpacing).toFixed(2)},${(leftTopY - tipCurve).toFixed(2)} ${leftTipInnerX.toFixed(2)},${leftTopY.toFixed(2)}`);\n } else {\n pathParts.push(`L ${leftTipInnerX.toFixed(2)},${leftTopY.toFixed(2)}`);\n }\n\n // Inner left arm - straight down\n pathParts.push(`L ${leftInnerX.toFixed(2)},${leftBottomY.toFixed(2)}`);\n\n // Inner bottom curve (from left to right)\n if (clampedArmCurvature > 0.1) {\n // Curved bottom using quadratic bezier\n const innerCtrlY = bottomY + curveDepth;\n pathParts.push(`Q ${0},${innerCtrlY.toFixed(2)} ${rightInnerX.toFixed(2)},${rightBottomY.toFixed(2)}`);\n } else {\n // Flat bottom\n pathParts.push(`L ${rightInnerX.toFixed(2)},${rightBottomY.toFixed(2)}`);\n }\n\n // Inner right arm - straight up\n pathParts.push(`L ${rightTipInnerX.toFixed(2)},${rightTopY.toFixed(2)}`);\n\n // Rounded right tip\n if (clampedTipRoundness > 0) {\n const tipCurve = clampedTipRoundness * thickness * 0.3;\n pathParts.push(`Q ${(halfSpacing).toFixed(2)},${(rightTopY - tipCurve).toFixed(2)} ${rightTipOuterX.toFixed(2)},${rightTopY.toFixed(2)}`);\n } else {\n pathParts.push(`L ${rightTipOuterX.toFixed(2)},${rightTopY.toFixed(2)}`);\n }\n\n // Outer right arm - straight down\n pathParts.push(`L ${rightOuterX.toFixed(2)},${rightBottomY.toFixed(2)}`);\n\n // Outer bottom curve (from right to left)\n if (clampedArmCurvature > 0.1) {\n const outerCtrlY = bottomY + curveDepth + thickness;\n pathParts.push(`Q ${0},${outerCtrlY.toFixed(2)} ${leftOuterX.toFixed(2)},${leftBottomY.toFixed(2)}`);\n } else {\n pathParts.push(`L ${leftOuterX.toFixed(2)},${leftBottomY.toFixed(2)}`);\n }\n\n // Outer left arm - straight up back to start\n pathParts.push(`L ${leftTipOuterX.toFixed(2)},${leftTopY.toFixed(2)}`);\n\n pathParts.push('Z');\n\n let path = pathParts.join(' ');\n\n // Calculate bounds from explicit geometry\n const padding = thickness * 0.3;\n let minX = leftOuterX - padding;\n let maxX = rightOuterX + padding;\n let minY = -padding - (clampedTipRoundness * thickness * 0.3);\n let maxY = bottomY + curveDepth + thickness + padding;\n\n const width = maxX - minX;\n const height = maxY - minY;\n\n path = normalizePath(path, minX, minY);\n\n if (rotation !== 0) {\n path = rotatePath(path, rotation, width, height);\n }\n\n return addSvgFields({ path, width, height, centerX: width / 2, centerY: height / 2 });\n}\n\n// ============================================================================\n// CHEVRON STYLE - Solid V-shape with inner cutout (like < or > arrows)\n// ============================================================================\n\nfunction generateChevron(params: BoomerangParams): GeneratorResult {\n const {\n armLength, // Length of the arms\n bendAngle, // Angle of the V (smaller = sharper point)\n thickness, // Controls arm width (proportional)\n taper = 0, // 0 = V with cutout, 1 = solid triangle (no cutout)\n tipRoundness = 0, // Roundness at the tip\n armBalance = 1, // Asymmetric arm lengths\n rotation = 0,\n } = params;\n\n const clampedBendAngle = Math.max(20, Math.min(160, bendAngle));\n const clampedTaper = Math.max(0, Math.min(1, taper));\n const clampedTipRoundness = Math.max(0, Math.min(1, tipRoundness));\n const clampedArmBalance = Math.max(0.5, Math.min(2, armBalance));\n\n // Arm width based on thickness, with minimum for visibility\n const armWidth = Math.max(armLength * 0.15, thickness * 0.5);\n\n // Cutout depth: taper controls this. High taper = no cutout (solid triangle)\n // taper=0: full cutout based on armLength\n // taper=1: no cutout (solid triangle)\n const cutoutDepth = armLength * 0.6 * (1 - clampedTaper);\n\n // Calculate arm lengths\n const arm1Len = armLength * (2 / (1 + clampedArmBalance));\n const arm2Len = armLength * (2 * clampedArmBalance / (1 + clampedArmBalance));\n\n const halfAngle = (clampedBendAngle / 2) * Math.PI / 180;\n\n // Outer points (tip and arm ends)\n const tip = { x: 0, y: 0 };\n const arm1End = { x: -Math.sin(halfAngle) * arm1Len, y: -Math.cos(halfAngle) * arm1Len };\n const arm2End = { x: Math.sin(halfAngle) * arm2Len, y: -Math.cos(halfAngle) * arm2Len };\n\n // Perpendicular directions for arm widths\n const arm1Perp = { x: -Math.cos(halfAngle), y: Math.sin(halfAngle) };\n const arm2Perp = { x: Math.cos(halfAngle), y: Math.sin(halfAngle) };\n\n // Outer corners at arm ends\n const arm1OuterCorner = {\n x: arm1End.x + arm1Perp.x * armWidth / 2,\n y: arm1End.y + arm1Perp.y * armWidth / 2\n };\n const arm1InnerCorner = {\n x: arm1End.x - arm1Perp.x * armWidth / 2,\n y: arm1End.y - arm1Perp.y * armWidth / 2\n };\n const arm2OuterCorner = {\n x: arm2End.x + arm2Perp.x * armWidth / 2,\n y: arm2End.y + arm2Perp.y * armWidth / 2\n };\n const arm2InnerCorner = {\n x: arm2End.x - arm2Perp.x * armWidth / 2,\n y: arm2End.y - arm2Perp.y * armWidth / 2\n };\n\n // Inner cutout point\n const innerTip = {\n x: 0,\n y: -cutoutDepth\n };\n\n // Build path\n const pathParts: string[] = [];\n\n // Start at outer tip\n if (clampedTipRoundness > 0) {\n const roundAmount = clampedTipRoundness * armWidth * 0.3;\n const tipStart = {\n x: tip.x + arm1Perp.x * roundAmount,\n y: tip.y + arm1Perp.y * roundAmount - roundAmount * 0.5\n };\n pathParts.push(`M ${tipStart.x.toFixed(2)},${tipStart.y.toFixed(2)}`);\n const tipEnd = {\n x: tip.x + arm2Perp.x * roundAmount,\n y: tip.y + arm2Perp.y * roundAmount - roundAmount * 0.5\n };\n pathParts.push(`Q ${tip.x.toFixed(2)},${tip.y.toFixed(2)} ${tipEnd.x.toFixed(2)},${tipEnd.y.toFixed(2)}`);\n } else {\n pathParts.push(`M ${tip.x.toFixed(2)},${tip.y.toFixed(2)}`);\n }\n\n // Outer edge to arm2 end\n pathParts.push(`L ${arm2OuterCorner.x.toFixed(2)},${arm2OuterCorner.y.toFixed(2)}`);\n\n // Top of arm2\n pathParts.push(`L ${arm2InnerCorner.x.toFixed(2)},${arm2InnerCorner.y.toFixed(2)}`);\n\n // Inner edge back to center (the cutout) - only if taper < 0.9\n if (cutoutDepth > 5 && clampedTaper < 0.9) {\n pathParts.push(`L ${innerTip.x.toFixed(2)},${innerTip.y.toFixed(2)}`);\n }\n\n // Inner edge to arm1\n pathParts.push(`L ${arm1InnerCorner.x.toFixed(2)},${arm1InnerCorner.y.toFixed(2)}`);\n\n // Top of arm1\n pathParts.push(`L ${arm1OuterCorner.x.toFixed(2)},${arm1OuterCorner.y.toFixed(2)}`);\n\n // Close back to tip\n pathParts.push('Z');\n\n let path = pathParts.join(' ');\n\n // Calculate bounds\n const allPoints = [tip, arm1End, arm2End, arm1OuterCorner, arm1InnerCorner, arm2OuterCorner, arm2InnerCorner];\n if (cutoutDepth > 5 && clampedTaper < 0.9) {\n allPoints.push(innerTip);\n }\n let minX = Math.min(...allPoints.map(p => p.x));\n let maxX = Math.max(...allPoints.map(p => p.x));\n let minY = Math.min(...allPoints.map(p => p.y));\n let maxY = Math.max(...allPoints.map(p => p.y));\n\n const padding = armWidth * 0.2;\n minX -= padding;\n maxX += padding;\n minY -= padding;\n maxY += padding;\n\n const width = maxX - minX;\n const height = maxY - minY;\n\n path = normalizePath(path, minX, minY);\n\n if (rotation !== 0) {\n path = rotatePath(path, rotation, width, height);\n }\n\n return addSvgFields({ path, width, height, centerX: width / 2, centerY: height / 2 });\n}\n\n// ============================================================================\n// Helper types and functions\n// ============================================================================\n\ninterface Point {\n x: number;\n y: number;\n}\n\nfunction generateArmSpine(\n start: Point,\n end: Point,\n direction: Point,\n length: number,\n curvature: number,\n numSamples: number\n): Point[] {\n const points: Point[] = [];\n const perpDir = { x: direction.y, y: -direction.x };\n const bowAmount = length * 0.4 * curvature;\n const midPoint = { x: (start.x + end.x) / 2, y: (start.y + end.y) / 2 };\n const controlPoint = {\n x: midPoint.x + perpDir.x * bowAmount,\n y: midPoint.y + perpDir.y * bowAmount\n };\n\n for (let i = 0; i <= numSamples; i++) {\n const t = i / numSamples;\n if (curvature < 0.1) {\n points.push({\n x: start.x + (end.x - start.x) * t,\n y: start.y + (end.y - start.y) * t,\n });\n } else {\n const mt = 1 - t;\n points.push({\n x: mt * mt * start.x + 2 * mt * t * controlPoint.x + t * t * end.x,\n y: mt * mt * start.y + 2 * mt * t * controlPoint.y + t * t * end.y,\n });\n }\n }\n\n return points;\n}\n\nfunction getSpineTangent(spine: Point[], index: number): Point {\n const prev = spine[Math.max(0, index - 1)];\n const next = spine[Math.min(spine.length - 1, index + 1)];\n const dx = next.x - prev.x;\n const dy = next.y - prev.y;\n const len = Math.sqrt(dx * dx + dy * dy);\n return len > 0 ? { x: dx / len, y: dy / len } : { x: 1, y: 0 };\n}\n\nfunction smoothCurveThroughPoints(points: Point[]): string {\n if (points.length < 2) return '';\n\n const parts: string[] = [];\n const tension = 0.3;\n\n for (let i = 0; i < points.length - 1; i++) {\n const p0 = points[Math.max(0, i - 1)];\n const p1 = points[i];\n const p2 = points[i + 1];\n const p3 = points[Math.min(points.length - 1, i + 2)];\n\n const cp1x = p1.x + (p2.x - p0.x) * tension;\n const cp1y = p1.y + (p2.y - p0.y) * tension;\n const cp2x = p2.x - (p3.x - p1.x) * tension;\n const cp2y = p2.y - (p3.y - p1.y) * tension;\n\n parts.push(`C ${cp1x.toFixed(2)},${cp1y.toFixed(2)} ${cp2x.toFixed(2)},${cp2y.toFixed(2)} ${p2.x.toFixed(2)},${p2.y.toFixed(2)}`);\n }\n\n return parts.join(' ');\n}\n\nfunction normalizePath(path: string, minX: number, minY: number): string {\n return path.replace(\n /([-\\d.]+),([-\\d.]+)/g,\n (_, x, y) => `${(parseFloat(x) - minX).toFixed(2)},${(parseFloat(y) - minY).toFixed(2)}`\n );\n}\n\nfunction rotatePath(path: string, rotation: number, width: number, height: number): string {\n const rad = (rotation * Math.PI) / 180;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n const cx = width / 2;\n const cy = height / 2;\n\n return path.replace(\n /([-\\d.]+),([-\\d.]+)/g,\n (_, xStr, yStr) => {\n const x = parseFloat(xStr) - cx;\n const y = parseFloat(yStr) - cy;\n const rx = x * cos - y * sin + cx;\n const ry = x * sin + y * cos + cy;\n return `${rx.toFixed(2)},${ry.toFixed(2)}`;\n }\n );\n}\n"],"mappings":"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","names":[]}