{
  "openapi": "3.1.1",
  "info": {
    "title": "Proofline API",
    "version": "1.0.0",
    "summary": "Deterministic tools for people and AI agents.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://proofline.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/tools": {
      "get": {
        "operationId": "listTools",
        "summary": "Catalog of all tools",
        "responses": {
          "200": {
            "description": "Tool list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/{id}": {
      "get": {
        "operationId": "getTool",
        "summary": "Definition of one tool",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "math-workbench",
                "equation-solver-steps",
                "graphing-calculator",
                "matrix-linear-algebra-lab",
                "number-theory-lab",
                "probability-statistics-studio",
                "graph-algorithm-visualizer",
                "big-o-crossover-calculator",
                "erasure-coding-playground",
                "floating-point-explorer",
                "equation-art-studio",
                "regex-golf-arena",
                "keyboard-heatmap-visualizer"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/math-workbench/calculate": {
      "post": {
        "operationId": "calculateMathWorkbench",
        "summary": "Simplify, factor, differentiate, integrate, solve, take limits, series and plots in one box.",
        "description": "A small computer algebra system: type commands such as \"integrate x*e^x from 0 to 1\", \"derivative sin(x)^2\", \"solve x^2 - 5x + 6 = 0\", \"limit sin(x)/x as x -> 0\" or \"series cos(x) at 0 order 6\". Results are exact (fractions, roots, π) where possible, and the tool says clearly when it falls back to a numeric answer.\n\nMethodology:\n- Input is tokenised and parsed with a Pratt parser that understands implicit multiplication (2x, 3(x+1), x sin x), powers of functions (sin^2(x)), |x| and the usual functions; log means the natural logarithm, log10/log2 are explicit.\n- All numbers are exact fractions (BigInt rationals); expressions are kept in a canonical form (like terms collected, powers merged, exact values of roots and special angles).\n- Derivatives use the sum, product, power and chain rules. Integrals use a table of standard forms, linearity, substitution, integration by parts, partial fractions and the e^(ax)·sin(bx) formula; every antiderivative is verified by differentiating it numerically at several points.\n- Definite integrals use F(b) − F(a) when an antiderivative exists and the integrand has no singularity inside the interval, cross-checked by adaptive Simpson (or tanh–sinh quadrature for endpoint singularities and infinite ranges); otherwise the numeric value is shown and labelled as such.\n- Limits try direct substitution, then L’Hôpital’s rule on 0/0 and ∞/∞ quotients, degree comparison at infinity, and finally numeric one-sided evaluation with extrapolation (marked as numeric).\n- Equations: linear, quadratic, rational, radical and higher polynomial equations (rational root theorem, then Durand–Kerner for the rest); systems of linear equations by exact Gaussian elimination.\n\nA compact computer algebra system, not a full replacement for Mathematica or SymPy: some simplifications (e.g. most trigonometric identities) are not applied, and numeric fallbacks are approximations.",
        "tags": [
          "math"
        ],
        "x-mcp-tool": "math_workbench",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MathWorkbenchInput"
              },
              "examples": {
                "example1": {
                  "summary": "Definite integral by parts",
                  "value": {
                    "query": "integrate x*e^x from 0 to 1"
                  }
                },
                "example2": {
                  "summary": "Second derivative",
                  "value": {
                    "query": "d^2/dx^2 sin(x)^2"
                  }
                },
                "example3": {
                  "summary": "Solve a quadratic",
                  "value": {
                    "query": "solve 2x^2 + 3x - 4 = 0"
                  }
                },
                "example4": {
                  "summary": "Classic limit",
                  "value": {
                    "query": "limit (1 - cos(x))/x^2 as x -> 0"
                  }
                },
                "example5": {
                  "summary": "Taylor series",
                  "value": {
                    "query": "series ln(1+x) at 0 order 5"
                  }
                },
                "example6": {
                  "summary": "Factor a polynomial",
                  "value": {
                    "query": "factor x^4 - 5x^2 + 4"
                  }
                },
                "example7": {
                  "summary": "Plot two functions",
                  "value": {
                    "query": "plot sin(x), x - x^3/6 from -4 to 4"
                  }
                },
                "example8": {
                  "summary": "Integral without elementary antiderivative",
                  "value": {
                    "query": "integrate e^(-x^2) from 0 to 2"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MathWorkbenchResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/equation-solver-steps/calculate": {
      "post": {
        "operationId": "calculateEquationSolverSteps",
        "summary": "Solve linear, quadratic, rational and radical equations or linear systems with every step shown.",
        "description": "Shows the full working for linear and quadratic equations (factoring, completing the square or the quadratic formula), rational equations with domain restrictions, radical equations, higher polynomials and systems of 2–6 linear equations solved by Gaussian elimination with exact fractions. Every answer is checked by substitution and extraneous roots are flagged.\n\nMethodology:\n- Everything is moved to one side and simplified with exact fractions. The equation type is detected: polynomial (by degree), rational (variable in a denominator), radical (variable under a root), single occurrence of the variable (isolated with inverse operations), otherwise numeric.\n- Quadratics: factoring when the discriminant is a perfect square, completing the square or the quadratic formula on request; complex solutions are shown when the discriminant is negative.\n- Higher polynomials: the rational root theorem finds all rational roots exactly; a remaining quadratic is solved exactly, larger remainders numerically with the Durand–Kerner method.\n- Rational equations: the denominators are factored, values that make them zero are excluded, both sides are multiplied by the least common denominator, and candidates in the excluded set are rejected as extraneous.\n- Radical equations: the radical is isolated and both sides raised to the root’s power (repeated for a second radical); each candidate is substituted into the original equation and rejected if it fails.\n- Linear systems: Gauss–Jordan elimination on the augmented matrix with exact fractions, showing every row operation; inconsistent and dependent systems are recognised.",
        "tags": [
          "math"
        ],
        "x-mcp-tool": "equation_solver_steps",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EquationSolverStepsInput"
              },
              "examples": {
                "example1": {
                  "summary": "Quadratic by completing the square",
                  "value": {
                    "equations": "x^2 + 6x + 5 = 0",
                    "method": "square"
                  }
                },
                "example2": {
                  "summary": "Quadratic formula with surds",
                  "value": {
                    "equations": "2x^2 + 3x - 4 = 0",
                    "method": "formula"
                  }
                },
                "example3": {
                  "summary": "Rational equation with an excluded value",
                  "value": {
                    "equations": "x/(x-2) + 1/(x+2) = 8/(x^2-4)"
                  }
                },
                "example4": {
                  "summary": "Radical equation with an extraneous root",
                  "value": {
                    "equations": "sqrt(x + 3) = x - 3"
                  }
                },
                "example5": {
                  "summary": "Linear system with 3 unknowns",
                  "value": {
                    "equations": "x + y + z = 6\n2y + 5z = -4\n2x + 5y - z = 27"
                  }
                },
                "example6": {
                  "summary": "Cubic equation",
                  "value": {
                    "equations": "x^3 - 2x^2 - 5x + 6 = 0"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EquationSolverStepsResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/graphing-calculator/calculate": {
      "post": {
        "operationId": "calculateGraphingCalculator",
        "summary": "Plot up to 6 functions or parametric curves with roots, extrema, intersections and SVG/PNG export.",
        "description": "Graphs y = f(x) for up to six functions (or parametric curves x(t), y(t)) over the range you choose, lists the roots, local minima and maxima and the intersection points numerically, prints a table of values and offers the graph as SVG and PNG downloads.\n\nMethodology:\n- Each function is parsed by the shared CAS core and evaluated in double precision at 600 points; jumps across vertical asymptotes are broken instead of joined, and extreme values are clipped unless you set y min/max.\n- Roots: sign changes on a 4,000-point grid refined by bisection, plus touching roots (local minima of |f| that reach zero). Poles are excluded because |f| must be tiny at a root.\n- Extrema: the derivative is computed symbolically and its roots are found the same way; each critical point is classified by comparing neighbouring values (inflection points are skipped).\n- Intersections: roots of f_i − f_j for every pair of functions. All of these are numeric approximations (about 10 significant digits) and only cover the plotted range.\n- The graph is an accessible SVG (title, description, data table); the PNG is rasterised from the same SVG with ImageMagick.",
        "tags": [
          "math"
        ],
        "x-mcp-tool": "graphing_calculator",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GraphingCalculatorInput"
              },
              "examples": {
                "example1": {
                  "summary": "Sine and a parabola",
                  "value": {
                    "functions": "y = sin(x)\ny = x^2/4 - 1",
                    "xMin": -5,
                    "xMax": 5
                  }
                },
                "example2": {
                  "summary": "Cubic with roots and extrema",
                  "value": {
                    "functions": "x^3 - 3x",
                    "xMin": -3,
                    "xMax": 3,
                    "tableStep": 0.5
                  }
                },
                "example3": {
                  "summary": "Parametric circle and Lissajous curve",
                  "value": {
                    "mode": "parametric",
                    "functions": "cos(t), sin(t)\nsin(3t), cos(2t)",
                    "tMin": 0,
                    "tMax": 6.283185307179586,
                    "png": false
                  }
                },
                "example4": {
                  "summary": "Rational function with asymptotes",
                  "value": {
                    "functions": "1/(x - 1)\nx/2",
                    "xMin": -4,
                    "xMax": 4,
                    "yMin": -6,
                    "yMax": 6,
                    "png": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GraphingCalculatorResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/matrix-linear-algebra-lab/calculate": {
      "post": {
        "operationId": "calculateMatrixLinearAlgebraLab",
        "summary": "Exact-fraction RREF with steps, determinant, inverse, null space, eigenvalues, LU/QR and Ax = b.",
        "description": "Enter matrices with whole numbers, fractions or decimals and get exact results: row reduction with every row operation, determinant, inverse, rank, null space, A + B, A·B and solutions of A x = b. Eigenvalues are exact for 2×2/3×3 cases with rational or quadratic roots and numeric (shifted QR algorithm) otherwise; LU, QR and the condition number are computed numerically.\n\nMethodology:\n- Entries are parsed as exact fractions (BigInt numerators and denominators), so row reduction, determinants, inverses, ranks, null spaces and solutions of A x = b are exact, with no rounding.\n- Row reduction is Gauss–Jordan elimination: swap to a non-zero pivot, scale the pivot row to 1, clear the column above and below; every operation is listed with the matrix after it.\n- Eigenvalues: the characteristic polynomial is computed exactly (Faddeev–LeVerrier). Rational roots and a remaining quadratic give exact eigenvalues (with surds or complex values); otherwise the matrix is reduced to Hessenberg form and the shifted QR algorithm finds the eigenvalues numerically. Eigenvectors are exact null spaces for rational eigenvalues and numeric (inverse iteration) otherwise.\n- LU uses partial pivoting (P·A = L·U); QR uses Householder reflections; the condition number is σmax/σmin from the singular values (Jacobi eigenvalues of AᵀA). These are double-precision numeric results.",
        "tags": [
          "math"
        ],
        "x-mcp-tool": "matrix_linear_algebra_lab",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MatrixLinearAlgebraLabInput"
              },
              "examples": {
                "example1": {
                  "summary": "Overview of a 3×3 matrix",
                  "value": {
                    "operation": "analyze",
                    "matrixA": "2 0 0\n0 3 4\n0 4 9"
                  }
                },
                "example2": {
                  "summary": "Solve A x = b with steps",
                  "value": {
                    "operation": "solve",
                    "matrixA": "2 1 -1\n-3 -1 2\n-2 1 2",
                    "vectorB": "8 -11 -3"
                  }
                },
                "example3": {
                  "summary": "Inverse with fractions",
                  "value": {
                    "operation": "inverse",
                    "matrixA": "1 2 3\n0 1 4\n5 6 0"
                  }
                },
                "example4": {
                  "summary": "Eigenvalues of a 2×2 matrix",
                  "value": {
                    "operation": "eigen",
                    "matrixA": "2 1\n1 3"
                  }
                },
                "example5": {
                  "summary": "Null space of a rank-deficient matrix",
                  "value": {
                    "operation": "nullspace",
                    "matrixA": "1 2 3\n2 4 6\n1 1 1"
                  }
                },
                "example6": {
                  "summary": "Product A·B",
                  "value": {
                    "operation": "multiply",
                    "matrixA": "1 2\n3 4",
                    "matrixB": "0 1\n1 0"
                  }
                },
                "example7": {
                  "summary": "QR decomposition",
                  "value": {
                    "operation": "qr",
                    "matrixA": "12 -51 4\n6 167 -68\n-4 24 -41"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatrixLinearAlgebraLabResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/number-theory-lab/calculate": {
      "post": {
        "operationId": "calculateNumberTheoryLab",
        "summary": "Primality, factorisation, gcd, modular arithmetic, CRT, φ, π(n), Collatz, continued fractions.",
        "description": "Big-integer number theory with the working shown: Miller–Rabin primality (deterministic up to 3.3·10^24, otherwise with a stated number of rounds), factorisation by trial division and Pollard rho, gcd/lcm with the extended Euclidean table, modular inverse and exponentiation, the Chinese remainder theorem, Euler φ and divisors, prime counting up to 10 million, Collatz sequences and continued fractions.\n\nMethodology:\n- Primality: trial division by primes below 100, then Miller–Rabin. Below 3,317,044,064,679,887,385,961,981 the first 13 primes as bases form a proof (Sorenson & Webster 2015), which covers every 64-bit number. Above it, the stated number of rounds uses bases derived from SHA-256 of n (reproducible); a composite passes each round with probability at most 1/4.\n- Factorisation: trial division up to 10,000, then Pollard–Brent rho with a fixed iteration budget; factors are checked with Miller–Rabin. If the budget runs out the remaining cofactor is reported as unfactored, never guessed.\n- φ(n) = ∏ p^(e−1)(p − 1), σ(n) = ∏ (p^(e+1) − 1)/(p − 1), d(n) = ∏ (e + 1). Carmichael numbers are detected with Korselt's criterion (square-free, composite, p − 1 | n − 1 for every prime factor).\n- gcd via the Euclidean algorithm with Bézout coefficients; inverse exists iff gcd(a, m) = 1. CRT merges congruences pairwise and also handles non-coprime moduli (or reports that none exists). π(n) uses an odd-only sieve of Eratosthenes.",
        "tags": [
          "math"
        ],
        "x-mcp-tool": "number_theory_lab",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NumberTheoryLabInput"
              },
              "examples": {
                "example1": {
                  "summary": "561, the smallest Carmichael number",
                  "value": {
                    "operation": "analyze",
                    "a": "561"
                  }
                },
                "example2": {
                  "summary": "Factor 2^64 + 1",
                  "value": {
                    "operation": "analyze",
                    "a": "2^64+1"
                  }
                },
                "example3": {
                  "summary": "Extended Euclid of 240 and 46",
                  "value": {
                    "operation": "gcd",
                    "a": "240",
                    "b": "46"
                  }
                },
                "example4": {
                  "summary": "CRT: x ≡ 2 (3), 3 (5), 2 (7)",
                  "value": {
                    "operation": "crt",
                    "congruences": "2 3\n3 5\n2 7"
                  }
                },
                "example5": {
                  "summary": "π(10^6)",
                  "value": {
                    "operation": "primecount",
                    "a": "1000000"
                  }
                },
                "example6": {
                  "summary": "Continued fraction of √7",
                  "value": {
                    "operation": "cf",
                    "a": "7"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NumberTheoryLabResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/probability-statistics-studio/calculate": {
      "post": {
        "operationId": "calculateProbabilityStatisticsStudio",
        "summary": "Distributions, descriptive stats, confidence intervals and t, chi-square and z tests with p-values.",
        "description": "Probabilities, densities and quantiles for the normal, t, chi-square, F, binomial, Poisson, exponential and uniform distributions with plots; descriptive statistics of a data set; confidence intervals for a mean or a proportion; and one-sample, two-sample and paired t-tests, chi-square goodness-of-fit and independence tests and z-tests for proportions, each with a p-value and a plain-language interpretation.\n\nMethodology:\n- Special functions are implemented directly: log-gamma (Lanczos), the regularised incomplete gamma function (series and continued fraction) and the regularised incomplete beta function (continued fraction). The normal CDF uses erfc via the incomplete gamma function; its quantile uses Acklam’s approximation refined by Halley steps.\n- CDFs: t and F via the incomplete beta function, chi-square and Poisson via the incomplete gamma function, binomial via the incomplete beta function. Quantiles of continuous distributions are found by bisection with a Newton polish; discrete quantiles are the smallest k with P(X ≤ k) ≥ p.\n- Values are checked in the test suite against published tables (e.g. Φ(1.96) = 0.975002, t₀.₉₇₅ with 10 df = 2.228139, χ²₀.₉₅ with 5 df = 11.0705, F₀.₉₅(5, 10) = 3.3258).\n- Descriptive statistics use the sample (n − 1) variance, quartiles by linear interpolation (the R/Excel default), the adjusted skewness and excess kurtosis, and the 1.5 × IQR outlier rule.\n- Tests: one-sample, Welch or pooled two-sample and paired t-tests; chi-square goodness-of-fit and independence (without continuity correction); one- and two-proportion z-tests (pooled for the test, unpooled for the interval). The interpretation compares p with α = 1 − confidence.\n\nA p-value is not the probability that H0 is true, and “not significant” does not prove H0. Check the assumptions listed with each test.",
        "tags": [
          "math"
        ],
        "x-mcp-tool": "probability_statistics_studio",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProbabilityStatisticsStudioInput"
              },
              "examples": {
                "example1": {
                  "summary": "Normal: P(Z ≤ 1.96) and the 97.5% quantile",
                  "value": {
                    "analysis": "distribution",
                    "distribution": "normal",
                    "param1": 0,
                    "param2": 1,
                    "x": 1.96,
                    "probability": 0.975
                  }
                },
                "example2": {
                  "summary": "Binomial: exactly / at most 5 heads in 10 flips",
                  "value": {
                    "analysis": "distribution",
                    "distribution": "binomial",
                    "param1": 10,
                    "param2": 0.5,
                    "x": 5,
                    "x2": 7
                  }
                },
                "example3": {
                  "summary": "Descriptive statistics",
                  "value": {
                    "analysis": "describe",
                    "data": "12, 15, 11, 18, 14, 15, 22, 13, 16, 15, 40"
                  }
                },
                "example4": {
                  "summary": "One-sample t-test",
                  "value": {
                    "analysis": "t-one",
                    "data": "5.1 4.9 5.6 5.8 6.0 5.3 5.5 5.7",
                    "mu0": 5
                  }
                },
                "example5": {
                  "summary": "Welch two-sample t-test",
                  "value": {
                    "analysis": "t-two",
                    "data": "20.1 22.3 19.8 21.5 23.0 20.7",
                    "data2": "18.2 19.5 17.9 18.8 20.1 19.0 18.4"
                  }
                },
                "example6": {
                  "summary": "Chi-square test of independence",
                  "value": {
                    "analysis": "chisq-indep",
                    "data": "30 10\n20 40"
                  }
                },
                "example7": {
                  "summary": "Confidence interval for a proportion",
                  "value": {
                    "analysis": "ci-proportion",
                    "successes": 42,
                    "trials": 120,
                    "confidence": 0.95
                  }
                },
                "example8": {
                  "summary": "Two-proportion z-test",
                  "value": {
                    "analysis": "z-two-prop",
                    "successes": 45,
                    "trials": 100,
                    "successes2": 30,
                    "trials2": 100
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProbabilityStatisticsStudioResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/graph-algorithm-visualizer/calculate": {
      "post": {
        "operationId": "calculateGraphAlgorithmVisualizer",
        "summary": "BFS, DFS, Dijkstra, Bellman–Ford, A*, MST, topological sort and SCCs on your edge list.",
        "description": "Paste an edge list (weighted or not, directed or not) and run a classic graph algorithm: BFS, DFS, Dijkstra, Bellman–Ford (with negative-cycle detection), A* with node coordinates, Prim or Kruskal minimum spanning tree, Kahn topological sort or Tarjan strongly connected components. Shows every step, the distances and the highlighted path or tree.\n\nMethodology:\n- Neighbours are visited in the order nodes first appear in your edge list, so every run is deterministic. Undirected edges are usable in both directions.\n- BFS finds fewest-edge paths; DFS records discovery and finish times. Dijkstra settles nodes in order of distance with a binary heap and refuses negative weights; Bellman–Ford relaxes all edges up to n − 1 times and then checks for a negative cycle.\n- A* is Dijkstra ordered by g + h with h = straight-line distance between coordinates. It returns optimal paths when h never overestimates (admissible) and is consistent; the tool warns when an edge is shorter than its straight-line length.\n- Prim grows a tree from the start node (a forest if the graph is disconnected); Kruskal adds the cheapest edges that do not close a cycle (union–find). Kahn's algorithm outputs nodes without remaining incoming edges and detects cycles; Tarjan's algorithm finds strongly connected components in one DFS.",
        "tags": [
          "math"
        ],
        "x-mcp-tool": "graph_algorithm_visualizer",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GraphAlgorithmVisualizerInput"
              },
              "examples": {
                "example1": {
                  "summary": "Dijkstra from A to F",
                  "value": {
                    "algorithm": "dijkstra",
                    "source": "A",
                    "target": "F"
                  }
                },
                "example2": {
                  "summary": "Kruskal MST",
                  "value": {
                    "algorithm": "kruskal"
                  }
                },
                "example3": {
                  "summary": "Topological sort of build steps",
                  "value": {
                    "directed": true,
                    "algorithm": "topo",
                    "edges": "fetch compile\ncompile test\ncompile package\ntest release\npackage release\nlint release"
                  }
                },
                "example4": {
                  "summary": "Bellman–Ford with a negative edge",
                  "value": {
                    "directed": true,
                    "algorithm": "bellman-ford",
                    "source": "S",
                    "target": "D",
                    "edges": "S A 4\nS B 5\nA C -3\nB C 2\nC D 2\nB D 6"
                  }
                },
                "example5": {
                  "summary": "A* on a grid",
                  "value": {
                    "algorithm": "astar",
                    "source": "S",
                    "target": "G",
                    "edges": "S A 1\nA B 1\nB G 1\nS C 1.5\nC D 1.5\nD G 1.5\nA C 1",
                    "coordinates": "S 0 0\nA 1 0\nB 2 0\nG 3 0\nC 0.5 1\nD 2 1"
                  }
                },
                "example6": {
                  "summary": "Strongly connected components",
                  "value": {
                    "directed": true,
                    "algorithm": "scc",
                    "edges": "1 2\n2 3\n3 1\n3 4\n4 5\n5 6\n6 4\n7 6\n7 8\n8 7"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GraphAlgorithmVisualizerResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/big-o-crossover-calculator/calculate": {
      "post": {
        "operationId": "calculateBigOCrossoverCalculator",
        "summary": "When does c₁·n log n beat c₂·n²? Crossover points, log-log chart and run times.",
        "description": "Compares cost functions such as 50·n log n against 2·n² or 2ⁿ with your constant factors, finds every input size where one overtakes another, draws them on a log-log chart, and converts operation counts into running time at a given number of operations per second.\n\nMethodology:\n- Each cost is c·f(n) with log₂ for logarithms; n! is evaluated as Γ(n + 1), so every function is continuous in n. All comparisons are done on log10 of the cost, so 2ⁿ or n! for large n never overflow.\n- Crossovers: the difference of the log costs is sampled at 2,000 log-spaced sizes between the smallest and largest n; every sign change is refined by 80 bisection steps. Crossovers closer together than the grid spacing can be missed.\n- Time = cost ÷ operations per second. Real programs also depend on memory access, caches and constant overheads that a single constant c only approximates.",
        "tags": [
          "math"
        ],
        "x-mcp-tool": "big_o_crossover_calculator",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BigOCrossoverCalculatorInput"
              },
              "examples": {
                "example1": {
                  "summary": "Merge sort vs insertion sort",
                  "value": {
                    "functions": [
                      {
                        "label": "Merge sort",
                        "complexity": "nlogn",
                        "constant": 6
                      },
                      {
                        "label": "Insertion sort",
                        "complexity": "n2",
                        "constant": 0.5
                      }
                    ]
                  }
                },
                "example2": {
                  "summary": "Brute force 2ⁿ vs n³ dynamic programming",
                  "value": {
                    "functions": [
                      {
                        "label": "Brute force",
                        "complexity": "2n",
                        "constant": 1
                      },
                      {
                        "label": "DP",
                        "complexity": "n3",
                        "constant": 100
                      },
                      {
                        "label": "Fancy n^2.37",
                        "complexity": "nk",
                        "constant": 1000000,
                        "exponent": 2.373
                      }
                    ],
                    "nMax": 100000,
                    "sizes": [
                      "10",
                      "20",
                      "30",
                      "50",
                      "100",
                      "1000"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BigOCrossoverCalculatorResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/erasure-coding-playground/calculate": {
      "post": {
        "operationId": "calculateErasureCodingPlayground",
        "summary": "Reed–Solomon over GF(256): encode data into k + m shards, lose some, rebuild it.",
        "description": "Splits your text or bytes into k data shards, adds m Reed–Solomon parity shards computed over GF(256), lets you drop any shards and reconstructs the original from any k survivors. Shows the generator and decoding matrices, the shard bytes in hex, and compares storage overhead and fault tolerance with replication and RAID-5 style XOR parity.\n\nMethodology:\n- Arithmetic is in the finite field GF(2^8) with the primitive polynomial x^8 + x^4 + x^3 + x^2 + 1 (0x11d): addition is XOR, multiplication uses log/antilog tables of the generator 2.\n- The data is split into k equal shards (zero-padded at the end). The n × k generator matrix is the k × k identity (so data shards are stored as is: a systematic code) on top of an m × k Cauchy matrix C[i][j] = 1 / (x_i + y_j) with x_i = k + i and y_j = j.\n- Every k × k submatrix of this generator is invertible, so any k of the n = k + m shards are enough (the code is MDS). Reconstruction inverts the rows of the surviving shards by Gauss–Jordan elimination over GF(256) and multiplies the survivors by that inverse.\n- RAID-5 style parity is the XOR of all data shards: it survives exactly one lost shard. Replication keeps m + 1 full copies, survives m losses, but costs (m + 1)× storage.",
        "tags": [
          "math"
        ],
        "x-mcp-tool": "erasure_coding_playground",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ErasureCodingPlaygroundInput"
              },
              "examples": {
                "example1": {
                  "summary": "RS(4,2): lose two data shards",
                  "value": {
                    "data": "Hello, erasure coding!",
                    "encoding": "text",
                    "k": 4,
                    "m": 2,
                    "lost": "D1, D3"
                  }
                },
                "example2": {
                  "summary": "RS(6,3) like many object stores, three shards lost",
                  "value": {
                    "data": "The quick brown fox jumps over the lazy dog",
                    "encoding": "text",
                    "k": 6,
                    "m": 3,
                    "lost": "D2, P1, D6"
                  }
                },
                "example3": {
                  "summary": "Too many losses (3 of RS(3,2))",
                  "value": {
                    "data": "00 01 02 03 04 05 06 07 08",
                    "encoding": "hex",
                    "k": 3,
                    "m": 2,
                    "lost": "1 2 4"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErasureCodingPlaygroundResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/floating-point-explorer/calculate": {
      "post": {
        "operationId": "calculateFloatingPointExplorer",
        "summary": "See how IEEE-754 half/single/double store a number: bits, exact value, ULP, rounding error.",
        "description": "Shows the sign, exponent and fraction bits of a decimal number in IEEE-754 binary16, binary32 or binary64, the exact decimal value that is actually stored (computed with big integers), the rounding error, the ULP and the neighbouring representable numbers. Evaluates expressions such as 0.1 + 0.2 step by step and explains subnormals, infinities and NaN.\n\nMethodology:\n- Decimal input is parsed as an exact fraction and rounded to the nearest representable value of the chosen format (round half to even), with big-integer arithmetic, so there is no double rounding via JavaScript numbers.\n- A normal number is (−1)^sign × 1.fraction × 2^(exponent − bias); subnormals (exponent field 0) are (−1)^sign × 0.fraction × 2^(1 − bias). The exact decimal of the stored value always terminates because the denominator is a power of two.\n- ULP is the gap to the next representable number away from zero; the neighbours are the bit patterns ±1 (crossing between ±0 and the smallest subnormals).\n- Expressions are evaluated twice: exactly with fractions, and in the chosen format with rounding after every literal and every operation (IEEE-754 semantics, like JavaScript for binary64 or C float for binary32).",
        "tags": [
          "math"
        ],
        "x-mcp-tool": "floating_point_explorer",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FloatingPointExplorerInput"
              },
              "examples": {
                "example1": {
                  "summary": "0.1 as a double",
                  "value": {
                    "value": "0.1",
                    "format": "binary64"
                  }
                },
                "example2": {
                  "summary": "0.1 + 0.2 ≠ 0.3",
                  "value": {
                    "value": "0.1 + 0.2",
                    "format": "binary64"
                  }
                },
                "example3": {
                  "summary": "Smallest half-precision subnormal",
                  "value": {
                    "value": "0x0001",
                    "format": "binary16"
                  }
                },
                "example4": {
                  "summary": "16777217 as a float",
                  "value": {
                    "value": "16777217",
                    "format": "binary32"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FloatingPointExplorerResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/equation-art-studio/calculate": {
      "post": {
        "operationId": "calculateEquationArtStudio",
        "summary": "Turn math into art: parametric, polar, Lissajous, rose and spirograph curves.",
        "description": "Type x(t) and y(t), or r(θ), or start from a preset (Lissajous, rose, spirograph, butterfly, heart), add rotational symmetry and a colour palette, and get a crisp SVG artwork plus a PNG download. Expressions are parsed safely (no code execution) and support + − × ÷ ^, sin, cos, tan, sqrt, abs, exp, log, pi and e.\n\nMethodology:\n- Expressions are tokenised and parsed by a small recursive-descent parser into a syntax tree, which is compiled into plain arithmetic closures — no eval or Function, and only the listed functions, constants and variables are accepted.\n- Polar curves are converted with x = r(θ)·cos θ, y = r(θ)·sin θ. Presets: Lissajous x = sin(a·t + d), y = sin(b·t); rose r = cos(a/b·θ); spirograph (hypotrochoid) x = (a−b)cos t + c·cos((a−b)/b·t), y = (a−b)sin t − c·sin((a−b)/b·t); Temple Fay’s butterfly; the classic 16 sin³t heart. Roses and spirographs with whole-number a, b run exactly one full period: for a rose with a/b = p/q in lowest terms that is π·q when p·q is odd and 2π·q otherwise (7/3 closes at 3π); for a spirograph 2π·b/gcd(a, b).\n- t is sampled evenly from start to end. Undefined samples (division by zero, sqrt of a negative number) leave gaps, and very large jumps (asymptotes) are not connected.\n- The drawing is fitted into a 600 × 600 square with equal x/y scale, optionally rotated into k symmetric copies, and coloured along t with a gradient from the palette. Points closer than 0.3 px are dropped to keep the SVG small.\n- The SVG uses only plain shapes (no scripts or styles). The PNG is rendered from the same SVG with ImageMagick when it is installed; both downloads stay available for about 2 hours.",
        "tags": [
          "fun"
        ],
        "x-mcp-tool": "equation_art_studio",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EquationArtStudioInput"
              },
              "examples": {
                "example1": {
                  "summary": "Spirograph, sunset palette",
                  "value": {
                    "curve": "spirograph",
                    "a": 7,
                    "b": 4,
                    "c": 3,
                    "samples": 2000,
                    "symmetry": 1,
                    "palette": "sunset",
                    "strokeWidth": 2
                  }
                },
                "example2": {
                  "summary": "Rose with 3-fold symmetry",
                  "value": {
                    "curve": "rose",
                    "a": 7,
                    "b": 3,
                    "samples": 1500,
                    "symmetry": 3,
                    "palette": "ocean",
                    "strokeWidth": 1.5,
                    "png": false
                  }
                },
                "example3": {
                  "summary": "Own parametric curve",
                  "value": {
                    "curve": "parametric",
                    "xExpr": "cos(t) + cos(6t)/2 + sin(14t)/3",
                    "yExpr": "sin(t) + sin(6t)/2 + cos(14t)/3",
                    "tMin": "0",
                    "tMax": "2*pi",
                    "samples": 2500,
                    "symmetry": 1,
                    "palette": "neon",
                    "strokeWidth": 2,
                    "png": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EquationArtStudioResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/regex-golf-arena/calculate": {
      "post": {
        "operationId": "calculateRegexGolfArena",
        "summary": "Match the left list, avoid the right list — in as few characters as possible.",
        "description": "Regex golf with built-in puzzles: write one JavaScript regular expression that matches every string on the “match” list and none on the “don’t match” list. Shorter is better; perfect solutions can join a per-puzzle top-20 leaderboard. Use “dry run” to test without submitting.\n\nMethodology:\n- Your pattern is compiled with JavaScript’s RegExp (flags i/u optional) and tested against every string with RegExp.test, so it may match anywhere in the string unless you anchor it.\n- Score = 10 × (strings on the match list that match + strings on the don’t-match list that do not match) − regex length, as in classic regex golf. A solution is perfect when every string is classified correctly.\n- Safety: patterns are limited to 200 characters, control characters are refused, and patterns where an unbounded quantifier repeats a group that contains another variable quantifier or an alternation — the classic catastrophic-backtracking shapes such as (a+)+ or (a|aa)* — are rejected before running. The puzzle strings are short (at most 12 characters), which bounds the remaining work.\n- Leaderboard: only perfect, non-dry-run solutions are entered, ranked by length, then date. Each puzzle keeps the top 20; an identical regex only counts once, and each nickname keeps its best entry. Only nickname, length, score and date are shown — never the regex — so nobody gets spoilers.",
        "tags": [
          "fun"
        ],
        "x-mcp-tool": "regex_golf_arena",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegexGolfArenaInput"
              },
              "examples": {
                "example1": {
                  "summary": "Warm-up, dry run",
                  "value": {
                    "puzzle": "warm-up",
                    "regex": "cat",
                    "flags": "none",
                    "dryRun": true
                  }
                },
                "example2": {
                  "summary": "Seeing double, almost right",
                  "value": {
                    "puzzle": "doubles",
                    "regex": "(ll|ff|tt|mm|pp|rr)",
                    "flags": "none",
                    "dryRun": true
                  }
                },
                "example3": {
                  "summary": "Show the ABBA puzzle",
                  "value": {
                    "puzzle": "abba",
                    "dryRun": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegexGolfArenaResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/keyboard-heatmap-visualizer/calculate": {
      "post": {
        "operationId": "calculateKeyboardHeatmapVisualizer",
        "summary": "Paste any text: see which keys and fingers do the work on QWERTY, Dvorak, Colemak & co.",
        "description": "Paste text and see a key-frequency heatmap on a QWERTY, QWERTZ, AZERTY, Dvorak or Colemak keyboard, plus finger and hand load, row usage, same-finger bigrams and hand alternation — and a table comparing how the same text would feel on each layout.\n\nMethodology:\n- Every character is looked up on the layout (unshifted, Shift or AltGr level). Characters not on the layout are decomposed when possible (é → e) and counted as approximated; the rest (e.g. emoji) are counted as unmapped and skipped. Line breaks and tabs are skipped.\n- Fingers follow standard touch typing on a row-staggered keyboard: left pinky for 1/Q/A/Z (and the ISO key left of Z), ring for 2/W/S/X, middle for 3/E/D/C, index for 4–5/R–T/F–G/V–B; mirrored on the right, with the right pinky also covering the keys beyond P/;//. The space bar counts for the thumbs.\n- Same-finger bigram = two consecutive characters typed with the same finger on different keys (a key repeated, like “ll”, is not counted). Hand alternation = share of consecutive characters typed by different hands. Both exclude spaces, and a space resets the sequence.\n- Home-row share is calculated without spaces. Shift and AltGr presses are counted as extra key presses but not attributed to a finger.\n- The heatmap colour uses the square root of the count so that rarer keys stay visible.\n\nA simplified model of typing effort: real comfort also depends on rolls, lateral stretches, keyboard geometry and habits.",
        "tags": [
          "fun"
        ],
        "x-mcp-tool": "keyboard_heatmap_visualizer",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KeyboardHeatmapVisualizerInput"
              },
              "examples": {
                "example1": {
                  "summary": "English pangrams on QWERTY vs the rest",
                  "value": {
                    "text": "The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs! How vexingly quick daft zebras jump; sphinx of black quartz, judge my vow.",
                    "layout": "qwerty",
                    "compare": [
                      "qwerty",
                      "dvorak",
                      "colemak"
                    ]
                  }
                },
                "example2": {
                  "summary": "German text on QWERTZ",
                  "value": {
                    "text": "Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.",
                    "layout": "qwertz",
                    "compare": [
                      "qwertz",
                      "qwerty",
                      "colemak"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyboardHeatmapVisualizerResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/workflows": {
      "get": {
        "operationId": "listWorkflows",
        "summary": "Multi-tool workflows",
        "responses": {
          "200": {
            "description": "Workflow list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "MathWorkbenchInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "query": {
            "title": "Command",
            "description": "Commands: simplify, expand, factor, derivative (or d/dx), integrate [from a to b], solve, limit … as x -> a, evaluate … at x = 2, series … at a order n, plot f, g from a to b. Use * or juxtaposition for products (2x), ^ for powers, sqrt(), ln(), log10(), sin(), e, pi.",
            "type": "string",
            "maxLength": 2000
          }
        },
        "required": [
          "query"
        ]
      },
      "MathWorkbenchResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "command",
              "input",
              "variable",
              "result",
              "latex",
              "numeric",
              "symbolic",
              "method",
              "steps",
              "items",
              "notes"
            ],
            "properties": {
              "command": {
                "type": "string",
                "enum": [
                  "simplify",
                  "expand",
                  "factor",
                  "derivative",
                  "integrate",
                  "solve",
                  "limit",
                  "evaluate",
                  "series",
                  "plot"
                ]
              },
              "input": {
                "type": "string",
                "description": "The parsed input in canonical plain-text form."
              },
              "variable": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "result": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Main result as plain text (null when nothing could be computed)."
              },
              "latex": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Main result as LaTeX."
              },
              "numeric": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Decimal value when the result is a single real number."
              },
              "symbolic": {
                "type": "boolean",
                "description": "True when the result is exact/symbolic, false for numeric approximations."
              },
              "method": {
                "type": "string"
              },
              "steps": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "label",
                    "text",
                    "latex",
                    "numeric"
                  ],
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "text": {
                      "type": "string"
                    },
                    "latex": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "numeric": {
                      "type": [
                        "number",
                        "null"
                      ]
                    }
                  }
                }
              },
              "notes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "EquationSolverStepsInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "equations": {
            "title": "Equation(s)",
            "description": "One equation per line. Several lines form a linear system (e.g. \"2x + y = 5\" and \"x - y = 1\").",
            "type": "string",
            "maxLength": 2000
          },
          "variable": {
            "title": "Solve for",
            "description": "Optional. Defaults to x (or the only variable). For systems: a comma-separated list of unknowns.",
            "type": "string",
            "maxLength": 60
          },
          "method": {
            "title": "Method for quadratics",
            "type": "string",
            "enum": [
              "auto",
              "factoring",
              "square",
              "formula"
            ],
            "default": "auto"
          },
          "searchMin": {
            "title": "Numeric search from",
            "description": "Only used when no symbolic method applies (e.g. cos(x) = x).",
            "type": "number",
            "default": -100
          },
          "searchMax": {
            "title": "Numeric search to",
            "type": "number",
            "default": 100
          }
        },
        "required": [
          "equations"
        ]
      },
      "EquationSolverStepsResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "type",
              "equation",
              "variables",
              "kind",
              "method",
              "status",
              "solutions",
              "extraneous",
              "excluded",
              "verification",
              "steps",
              "matrixSteps",
              "notes"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "single",
                  "system"
                ]
              },
              "equation": {
                "type": "string"
              },
              "variables": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "kind": {
                "type": "string"
              },
              "method": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "enum": [
                  "solved",
                  "no-solution",
                  "identity",
                  "infinite"
                ]
              },
              "solutions": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "variable",
                    "value",
                    "latex",
                    "exact",
                    "real",
                    "imaginary"
                  ],
                  "properties": {
                    "variable": {
                      "type": "string"
                    },
                    "value": {
                      "type": "string"
                    },
                    "latex": {
                      "type": "string"
                    },
                    "exact": {
                      "type": "boolean"
                    },
                    "real": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "imaginary": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "Imaginary part for complex solutions, otherwise null."
                    }
                  }
                }
              },
              "extraneous": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "value",
                    "reason"
                  ],
                  "properties": {
                    "value": {
                      "type": "string"
                    },
                    "reason": {
                      "type": "string"
                    }
                  }
                }
              },
              "excluded": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "verification": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "solution",
                    "lhs",
                    "rhs",
                    "ok"
                  ],
                  "properties": {
                    "solution": {
                      "type": "string"
                    },
                    "lhs": {
                      "type": "string"
                    },
                    "rhs": {
                      "type": "string"
                    },
                    "ok": {
                      "type": "boolean"
                    }
                  }
                }
              },
              "steps": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "matrixSteps": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "operation",
                    "matrix"
                  ],
                  "properties": {
                    "operation": {
                      "type": "string"
                    },
                    "matrix": {
                      "type": "string"
                    }
                  }
                }
              },
              "notes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "GraphingCalculatorInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "mode": {
            "title": "Graph type",
            "type": "string",
            "enum": [
              "functions",
              "parametric"
            ],
            "default": "functions"
          },
          "functions": {
            "title": "Functions (one per line)",
            "description": "Functions: \"y = x^2 - 2\" or just \"x^2 - 2\". Parametric: \"cos(t), sin(t)\" per line. Up to 6 lines.",
            "type": "string",
            "maxLength": 3000
          },
          "xMin": {
            "title": "x min",
            "type": "number",
            "default": -10
          },
          "xMax": {
            "title": "x max",
            "type": "number",
            "default": 10
          },
          "yMin": {
            "title": "y min",
            "description": "Optional; automatic (asymptotes are clipped) when empty.",
            "type": "number"
          },
          "yMax": {
            "title": "y max",
            "description": "Optional.",
            "type": "number"
          },
          "tMin": {
            "title": "t min (parametric)",
            "type": "number",
            "default": 0
          },
          "tMax": {
            "title": "t max (parametric)",
            "description": "Default 2π.",
            "type": "number",
            "default": 6.283185307179586
          },
          "tableStep": {
            "title": "Table step",
            "description": "Optional step for the table of values (default: a tenth of the range; at most 41 rows).",
            "type": "number",
            "minimum": 0
          },
          "analyze": {
            "title": "Find roots, extrema and intersections",
            "type": "boolean",
            "default": true
          },
          "png": {
            "title": "Also create a PNG download",
            "type": "boolean",
            "default": true
          }
        },
        "required": [
          "functions"
        ]
      },
      "GraphingCalculatorResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "mode",
              "domain",
              "curves",
              "intersections",
              "table",
              "svg",
              "png"
            ],
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "functions",
                  "parametric"
                ]
              },
              "domain": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "min",
                  "max",
                  "variable"
                ],
                "properties": {
                  "min": {
                    "type": "number"
                  },
                  "max": {
                    "type": "number"
                  },
                  "variable": {
                    "type": "string"
                  }
                }
              },
              "curves": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "index",
                    "input",
                    "expression",
                    "latex",
                    "derivative",
                    "roots",
                    "extrema",
                    "yIntercept"
                  ],
                  "properties": {
                    "index": {
                      "type": "integer"
                    },
                    "input": {
                      "type": "string"
                    },
                    "expression": {
                      "type": "string"
                    },
                    "latex": {
                      "type": "string"
                    },
                    "derivative": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "roots": {
                      "type": "array",
                      "items": {
                        "type": "number"
                      }
                    },
                    "extrema": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "x",
                          "y",
                          "kind"
                        ],
                        "properties": {
                          "x": {
                            "type": "number"
                          },
                          "y": {
                            "type": "number"
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "minimum",
                              "maximum"
                            ]
                          }
                        }
                      }
                    },
                    "yIntercept": {
                      "type": [
                        "number",
                        "null"
                      ]
                    }
                  }
                }
              },
              "intersections": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "a",
                    "b",
                    "x",
                    "y"
                  ],
                  "properties": {
                    "a": {
                      "type": "integer"
                    },
                    "b": {
                      "type": "integer"
                    },
                    "x": {
                      "type": "number"
                    },
                    "y": {
                      "type": "number"
                    }
                  }
                }
              },
              "table": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "columns",
                  "rows"
                ],
                "properties": {
                  "columns": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "rows": {
                    "type": "array",
                    "items": {
                      "type": "array",
                      "items": {
                        "type": [
                          "number",
                          "null"
                        ]
                      }
                    }
                  }
                }
              },
              "svg": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              },
              "png": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "MatrixLinearAlgebraLabInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "operation": {
            "title": "Operation",
            "type": "string",
            "enum": [
              "analyze",
              "rref",
              "determinant",
              "inverse",
              "rank",
              "nullspace",
              "transpose",
              "add",
              "subtract",
              "multiply",
              "solve",
              "lu",
              "qr",
              "eigen",
              "condition"
            ],
            "default": "analyze"
          },
          "matrixA": {
            "title": "Matrix A",
            "description": "One row per line (or rows separated by ;), entries separated by spaces or commas. Fractions like 1/3 and decimals are fine. Up to 10×10.",
            "type": "string",
            "maxLength": 4000
          },
          "matrixB": {
            "title": "Matrix B",
            "description": "Only for A + B, A − B and A · B.",
            "type": "string",
            "maxLength": 4000
          },
          "vectorB": {
            "title": "Right-hand side b",
            "description": "Only for \"Solve A x = b\": one number per row of A.",
            "type": "string",
            "maxLength": 1000
          }
        },
        "required": [
          "matrixA"
        ]
      },
      "MatrixLinearAlgebraLabResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "operation",
              "size",
              "exact",
              "matrix",
              "scalar",
              "scalarNumeric",
              "vectors",
              "factors",
              "eigen",
              "properties",
              "steps",
              "notes"
            ],
            "properties": {
              "operation": {
                "type": "string",
                "enum": [
                  "analyze",
                  "rref",
                  "determinant",
                  "inverse",
                  "rank",
                  "nullspace",
                  "transpose",
                  "add",
                  "subtract",
                  "multiply",
                  "solve",
                  "lu",
                  "qr",
                  "eigen",
                  "condition"
                ]
              },
              "size": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "rows",
                  "cols"
                ],
                "properties": {
                  "rows": {
                    "type": "integer"
                  },
                  "cols": {
                    "type": "integer"
                  }
                }
              },
              "exact": {
                "type": "boolean",
                "description": "True when every number is an exact fraction."
              },
              "matrix": {
                "type": [
                  "array",
                  "null"
                ],
                "items": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "description": "Resulting matrix (entries as exact fractions or decimals)."
              },
              "scalar": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "scalarNumeric": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "vectors": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "description": "Null-space basis or solution vectors."
              },
              "factors": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "name",
                    "matrix"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "matrix": {
                      "type": "array",
                      "items": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              },
              "eigen": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "value",
                    "real",
                    "imaginary",
                    "multiplicity",
                    "exact",
                    "vectors"
                  ],
                  "properties": {
                    "value": {
                      "type": "string"
                    },
                    "real": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "imaginary": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "multiplicity": {
                      "type": "integer"
                    },
                    "exact": {
                      "type": "boolean"
                    },
                    "vectors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              },
              "properties": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "name",
                    "value"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "value": {
                      "type": "string"
                    }
                  }
                }
              },
              "steps": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "operation",
                    "matrix"
                  ],
                  "properties": {
                    "operation": {
                      "type": "string"
                    },
                    "matrix": {
                      "type": "string"
                    }
                  }
                }
              },
              "notes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "NumberTheoryLabInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "operation": {
            "title": "Operation",
            "type": "string",
            "enum": [
              "analyze",
              "gcd",
              "modpow",
              "modinv",
              "crt",
              "primecount",
              "collatz",
              "cf"
            ],
            "default": "analyze"
          },
          "a": {
            "title": "n or a",
            "description": "Integer: decimal, 0x hex, 0b binary, or a power such as 2^127-1.",
            "type": "string",
            "maxLength": 1300,
            "default": "561"
          },
          "b": {
            "title": "b (second number / exponent / denominator)",
            "type": "string",
            "maxLength": 1300
          },
          "m": {
            "title": "Modulus m",
            "type": "string",
            "maxLength": 1300
          },
          "congruences": {
            "title": "Congruences (one per line: remainder modulus)",
            "description": "For the CRT: each line \"a m\" means x ≡ a (mod m). Moduli need not be coprime.",
            "type": "string",
            "maxLength": 4000
          },
          "rounds": {
            "title": "Miller–Rabin rounds above 3.3·10^24",
            "description": "Error probability at most 4^−rounds for numbers beyond the deterministic range.",
            "type": "integer",
            "minimum": 1,
            "maximum": 64,
            "default": 40
          }
        },
        "required": []
      },
      "NumberTheoryLabResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "required": [
              "operation",
              "answer"
            ],
            "properties": {
              "operation": {
                "type": "string"
              },
              "answer": {
                "type": "string",
                "description": "Main result as text (big integers as decimal strings)."
              },
              "n": {
                "type": "string"
              },
              "isPrime": {
                "type": "boolean"
              },
              "primalityMethod": {
                "type": "string"
              },
              "errorBound": {
                "type": "number"
              },
              "basesTested": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "factors": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "p",
                    "e"
                  ],
                  "properties": {
                    "p": {
                      "type": "string"
                    },
                    "e": {
                      "type": "integer"
                    }
                  }
                }
              },
              "factorisationComplete": {
                "type": "boolean"
              },
              "phi": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "divisorCount": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "divisorSum": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "divisors": {
                "type": [
                  "array",
                  "null"
                ],
                "items": {
                  "type": "string"
                }
              },
              "carmichael": {
                "type": "boolean"
              },
              "gcd": {
                "type": "string"
              },
              "lcm": {
                "type": "string"
              },
              "bezout": {
                "type": "object",
                "properties": {
                  "x": {
                    "type": "string"
                  },
                  "y": {
                    "type": "string"
                  }
                }
              },
              "value": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "modulus": {
                "type": "string"
              },
              "count": {
                "type": "integer"
              },
              "steps": {
                "type": "integer"
              },
              "peak": {
                "type": "string"
              },
              "terms": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "period": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "convergents": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "ProbabilityStatisticsStudioInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "analysis": {
            "title": "Analysis",
            "type": "string",
            "enum": [
              "distribution",
              "describe",
              "ci-mean",
              "ci-proportion",
              "t-one",
              "t-two",
              "t-paired",
              "chisq-gof",
              "chisq-indep",
              "z-one-prop",
              "z-two-prop"
            ],
            "default": "distribution"
          },
          "distribution": {
            "title": "Distribution",
            "type": "string",
            "enum": [
              "normal",
              "t",
              "chisq",
              "f",
              "binomial",
              "poisson",
              "exponential",
              "uniform"
            ],
            "default": "normal"
          },
          "param1": {
            "title": "Parameter 1",
            "description": "Defaults: normal μ = 0, t df = 10, chi-square df = 1, F d1 = 5, binomial n = 10, Poisson λ = 1, exponential λ = 1, uniform a = 0.",
            "type": "number"
          },
          "param2": {
            "title": "Parameter 2",
            "description": "Defaults: normal σ = 1, F d2 = 10, binomial p = 0.5, uniform b = 1.",
            "type": "number"
          },
          "x": {
            "title": "Value x",
            "description": "Distribution: compute pdf/pmf and P(X ≤ x).",
            "type": "number"
          },
          "x2": {
            "title": "Second value x₂",
            "description": "Optional: also compute P(x ≤ X ≤ x₂).",
            "type": "number"
          },
          "probability": {
            "title": "Probability p (for a quantile)",
            "description": "Distribution: the x with P(X ≤ x) = p (e.g. 0.975).",
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "data": {
            "title": "Data / sample 1 / observed counts / table",
            "description": "Numbers separated by spaces, commas or new lines. For the independence test: one row of counts per line.",
            "type": "string",
            "maxLength": 200000
          },
          "data2": {
            "title": "Sample 2 / expected counts",
            "description": "Two-sample and paired tests: the second sample. Goodness of fit: expected counts or proportions (optional; equal by default).",
            "type": "string",
            "maxLength": 200000
          },
          "mu0": {
            "title": "Hypothesised mean μ0",
            "type": "number",
            "default": 0
          },
          "sigma": {
            "title": "Known population SD σ",
            "description": "Optional, for a z interval for the mean.",
            "type": "number",
            "minimum": 0
          },
          "successes": {
            "title": "Successes x (group 1)",
            "type": "integer",
            "minimum": 0
          },
          "trials": {
            "title": "Trials n (group 1)",
            "type": "integer",
            "minimum": 1
          },
          "successes2": {
            "title": "Successes x (group 2)",
            "type": "integer",
            "minimum": 0
          },
          "trials2": {
            "title": "Trials n (group 2)",
            "type": "integer",
            "minimum": 1
          },
          "p0": {
            "title": "Hypothesised proportion p0",
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "default": 0.5
          },
          "confidence": {
            "title": "Confidence level",
            "description": "Also sets α = 1 − confidence for the tests.",
            "type": "number",
            "minimum": 0.5,
            "maximum": 0.9999,
            "default": 0.95
          },
          "alternative": {
            "title": "Alternative hypothesis",
            "type": "string",
            "enum": [
              "two-sided",
              "less",
              "greater"
            ],
            "default": "two-sided"
          },
          "equalVariances": {
            "title": "Assume equal variances (pooled two-sample t-test)",
            "type": "boolean",
            "default": false
          }
        },
        "required": []
      },
      "ProbabilityStatisticsStudioResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "analysis",
              "distribution",
              "descriptive",
              "interval",
              "test",
              "warnings"
            ],
            "properties": {
              "analysis": {
                "type": "string",
                "enum": [
                  "distribution",
                  "describe",
                  "ci-mean",
                  "ci-proportion",
                  "t-one",
                  "t-two",
                  "t-paired",
                  "chisq-gof",
                  "chisq-indep",
                  "z-one-prop",
                  "z-two-prop"
                ]
              },
              "distribution": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "label": {
                    "type": "string"
                  },
                  "discrete": {
                    "type": "boolean"
                  },
                  "mean": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "variance": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "sd": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "pdfAtX": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "cdfAtX": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "survivalAtX": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "P(X > x)"
                  },
                  "between": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "P(x ≤ X ≤ x₂)"
                  },
                  "quantile": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "x": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "x2": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "probability": {
                    "type": [
                      "number",
                      "null"
                    ]
                  }
                }
              },
              "descriptive": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "properties": {
                  "n": {
                    "type": "integer"
                  },
                  "mean": {
                    "type": "number"
                  },
                  "median": {
                    "type": "number"
                  },
                  "modes": {
                    "type": "array",
                    "items": {
                      "type": "number"
                    }
                  },
                  "sd": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "variance": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "min": {
                    "type": "number"
                  },
                  "max": {
                    "type": "number"
                  },
                  "q1": {
                    "type": "number"
                  },
                  "q3": {
                    "type": "number"
                  },
                  "iqr": {
                    "type": "number"
                  },
                  "se": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "skewness": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "kurtosis": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "sum": {
                    "type": "number"
                  },
                  "outliers": {
                    "type": "array",
                    "items": {
                      "type": "number"
                    }
                  }
                }
              },
              "interval": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "properties": {
                  "method": {
                    "type": "string"
                  },
                  "confidence": {
                    "type": "number"
                  },
                  "estimate": {
                    "type": "number"
                  },
                  "lower": {
                    "type": "number"
                  },
                  "upper": {
                    "type": "number"
                  },
                  "margin": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "alternatives": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "method": {
                          "type": "string"
                        },
                        "lower": {
                          "type": "number"
                        },
                        "upper": {
                          "type": "number"
                        }
                      }
                    }
                  }
                }
              },
              "test": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "h0": {
                    "type": "string"
                  },
                  "h1": {
                    "type": "string"
                  },
                  "statistic": {
                    "type": "number"
                  },
                  "statisticName": {
                    "type": "string"
                  },
                  "df": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "pValue": {
                    "type": "number"
                  },
                  "alpha": {
                    "type": "number"
                  },
                  "reject": {
                    "type": "boolean"
                  },
                  "estimate": {
                    "type": "number"
                  },
                  "ciLower": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "ciUpper": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "effectName": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "effectSize": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "interpretation": {
                    "type": "string"
                  },
                  "details": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "value": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              },
              "warnings": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "GraphAlgorithmVisualizerInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "edges": {
            "title": "Edges (one per line: from to [weight])",
            "description": "Formats: \"A B 4\", \"A -> B 4\", \"A,B,4\". A line with one name adds an isolated node. # starts a comment. Max 200 nodes, 2,000 edges.",
            "type": "string",
            "maxLength": 40000,
            "default": "A B 4\nA C 2\nB C 5\nB D 10\nC E 3\nE D 4\nD F 11"
          },
          "directed": {
            "title": "Directed edges",
            "type": "boolean",
            "default": false
          },
          "algorithm": {
            "title": "Algorithm",
            "type": "string",
            "enum": [
              "bfs",
              "dfs",
              "dijkstra",
              "bellman-ford",
              "astar",
              "prim",
              "kruskal",
              "topo",
              "scc"
            ],
            "default": "dijkstra"
          },
          "source": {
            "title": "Start node",
            "description": "Default: the first node. Used by BFS, DFS, Dijkstra, Bellman–Ford, A* and Prim.",
            "type": "string",
            "maxLength": 40
          },
          "target": {
            "title": "Target node",
            "description": "Optional for searches; required for A*.",
            "type": "string",
            "maxLength": 40
          },
          "coordinates": {
            "title": "Node coordinates (node x y), for A* and layout",
            "description": "A* uses the straight-line distance as heuristic; it is admissible only if no edge is shorter than the distance between its end points.",
            "type": "string",
            "maxLength": 20000
          }
        },
        "required": [
          "edges"
        ]
      },
      "GraphAlgorithmVisualizerResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "required": [
              "algorithm",
              "directed",
              "weighted",
              "nodeCount",
              "edgeCount",
              "steps"
            ],
            "properties": {
              "algorithm": {
                "type": "string"
              },
              "directed": {
                "type": "boolean"
              },
              "weighted": {
                "type": "boolean"
              },
              "nodeCount": {
                "type": "integer"
              },
              "edgeCount": {
                "type": "integer"
              },
              "source": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "target": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "order": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Visit / settle / output order."
              },
              "distances": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "node",
                    "distance",
                    "previous"
                  ],
                  "properties": {
                    "node": {
                      "type": "string"
                    },
                    "distance": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "previous": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              },
              "path": {
                "type": [
                  "array",
                  "null"
                ],
                "items": {
                  "type": "string"
                }
              },
              "pathCost": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "mst": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "total": {
                    "type": "number"
                  },
                  "edges": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "components": {
                    "type": "integer"
                  }
                }
              },
              "topologicalOrder": {
                "type": [
                  "array",
                  "null"
                ],
                "items": {
                  "type": "string"
                }
              },
              "components": {
                "type": [
                  "array",
                  "null"
                ],
                "items": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "negativeCycle": {
                "type": [
                  "array",
                  "null"
                ],
                "items": {
                  "type": "string"
                }
              },
              "steps": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "step",
                    "detail"
                  ],
                  "properties": {
                    "step": {
                      "type": "integer"
                    },
                    "action": {
                      "type": "string"
                    },
                    "node": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "BigOCrossoverCalculatorInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "functions": {
            "title": "Cost functions",
            "type": "array",
            "minItems": 1,
            "maxItems": 8,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "label": {
                  "title": "Name",
                  "type": "string",
                  "maxLength": 40
                },
                "complexity": {
                  "title": "Growth",
                  "type": "string",
                  "enum": [
                    "1",
                    "logn",
                    "sqrtn",
                    "n",
                    "nlogn",
                    "n2",
                    "n3",
                    "nk",
                    "2n",
                    "nfact"
                  ],
                  "default": "n"
                },
                "constant": {
                  "title": "Constant c",
                  "type": "number",
                  "minimum": 1e-12,
                  "maximum": 1000000000000000,
                  "default": 1
                },
                "exponent": {
                  "title": "k (for n^k)",
                  "type": "number",
                  "minimum": 0,
                  "maximum": 20
                }
              },
              "required": [
                "complexity",
                "constant"
              ]
            },
            "default": [
              {
                "label": "Merge sort",
                "complexity": "nlogn",
                "constant": 6
              },
              {
                "label": "Insertion sort",
                "complexity": "n2",
                "constant": 0.5
              }
            ]
          },
          "nMin": {
            "title": "Smallest n",
            "type": "number",
            "minimum": 1,
            "maximum": 1000000000000,
            "default": 2
          },
          "nMax": {
            "title": "Largest n",
            "type": "number",
            "minimum": 2,
            "maximum": 1000000000000000,
            "default": 1000000
          },
          "opsPerSecond": {
            "title": "Operations per second",
            "description": "For converting cost into time; 10^9 is a rough figure for simple operations on one CPU core.",
            "type": "number",
            "minimum": 1,
            "maximum": 1000000000000000000,
            "default": 1000000000
          },
          "sizes": {
            "title": "Input sizes for the table",
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 12,
            "default": [
              "10",
              "100",
              "1000",
              "10000",
              "100000",
              "1000000"
            ]
          }
        },
        "required": [
          "functions"
        ]
      },
      "BigOCrossoverCalculatorResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "required": [
              "functions",
              "crossovers",
              "table",
              "opsPerSecond"
            ],
            "properties": {
              "opsPerSecond": {
                "type": "number"
              },
              "functions": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "label",
                    "formula"
                  ],
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "formula": {
                      "type": "string"
                    }
                  }
                }
              },
              "crossovers": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "between",
                    "n",
                    "cheaperAbove"
                  ],
                  "properties": {
                    "between": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "n": {
                      "type": "number"
                    },
                    "firstIntegerN": {
                      "type": "integer"
                    },
                    "cheaperAbove": {
                      "type": "string"
                    }
                  }
                }
              },
              "table": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "n",
                    "costs"
                  ],
                  "properties": {
                    "n": {
                      "type": "number"
                    },
                    "costs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "label",
                          "log10Ops",
                          "ops",
                          "time"
                        ],
                        "properties": {
                          "label": {
                            "type": "string"
                          },
                          "log10Ops": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "ops": {
                            "type": "string"
                          },
                          "time": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              },
              "cheapestAtMax": {
                "type": "string"
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "ErasureCodingPlaygroundInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "data": {
            "title": "Data",
            "description": "Up to 4,096 bytes. Text is encoded as UTF-8.",
            "type": "string",
            "maxLength": 8192,
            "default": "Hello, erasure coding!"
          },
          "encoding": {
            "title": "Data is",
            "type": "string",
            "enum": [
              "text",
              "hex"
            ],
            "default": "text"
          },
          "k": {
            "title": "Data shards (k)",
            "type": "integer",
            "minimum": 1,
            "maximum": 32,
            "default": 4
          },
          "m": {
            "title": "Parity shards (m)",
            "type": "integer",
            "minimum": 0,
            "maximum": 16,
            "default": 2
          },
          "lost": {
            "title": "Lost shards",
            "description": "Shards to delete before reconstruction: D1…Dk (data), P1…Pm (parity) or numbers 1…k+m. Leave empty to only encode.",
            "type": "string"
          }
        },
        "required": [
          "data"
        ]
      },
      "ErasureCodingPlaygroundResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "required": [
              "k",
              "m",
              "n",
              "inputBytes",
              "shardSize",
              "storageOverhead",
              "lost",
              "recoverable",
              "shards",
              "generatorMatrix",
              "comparison",
              "xorParity"
            ],
            "properties": {
              "k": {
                "type": "integer"
              },
              "m": {
                "type": "integer"
              },
              "n": {
                "type": "integer"
              },
              "inputBytes": {
                "type": "integer"
              },
              "shardSize": {
                "type": "integer",
                "description": "Bytes per shard (data zero-padded to k × shardSize)."
              },
              "storageOverhead": {
                "type": "number",
                "description": "n / k"
              },
              "lost": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "recoverable": {
                "type": "boolean"
              },
              "usedShards": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "reconstructedHex": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "reconstructedText": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "matchesOriginal": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "shards": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "name",
                    "role",
                    "lost",
                    "hex"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "role": {
                      "type": "string",
                      "enum": [
                        "data",
                        "parity"
                      ]
                    },
                    "lost": {
                      "type": "boolean"
                    },
                    "hex": {
                      "type": "string"
                    }
                  }
                }
              },
              "generatorMatrix": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "integer"
                  }
                }
              },
              "decodeMatrix": {
                "type": [
                  "array",
                  "null"
                ],
                "items": {
                  "type": "array",
                  "items": {
                    "type": "integer"
                  }
                }
              },
              "xorParity": {
                "type": "object",
                "required": [
                  "parityHex",
                  "recoverable"
                ],
                "properties": {
                  "parityHex": {
                    "type": "string"
                  },
                  "recoverable": {
                    "type": "boolean"
                  }
                }
              },
              "comparison": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "scheme",
                    "storageOverhead",
                    "toleratedLosses",
                    "bytesStored"
                  ],
                  "properties": {
                    "scheme": {
                      "type": "string"
                    },
                    "storageOverhead": {
                      "type": "number"
                    },
                    "toleratedLosses": {
                      "type": "integer"
                    },
                    "bytesStored": {
                      "type": "integer"
                    },
                    "repairReads": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "FloatingPointExplorerInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "value": {
            "title": "Number, expression or bit pattern",
            "description": "A decimal (0.1, -6.02e23), an expression with + − * / and parentheses, NaN / Infinity, or a bit pattern 0x… / 0b….",
            "type": "string",
            "maxLength": 500,
            "default": "0.1"
          },
          "format": {
            "title": "Format",
            "type": "string",
            "enum": [
              "binary64",
              "binary32",
              "binary16"
            ],
            "default": "binary64"
          }
        },
        "required": [
          "value"
        ]
      },
      "FloatingPointExplorerResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "required": [
              "format",
              "input",
              "mode",
              "bits",
              "hex",
              "sign",
              "exponentField",
              "fractionField",
              "kind",
              "storedExact",
              "shortest",
              "neighbours",
              "otherFormats"
            ],
            "properties": {
              "format": {
                "type": "string"
              },
              "input": {
                "type": "string"
              },
              "mode": {
                "type": "string",
                "enum": [
                  "decimal",
                  "special",
                  "bits",
                  "expression"
                ]
              },
              "bits": {
                "type": "string",
                "description": "Binary, most significant bit first."
              },
              "hex": {
                "type": "string"
              },
              "sign": {
                "type": "integer"
              },
              "exponentField": {
                "type": "integer"
              },
              "unbiasedExponent": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "fractionField": {
                "type": "string",
                "description": "Fraction field as an integer (decimal string)."
              },
              "kind": {
                "type": "string",
                "enum": [
                  "zero",
                  "subnormal",
                  "normal",
                  "infinity",
                  "nan"
                ]
              },
              "storedExact": {
                "type": "string",
                "description": "Exact decimal value of the stored number."
              },
              "shortest": {
                "type": "string",
                "description": "Shortest decimal that rounds back to the same bits."
              },
              "roundingError": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "stored − input, exact decimal (null if not applicable)."
              },
              "relativeError": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "ulp": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Distance to the next number away from zero (exact decimal)."
              },
              "neighbours": {
                "type": "object",
                "required": [
                  "previous",
                  "next"
                ],
                "properties": {
                  "previous": {
                    "type": "string"
                  },
                  "next": {
                    "type": "string"
                  }
                }
              },
              "expression": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "exact": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "result": {
                    "type": "string"
                  },
                  "correctlyRounded": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "equalsCorrectlyRounded": {
                    "type": [
                      "boolean",
                      "null"
                    ]
                  },
                  "steps": {
                    "type": "array"
                  }
                }
              },
              "otherFormats": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "format",
                    "hex",
                    "stored"
                  ],
                  "properties": {
                    "format": {
                      "type": "string"
                    },
                    "hex": {
                      "type": "string"
                    },
                    "stored": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "EquationArtStudioInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "curve": {
            "title": "Curve",
            "type": "string",
            "enum": [
              "parametric",
              "polar",
              "lissajous",
              "rose",
              "spirograph",
              "butterfly",
              "heart"
            ],
            "default": "spirograph"
          },
          "xExpr": {
            "title": "x(t)",
            "description": "Used for “my own parametric curve”. Variables: t, a, b, c, d. Implicit multiplication works: 2t, 3sin(t).",
            "type": "string",
            "maxLength": 400,
            "default": "cos(t) + cos(6t)/2 + sin(14t)/3"
          },
          "yExpr": {
            "title": "y(t)",
            "type": "string",
            "maxLength": 400,
            "default": "sin(t) + sin(6t)/2 + cos(14t)/3"
          },
          "rExpr": {
            "title": "r(θ)",
            "description": "Used for “my own polar curve”. Write θ as theta or t.",
            "type": "string",
            "maxLength": 400,
            "default": "1 + 0.5*cos(5theta)"
          },
          "tMin": {
            "title": "t from",
            "description": "A number or constant expression such as 0 or -pi. Empty = preset default (0).",
            "type": "string",
            "maxLength": 60
          },
          "tMax": {
            "title": "t to",
            "description": "E.g. 2*pi. Empty = preset default (2π, or a full period for roses and spirographs).",
            "type": "string",
            "maxLength": 60
          },
          "a": {
            "title": "a",
            "description": "Parameter for presets and your expressions. Empty = preset default.",
            "type": "number",
            "minimum": -1000,
            "maximum": 1000
          },
          "b": {
            "title": "b",
            "type": "number",
            "minimum": -1000,
            "maximum": 1000
          },
          "c": {
            "title": "c",
            "type": "number",
            "minimum": -1000,
            "maximum": 1000
          },
          "d": {
            "title": "d",
            "type": "number",
            "minimum": -1000,
            "maximum": 1000
          },
          "samples": {
            "title": "Samples",
            "description": "More samples = smoother curves. Samples × symmetry copies is limited to 24,000.",
            "type": "integer",
            "minimum": 50,
            "maximum": 10000,
            "default": 2000
          },
          "symmetry": {
            "title": "Rotational symmetry (copies)",
            "type": "integer",
            "minimum": 1,
            "maximum": 12,
            "default": 1
          },
          "palette": {
            "title": "Palette",
            "type": "string",
            "enum": [
              "sunset",
              "ocean",
              "forest",
              "neon",
              "rainbow",
              "mono"
            ],
            "default": "sunset"
          },
          "strokeWidth": {
            "title": "Line width",
            "type": "number",
            "minimum": 0.25,
            "maximum": 12,
            "default": 2,
            "x-unit": "px"
          },
          "png": {
            "title": "Also render a PNG download",
            "type": "boolean",
            "default": true
          }
        },
        "required": []
      },
      "EquationArtStudioResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "curve",
              "curveName",
              "kind",
              "x",
              "y",
              "r",
              "tMin",
              "tMax",
              "params",
              "samples",
              "symmetry",
              "palette",
              "invalidSamples",
              "drawnPoints",
              "closed",
              "arcLength",
              "bbox",
              "svgBytes",
              "svgArtifact",
              "pngArtifact"
            ],
            "properties": {
              "curve": {
                "type": "string"
              },
              "curveName": {
                "type": "string"
              },
              "kind": {
                "type": "string",
                "enum": [
                  "parametric",
                  "polar"
                ]
              },
              "x": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "y": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "r": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "tMin": {
                "type": "number"
              },
              "tMax": {
                "type": "number"
              },
              "params": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "a",
                  "b",
                  "c",
                  "d"
                ],
                "properties": {
                  "a": {
                    "type": "number"
                  },
                  "b": {
                    "type": "number"
                  },
                  "c": {
                    "type": "number"
                  },
                  "d": {
                    "type": "number"
                  }
                }
              },
              "samples": {
                "type": "integer"
              },
              "symmetry": {
                "type": "integer"
              },
              "palette": {
                "type": "string"
              },
              "invalidSamples": {
                "type": "integer"
              },
              "drawnPoints": {
                "type": "integer"
              },
              "closed": {
                "type": "boolean"
              },
              "arcLength": {
                "type": "number",
                "description": "Length of one copy of the curve in curve units."
              },
              "bbox": {
                "type": "array",
                "items": {
                  "type": "number"
                },
                "description": "[minX, minY, maxX, maxY] in curve units, including symmetry copies."
              },
              "svgBytes": {
                "type": "integer"
              },
              "svgArtifact": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "path",
                  "bytes",
                  "sha256"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  }
                }
              },
              "pngArtifact": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "path",
                  "bytes",
                  "sha256"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "RegexGolfArenaInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "puzzle": {
            "title": "Puzzle",
            "type": "string",
            "enum": [
              "warm-up",
              "ending",
              "hex-colours",
              "doubles",
              "abba",
              "iso-dates",
              "powers-of-two",
              "vowel-parade"
            ],
            "default": "warm-up"
          },
          "regex": {
            "title": "Your regex",
            "description": "Without slashes. Tested with JavaScript RegExp.test (a match anywhere counts unless you anchor with ^ and $). Leave empty to see the puzzle and its leaderboard.",
            "type": "string",
            "maxLength": 200
          },
          "flags": {
            "title": "Flags",
            "description": "Flags do not count towards the length.",
            "type": "string",
            "enum": [
              "none",
              "i",
              "u",
              "iu"
            ],
            "default": "none"
          },
          "nickname": {
            "title": "Nickname for the leaderboard (optional)",
            "description": "Letters, digits, spaces, dot, dash and underscore; up to 24 characters. Shown publicly with the length and date — the regex itself is never shown.",
            "type": "string",
            "maxLength": 24
          },
          "dryRun": {
            "title": "Dry run (test only, do not submit to the leaderboard)",
            "type": "boolean",
            "default": false
          }
        },
        "required": []
      },
      "RegexGolfArenaResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "puzzle",
              "title",
              "hint",
              "match",
              "dontMatch",
              "par",
              "submission",
              "leaderboard"
            ],
            "properties": {
              "puzzle": {
                "type": "string"
              },
              "title": {
                "type": "string"
              },
              "hint": {
                "type": "string"
              },
              "match": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "dontMatch": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "par": {
                "type": "integer",
                "description": "Length of a known (not necessarily shortest) solution."
              },
              "submission": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "regex",
                  "flags",
                  "length",
                  "perfect",
                  "score",
                  "matched",
                  "missed",
                  "rejected",
                  "falsePositives",
                  "dryRun",
                  "leaderboardRank",
                  "leaderboardNote"
                ],
                "properties": {
                  "regex": {
                    "type": "string"
                  },
                  "flags": {
                    "type": "string"
                  },
                  "length": {
                    "type": "integer"
                  },
                  "perfect": {
                    "type": "boolean"
                  },
                  "score": {
                    "type": "integer",
                    "description": "10 × (correct matches + correct rejections) − length."
                  },
                  "matched": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "missed": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "rejected": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "falsePositives": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "dryRun": {
                    "type": "boolean"
                  },
                  "leaderboardRank": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  },
                  "leaderboardNote": {
                    "type": "string"
                  }
                }
              },
              "leaderboard": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "rank",
                    "nickname",
                    "length",
                    "score",
                    "date"
                  ],
                  "properties": {
                    "rank": {
                      "type": "integer"
                    },
                    "nickname": {
                      "type": "string"
                    },
                    "length": {
                      "type": "integer"
                    },
                    "score": {
                      "type": "integer"
                    },
                    "date": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "KeyboardHeatmapVisualizerInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "text": {
            "title": "Text",
            "type": "string",
            "maxLength": 100000
          },
          "layout": {
            "title": "Layout for the heatmap",
            "type": "string",
            "enum": [
              "qwerty",
              "qwertz",
              "azerty",
              "dvorak",
              "colemak"
            ],
            "default": "qwerty"
          },
          "compare": {
            "title": "Compare with",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "qwerty",
                "qwertz",
                "azerty",
                "dvorak",
                "colemak"
              ]
            },
            "default": [
              "qwerty",
              "qwertz",
              "azerty",
              "dvorak",
              "colemak"
            ]
          }
        },
        "required": [
          "text"
        ]
      },
      "KeyboardHeatmapVisualizerResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "characters",
              "layout",
              "topKeys",
              "comparison",
              "bestForHomeRow",
              "bestForSameFinger"
            ],
            "properties": {
              "characters": {
                "type": "integer"
              },
              "layout": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "layout",
                  "name",
                  "keystrokes",
                  "typed",
                  "unmapped",
                  "approximated",
                  "rows",
                  "fingers",
                  "leftHand",
                  "rightHand",
                  "homeRow",
                  "sameFingerBigrams",
                  "handAlternation",
                  "modifierPresses"
                ],
                "properties": {
                  "layout": {
                    "type": "string",
                    "enum": [
                      "qwerty",
                      "qwertz",
                      "azerty",
                      "dvorak",
                      "colemak"
                    ]
                  },
                  "name": {
                    "type": "string"
                  },
                  "keystrokes": {
                    "type": "integer",
                    "description": "Key presses including Shift/AltGr."
                  },
                  "typed": {
                    "type": "integer",
                    "description": "Characters typed (excluding modifier presses)."
                  },
                  "unmapped": {
                    "type": "integer"
                  },
                  "approximated": {
                    "type": "integer"
                  },
                  "rows": {
                    "type": "array",
                    "items": {
                      "type": "number"
                    },
                    "description": "% of characters per row: number, top, home, bottom, space."
                  },
                  "fingers": {
                    "type": "array",
                    "items": {
                      "type": "number"
                    },
                    "description": "% per finger: L-pinky, L-ring, L-middle, L-index, R-index, R-middle, R-ring, R-pinky, Thumbs."
                  },
                  "leftHand": {
                    "type": "number"
                  },
                  "rightHand": {
                    "type": "number"
                  },
                  "homeRow": {
                    "type": "number",
                    "description": "% of non-space characters typed on the home row."
                  },
                  "sameFingerBigrams": {
                    "type": "number"
                  },
                  "handAlternation": {
                    "type": "number"
                  },
                  "modifierPresses": {
                    "type": "integer"
                  }
                }
              },
              "topKeys": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "key",
                    "count",
                    "percent"
                  ],
                  "properties": {
                    "key": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "percent": {
                      "type": "number"
                    }
                  }
                }
              },
              "comparison": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "layout",
                    "name",
                    "keystrokes",
                    "typed",
                    "unmapped",
                    "approximated",
                    "rows",
                    "fingers",
                    "leftHand",
                    "rightHand",
                    "homeRow",
                    "sameFingerBigrams",
                    "handAlternation",
                    "modifierPresses"
                  ],
                  "properties": {
                    "layout": {
                      "type": "string",
                      "enum": [
                        "qwerty",
                        "qwertz",
                        "azerty",
                        "dvorak",
                        "colemak"
                      ]
                    },
                    "name": {
                      "type": "string"
                    },
                    "keystrokes": {
                      "type": "integer",
                      "description": "Key presses including Shift/AltGr."
                    },
                    "typed": {
                      "type": "integer",
                      "description": "Characters typed (excluding modifier presses)."
                    },
                    "unmapped": {
                      "type": "integer"
                    },
                    "approximated": {
                      "type": "integer"
                    },
                    "rows": {
                      "type": "array",
                      "items": {
                        "type": "number"
                      },
                      "description": "% of characters per row: number, top, home, bottom, space."
                    },
                    "fingers": {
                      "type": "array",
                      "items": {
                        "type": "number"
                      },
                      "description": "% per finger: L-pinky, L-ring, L-middle, L-index, R-index, R-middle, R-ring, R-pinky, Thumbs."
                    },
                    "leftHand": {
                      "type": "number"
                    },
                    "rightHand": {
                      "type": "number"
                    },
                    "homeRow": {
                      "type": "number",
                      "description": "% of non-space characters typed on the home row."
                    },
                    "sameFingerBigrams": {
                      "type": "number"
                    },
                    "handAlternation": {
                      "type": "number"
                    },
                    "modifierPresses": {
                      "type": "integer"
                    }
                  }
                }
              },
              "bestForHomeRow": {
                "type": "string"
              },
              "bestForSameFinger": {
                "type": "string"
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}