{
  "schema_version": 1,
  "root": {
    "kind": "object",
    "fields": [
      {
        "name": "schema_version",
        "description": "Version of the configuration format, which this library reads; required.",
        "unit": "",
        "schema": {
          "kind": "integer",
          "fixed": true
        },
        "default": 1
      },
      {
        "name": "body",
        "description": "What the terrain lies on: a plane in metres, or a whole body (a sphere, ellipsoid or shape model) in longitude and latitude degrees.",
        "unit": "",
        "schema": {
          "kind": "ref",
          "ref": "d0"
        },
        "default": {
          "type": "plane"
        }
      },
      {
        "name": "base",
        "description": "The starting heights, read from a GeoTIFF or a chain of them, whose grid outputs cover unless they give a region; unset for the body's datum, 0 m, everywhere.",
        "unit": "",
        "schema": {
          "kind": "optional",
          "of": {
            "kind": "ref",
            "ref": "d1"
          },
          "default": {
            "type": "raster",
            "path": "",
            "band": 0,
            "pixel_size": null,
            "resampling": "cubic",
            "scale": null,
            "offset": null,
            "low_pass": 0.0
          }
        },
        "default": null
      },
      {
        "name": "layers",
        "description": "Relief and features added to the base's heights, applied in order: noise, craters, boulders and more.",
        "unit": "",
        "schema": {
          "kind": "array",
          "of": {
            "kind": "ref",
            "ref": "d2"
          },
          "default": {
            "type": "noise",
            "stack": [
              {
                "enabled": true,
                "basis": "perlin",
                "fractal": "fbm",
                "blend": "add",
                "seed": 0,
                "wavelength": 1000.0,
                "amplitude": 100.0,
                "octaves": 8,
                "lacunarity": 2.0,
                "gain": 0.5,
                "hurst": null,
                "offset": 1.0,
                "warp_amplitude": 0.0,
                "warp_wavelength": 500.0
              }
            ]
          }
        },
        "default": []
      },
      {
        "name": "outputs",
        "description": "Files written after generation, each over its own region or the whole body: heightmaps, crater and boulder lists, boulder models, albedo and meshes.",
        "unit": "",
        "schema": {
          "kind": "array",
          "of": {
            "kind": "ref",
            "ref": "d45"
          },
          "default": {
            "type": "heightmap",
            "path": "",
            "region": null,
            "compression": "lzw",
            "tile_size": 256
          }
        },
        "default": []
      },
      {
        "name": "albedo",
        "description": "The terrain's albedo: a source and the layers that change it, written by albedo outputs; none when unset.",
        "unit": "",
        "schema": {
          "kind": "optional",
          "of": {
            "kind": "ref",
            "ref": "d47"
          },
          "default": {
            "source": {
              "type": "synthetic",
              "rgb": false,
              "hue": 0.0,
              "saturation": 0.0,
              "value": 0.11,
              "hue_noise": [],
              "saturation_noise": [],
              "value_noise": []
            },
            "layers": []
          }
        },
        "default": null
      },
      {
        "name": "materials",
        "description": "The material map: soil, sand, dust, bedrock and rock shares, and their Hapke parameters, written by materials and photometry outputs; none when unset.",
        "unit": "",
        "schema": {
          "kind": "optional",
          "of": {
            "kind": "ref",
            "ref": "d60"
          },
          "default": {
            "exposure": {
              "reach": 12.0,
              "rise_soil": 0.01,
              "rise_boulder": 0.035,
              "slope_soil": 0.2,
              "slope_boulder": 0.4,
              "floor_cover": 0.0,
              "floor_patch": 60.0,
              "seed": 0
            },
            "dust_cover": 0.0,
            "dust_patch": 50.0,
            "seed": 0,
            "photometry": {
              "reference": "none",
              "soil": null,
              "sand": null,
              "dust": null,
              "bedrock": null,
              "rock": null
            }
          }
        },
        "default": null
      }
    ]
  },
  "definitions": {
    "d0": {
      "kind": "choice",
      "alternatives": [
        {
          "type": "plane",
          "description": "A flat projected frame in metres, for local sites.",
          "fields": [],
          "default": {
            "type": "plane"
          }
        },
        {
          "type": "sphere",
          "description": "A whole body such as a planet or moon: positions in longitude and latitude (degrees) and features generated over the whole body.",
          "fields": [
            {
              "name": "radius",
              "description": "Radius of the body's datum sphere, in metres; required.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            }
          ],
          "default": {
            "type": "sphere",
            "radius": 0.0
          }
        },
        {
          "type": "ellipsoid",
          "description": "A whole body shaped as a triaxial ellipsoid, such as an elongated moon or asteroid: planetocentric longitude and latitude (degrees), heights along the direction from the centre, and features generated over the whole body.",
          "fields": [
            {
              "name": "radii",
              "description": "Semi-axes a, b and c of the datum ellipsoid in metres, along x (longitude 0), y (longitude 90) and z (the north pole); exactly three, each positive.",
              "unit": "m",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": [],
              "minimum": 0.0,
              "exclusive_minimum": true
            }
          ],
          "default": {
            "type": "ellipsoid",
            "radii": []
          }
        },
        {
          "type": "shape_model",
          "description": "A whole star-shaped body such as an asteroid, from a shape model: planetocentric longitude and latitude (degrees), heights along the direction from the centre, and features generated over the whole body. The model is resampled along rays from its origin, keeping the outermost surface where a ray crosses it more than once.",
          "fields": [
            {
              "name": "path",
              "description": "Shape model in body-fixed coordinates around its origin: a Gaskell ICQ model (.icq) or a closed mesh (.obj, .gltf, .glb or .stl); relative paths resolve against the configuration's folder.",
              "unit": "",
              "schema": {
                "kind": "string"
              },
              "default": ""
            },
            {
              "name": "q",
              "description": "Intervals per cube face edge of the radial grid the model is resampled on, 1 to 4096; unset keeps an ICQ model's own Q and uses 256 for a mesh.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "integer",
                  "minimum": 0
                },
                "default": 0
              },
              "default": null,
              "minimum": 1.0,
              "exclusive_minimum": false,
              "maximum": 4096.0,
              "exclusive_maximum": false
            },
            {
              "name": "metres_per_unit",
              "description": "Metres per unit of the file's coordinates; unset is 1000 for an ICQ model, whose coordinates are kilometres, and 1 for a mesh.",
              "unit": "m",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": true
            }
          ],
          "default": {
            "type": "shape_model",
            "path": "",
            "q": null,
            "metres_per_unit": null
          }
        }
      ]
    },
    "d1": {
      "kind": "choice",
      "alternatives": [
        {
          "type": "raster",
          "description": "A heightmap read from a GeoTIFF in its own projected coordinates, optionally resampled, to add relief to a real DEM.",
          "fields": [
            {
              "name": "path",
              "description": "GeoTIFF to read the heights from; relative paths resolve against the configuration's folder.",
              "unit": "",
              "schema": {
                "kind": "string"
              },
              "default": ""
            },
            {
              "name": "band",
              "description": "Band of the file to read, counting from 0.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 0
            },
            {
              "name": "pixel_size",
              "description": "Cell size in metres to resample the raster to over the same extent, as when upscaling a DEM. Unset keeps the file's.",
              "unit": "m",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "resampling",
              "description": "Interpolation used when resampling to the cell size.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "nearest",
                  "bilinear",
                  "cubic"
                ],
                "descriptions": [
                  "The value of the nearest cell centre: blocky, but never mixes values.",
                  "Linear in each axis over the four surrounding cells.",
                  "Keys cubic convolution over the sixteen surrounding cells: the smoothest, for upscaling DEMs."
                ]
              },
              "default": "cubic"
            },
            {
              "name": "scale",
              "description": "Factor each sample is multiplied by, replacing the band's scale from the file's GDAL metadata. Unset keeps the file's.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null
            },
            {
              "name": "offset",
              "description": "Added to each scaled sample, replacing the band's offset from the file's GDAL metadata. Unset keeps the file's.",
              "unit": "m",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null
            },
            {
              "name": "low_pass",
              "description": "Standard deviation in metres of a Gaussian low-pass applied to the file's heights before any resampling, keeping a DEM's low frequencies for synthetic detail to be added to; a dem_detail layer can add the removed detail back. 0 keeps every frequency.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            }
          ],
          "default": {
            "type": "raster",
            "path": "",
            "band": 0,
            "pixel_size": null,
            "resampling": "cubic",
            "scale": null,
            "offset": null,
            "low_pass": 0.0
          }
        },
        {
          "type": "chain",
          "description": "Several bases tried in order, each filling where those before it have no data; its grid is the first one's.",
          "fields": [
            {
              "name": "sources",
              "description": "Bases tried in order, each filling where those before it have no data; the chain's grid is the first one's.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "ref",
                  "ref": "d1"
                },
                "default": {
                  "type": "raster",
                  "path": "",
                  "band": 0,
                  "pixel_size": null,
                  "resampling": "cubic",
                  "scale": null,
                  "offset": null,
                  "low_pass": 0.0
                }
              },
              "default": []
            }
          ],
          "default": {
            "type": "chain",
            "sources": []
          }
        }
      ]
    },
    "d3": {
      "kind": "object",
      "fields": [
        {
          "name": "enabled",
          "description": "Includes this layer in the stack; disabled layers are skipped.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": true
        },
        {
          "name": "basis",
          "description": "Single-octave noise the fractal is built from.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "perlin",
              "simplex",
              "value",
              "worley_f1",
              "worley_f2",
              "worley_f2_minus_f1",
              "voronoi"
            ],
            "descriptions": [
              "Improved Perlin gradient noise: smooth, general-purpose relief.",
              "Simplex gradient noise: smooth relief, an alternative to Perlin.",
              "Value noise: random values interpolated over a lattice; blockier than gradient noise.",
              "Cellular noise from the distance to the nearest feature point: cones and basins.",
              "Cellular noise from the distance to the second-nearest feature point.",
              "Cellular noise F2 - F1: ridges along cell borders, like cracked ground.",
              "Voronoi cells, each at one random height: flat polygonal plateaus and terraces."
            ]
          },
          "default": "perlin"
        },
        {
          "name": "fractal",
          "description": "How the octaves of the basis noise are combined.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "fbm",
              "ridged",
              "billow",
              "hybrid_multifractal"
            ],
            "descriptions": [
              "Fractional Brownian motion: a weighted sum of octaves, the general-purpose choice.",
              "Ridged multifractal: sharp crests from inverted absolute noise, like eroded ridges.",
              "Sum of absolute-value octaves: rounded, puffy forms.",
              "Hybrid multifractal: smooth lowlands and rough highlands."
            ]
          },
          "default": "fbm"
        },
        {
          "name": "blend",
          "description": "How this layer combines with the height of the layers before it; the first enabled layer sets the height instead.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "add",
              "max",
              "min",
              "mask"
            ],
            "descriptions": [
              "Adds the layer to the height so far.",
              "Keeps the higher of the height so far and the layer.",
              "Keeps the lower of the height so far and the layer.",
              "Multiplies the height so far by (layer / amplitude + 1) / 2, so the layer modulates roughness by region."
            ]
          },
          "default": "add"
        },
        {
          "name": "seed",
          "description": "Seed of the noise; changing it gives a different pattern of the same character.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        },
        {
          "name": "wavelength",
          "description": "Wavelength of the first, broadest octave, in metres; sets the size of the largest features.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 1000.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "amplitude",
          "description": "Largest height of the layer above or below 0, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 100.0
        },
        {
          "name": "octaves",
          "description": "Number of octaves, at least 1; each one adds detail at a shorter wavelength.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 8,
          "minimum": 1.0,
          "exclusive_minimum": false,
          "maximum": 32.0,
          "exclusive_maximum": false
        },
        {
          "name": "lacunarity",
          "description": "Frequency ratio between successive octaves; greater than 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 2.0,
          "minimum": 1.0,
          "exclusive_minimum": true
        },
        {
          "name": "gain",
          "description": "Weight ratio between successive octaves, greater than 0; higher values give rougher terrain. Unused when the Hurst exponent is set.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.5,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "hurst",
          "description": "Hurst exponent that sets the octave gain to lacunarity^-hurst: near 1 is smooth, lower is rougher at short baselines. Unset uses the gain.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null
        },
        {
          "name": "offset",
          "description": "Ridge offset of the ridged and hybrid multifractal types; greater than 0.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "warp_amplitude",
          "description": "Domain warp displacement in metres, which bends the noise into swirled shapes; 0 disables warping.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "warp_wavelength",
          "description": "Wavelength of the warp field, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 500.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        }
      ]
    },
    "d5": {
      "kind": "object",
      "fields": [
        {
          "name": "start",
          "description": "Diameter in metres where this segment begins; it runs up to the next segment's start.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "coefficient",
          "description": "Coefficient of N(>=D) = coefficient D^-exponent, the cumulative count per m^2 with D in metres.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "exponent",
          "description": "Exponent of the segment's power law; larger values give relatively more small craters.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 2.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        }
      ]
    },
    "d6": {
      "kind": "object",
      "fields": [
        {
          "name": "min",
          "description": "Smallest diameter of the band in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "max",
          "description": "Largest diameter of the band in metres, above min.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 2.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "density",
          "description": "Count per m^2 with diameters in the band, spread uniformly across it; a relative weight when total is set.",
          "unit": "1/m^2",
          "schema": {
            "kind": "number"
          },
          "default": 0.01,
          "minimum": 0.0,
          "exclusive_minimum": false
        }
      ]
    },
    "d4": {
      "kind": "choice",
      "alternatives": [
        {
          "type": "power_law",
          "description": "A cumulative power law, N(>=D) = coefficient D^-exponent per m^2 with D in metres.",
          "fields": [
            {
              "name": "coefficient",
              "description": "Coefficient of N(>=D) = coefficient D^-exponent, the cumulative count per m^2 with D in metres; scales how many there are.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.1,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "exponent",
              "description": "Exponent of the power law; larger values give relatively more small craters or boulders.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 2.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            }
          ],
          "default": {
            "type": "power_law",
            "coefficient": 0.1,
            "exponent": 2.0
          }
        },
        {
          "type": "piecewise_power_law",
          "description": "A cumulative distribution made of power-law segments over diameter ranges.",
          "fields": [
            {
              "name": "segments",
              "description": "Power-law segments in strictly increasing order of start, each running to the next one's start; they must meet at their joins.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "ref",
                  "ref": "d5"
                },
                "default": {
                  "start": 0.0,
                  "coefficient": 1.0,
                  "exponent": 2.0
                }
              },
              "default": [
                {
                  "start": 0.0,
                  "coefficient": 1.0,
                  "exponent": 2.0
                }
              ]
            }
          ],
          "default": {
            "type": "piecewise_power_law",
            "segments": [
              {
                "start": 0.0,
                "coefficient": 1.0,
                "exponent": 2.0
              }
            ]
          }
        },
        {
          "type": "tabulated",
          "description": "A cumulative distribution from a table of diameters and counts N(>=D), in units you choose.",
          "fields": [
            {
              "name": "diameters",
              "description": "Table diameters in diameter units, at least two, positive and strictly increasing; counts are interpolated linearly in log D and log N between them.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": [],
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "cumulative",
              "description": "Cumulative count N(>=D) at each diameter, per area unit; positive and not increasing.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": [],
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "diameter_unit",
              "description": "Metres per table diameter unit: 1 for metres, 1000 for km.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "area_unit",
              "description": "Square metres per table area unit: 1 for m^2, 1e6 for km^2.",
              "unit": "m^2",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            }
          ],
          "default": {
            "type": "tabulated",
            "diameters": [],
            "cumulative": [],
            "diameter_unit": 1.0,
            "area_unit": 1.0
          }
        },
        {
          "type": "production_surface",
          "description": "The craters a production function leaves on a surface of a given age, scaled by a chronology, with no erosion; cap it with an equilibrium in a minimum.",
          "fields": [
            {
              "name": "production",
              "description": "Production function that gives the craters' sizes.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "neukum",
                  "extended_neukum",
                  "ivanov"
                ],
                "descriptions": [
                  "Neukum et al. (2001) lunar production function, valid from 10 m to 300 km.",
                  "The Neukum production function continued below 10 m as a power law of slope -2.85, valid from 2.5 m to 300 km.",
                  "Ivanov (2001) Martian production function, valid from 15 m to 362 km."
                ]
              },
              "default": "extended_neukum"
            },
            {
              "name": "chronology",
              "description": "Chronology that gives how many craters at least 1 km across the surface holds.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "neukum",
                  "ivanov"
                ],
                "descriptions": [
                  "Neukum et al. (2001) lunar chronology, for surfaces 0 to 4.6 Gyr old.",
                  "Ivanov (2001) Martian chronology, for surfaces 0 to 4.6 Gyr old."
                ]
              },
              "default": "neukum"
            },
            {
              "name": "age_gyr",
              "description": "Age of the surface in Gyr, from 0 to 4.6; older surfaces hold more craters.",
              "unit": "Gyr",
              "schema": {
                "kind": "number"
              },
              "default": 3.5,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 4.6,
              "exclusive_maximum": false
            }
          ],
          "default": {
            "type": "production_surface",
            "production": "extended_neukum",
            "chronology": "neukum",
            "age_gyr": 3.5
          }
        },
        {
          "type": "minimum",
          "description": "The least of several densities at each diameter, such as a production surface capped by an equilibrium.",
          "fields": [
            {
              "name": "distributions",
              "description": "Densities whose least cumulative count at each diameter is used; at least one.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "ref",
                  "ref": "d4"
                },
                "default": {
                  "type": "power_law",
                  "coefficient": 0.1,
                  "exponent": 2.0
                }
              },
              "default": []
            }
          ],
          "default": {
            "type": "minimum",
            "distributions": []
          }
        },
        {
          "type": "trask",
          "description": "The Trask (1966) lunar equilibrium density, N(>=D) = 10^-1.1 D^-2.",
          "fields": [],
          "default": {
            "type": "trask"
          }
        },
        {
          "type": "hartmann",
          "description": "The Hartmann (1984) lunar equilibrium density, N(>=D) = 10^-1.14 D^-1.83 per km^2 with D in km.",
          "fields": [],
          "default": {
            "type": "hartmann"
          }
        },
        {
          "type": "moore",
          "description": "Moore's terrain-specific crater distributions for Lunar Roving Vehicle trafficability.",
          "fields": [
            {
              "name": "terrain",
              "description": "Terrain type whose crater distribution of Moore's to use.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "rough_mare",
                  "smooth_mare",
                  "uplands",
                  "heavily_cratered"
                ],
                "descriptions": [
                  "Moore's rough mare crater distribution: 10^-1 D^-2 per m^2 below 100 m, 10 D^-3 above.",
                  "Moore's smooth mare crater distribution: 10^-1 D^-2 per m^2 below 40 m, then D^-3, D^-1.68 from 100 m and D^-3 from 200 m.",
                  "Moore's uplands crater distribution: 10^-1 D^-2 per m^2 below 1 km, 10^2 D^-3 above.",
                  "Moore's heavily cratered distribution: 10^-1 D^-2 per m^2 up to 10 km."
                ]
              },
              "default": "rough_mare"
            }
          ],
          "default": {
            "type": "moore",
            "terrain": "rough_mare"
          }
        },
        {
          "type": "viper",
          "description": "The VIPER environmental specification crater density, as synthterrain uses it; kept for comparison with synthterrain.",
          "fields": [],
          "default": {
            "type": "viper"
          }
        },
        {
          "type": "piecewise_uniform",
          "description": "Counts per m^2 in diameter bands, each with diameters spread uniformly across it; none outside the bands.",
          "fields": [
            {
              "name": "bands",
              "description": "Diameter bands with their counts; overlapping bands add, and gaps between them hold none.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "ref",
                  "ref": "d6"
                },
                "default": {
                  "min": 1.0,
                  "max": 2.0,
                  "density": 0.01
                }
              },
              "default": [
                {
                  "min": 1.0,
                  "max": 2.0,
                  "density": 0.01
                }
              ]
            },
            {
              "name": "total",
              "description": "Count per m^2 of all bands together, shared in proportion to each band's density; 0 uses the densities as given.",
              "unit": "1/m^2",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            }
          ],
          "default": {
            "type": "piecewise_uniform",
            "bands": [
              {
                "min": 1.0,
                "max": 2.0,
                "density": 0.01
              }
            ],
            "total": 0.0
          }
        }
      ]
    },
    "d7": {
      "kind": "choice",
      "alternatives": [
        {
          "type": "uniform",
          "description": "Ages uniform over one lifetime for every diameter, so freshness is uniform between 0 and 1.",
          "fields": [
            {
              "name": "lifetime_gyr",
              "description": "Lifetime in Gyr, positive, that every crater's age is drawn uniformly within; with degradation, a crater this old is fully worn.",
              "unit": "Gyr",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            }
          ],
          "default": {
            "type": "uniform",
            "lifetime_gyr": 1.0
          }
        },
        {
          "type": "fresh",
          "description": "Every crater is fresh, with age and lifetime zero.",
          "fields": [],
          "default": {
            "type": "fresh"
          }
        },
        {
          "type": "steady_state",
          "description": "Crater ages where small craters are in equilibrium: a crater lasts until the production rate replaces the equilibrium density, or the surface's age, with ages drawn from the chronology's formation rate.",
          "fields": [
            {
              "name": "age_gyr",
              "description": "Age of the surface in Gyr, from 0 to 4.6; it caps every crater's lifetime, so larger craters on an older surface can be older.",
              "unit": "Gyr",
              "schema": {
                "kind": "number"
              },
              "default": 3.5,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 4.6,
              "exclusive_maximum": false
            },
            {
              "name": "production",
              "description": "Production function whose rate, with the equilibrium, sets how long small craters last.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "neukum",
                  "extended_neukum",
                  "ivanov"
                ],
                "descriptions": [
                  "Neukum et al. (2001) lunar production function, valid from 10 m to 300 km.",
                  "The Neukum production function continued below 10 m as a power law of slope -2.85, valid from 2.5 m to 300 km.",
                  "Ivanov (2001) Martian production function, valid from 15 m to 362 km."
                ]
              },
              "default": "extended_neukum"
            },
            {
              "name": "equilibrium",
              "description": "Equilibrium density that, with the production rate, sets how long small craters last before they are erased.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "trask",
                  "hartmann"
                ],
                "descriptions": [
                  "Trask (1966) lunar equilibrium, N(>=D) = 10^-1.1 D^-2, as the DSNE uses.",
                  "Hartmann (1984) lunar equilibrium, N(>=D) = 10^-1.14 D^-1.83 per km^2 with D in km."
                ]
              },
              "default": "trask"
            },
            {
              "name": "chronology",
              "description": "Chronology whose formation rate the craters' ages are drawn from.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "neukum",
                  "ivanov"
                ],
                "descriptions": [
                  "Neukum et al. (2001) lunar chronology, for surfaces 0 to 4.6 Gyr old.",
                  "Ivanov (2001) Martian chronology, for surfaces 0 to 4.6 Gyr old."
                ]
              },
              "default": "neukum"
            }
          ],
          "default": {
            "type": "steady_state",
            "age_gyr": 3.5,
            "production": "extended_neukum",
            "equilibrium": "trask",
            "chronology": "neukum"
          }
        }
      ]
    },
    "d8": {
      "kind": "object",
      "fields": [
        {
          "name": "diameter_ratio",
          "description": "Largest ratio of two craters' diameters, at least 1, for them to count as similar in size and be kept apart.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.5,
          "minimum": 1.0,
          "exclusive_minimum": false
        },
        {
          "name": "separation",
          "description": "Least distance between the centres of similar-size craters, in larger diameters; 0 disables spacing.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        }
      ]
    },
    "d9": {
      "kind": "object",
      "fields": [
        {
          "name": "x",
          "description": "Centre along x in the surface's coordinates; the longitude in degrees on a sphere.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0
        },
        {
          "name": "y",
          "description": "Centre along y in the surface's coordinates; the latitude in degrees on a sphere.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0
        },
        {
          "name": "diameter",
          "description": "Rim-to-rim diameter, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "age_gyr",
          "description": "Age in Gyr; older craters are more degraded under a degradation model and are applied earlier in oldest-first order.",
          "unit": "Gyr",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "id",
          "description": "Stable ID that seeds the crater's outline; 0 derives one from its position and diameter.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        }
      ]
    },
    "d11": {
      "kind": "choice",
      "alternatives": [
        {
          "type": "fassett_thomson",
          "description": "Fresh simple-crater profile of Fassett and Thomson (2014), with synthterrain's variants.",
          "fields": [
            {
              "name": "rim",
              "description": "How the profile's interior and exterior fits are joined at the rim.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "original",
                  "at_one_radius",
                  "plateau"
                ],
                "descriptions": [
                  "The published fits, whose interior and exterior meet at 0.98 radii.",
                  "Interior fit extended to 1.0 radii so the rim lies at the stated diameter, as synthterrain's FT_Crater; leaves a small step at the rim.",
                  "A flat rim at the fresh rim height from 0.98 to 1.02 radii, after Fassett et al. (2022), as synthterrain's FTmod_Crater."
                ]
              },
              "default": "original"
            }
          ],
          "default": {
            "type": "fassett_thomson",
            "rim": "original"
          }
        },
        {
          "type": "martin_parkes_dunstan",
          "description": "Simple-crater profile of Martin, Parkes and Dunstan (2014), developed for the PANGU simulator; degradation rounds its rim.",
          "fields": [],
          "default": {
            "type": "martin_parkes_dunstan"
          }
        }
      ]
    },
    "d10": {
      "kind": "choice",
      "alternatives": [
        {
          "type": "fassett_thomson",
          "description": "Fresh simple-crater profile of Fassett and Thomson (2014), with synthterrain's variants.",
          "fields": [
            {
              "name": "rim",
              "description": "How the profile's interior and exterior fits are joined at the rim.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "original",
                  "at_one_radius",
                  "plateau"
                ],
                "descriptions": [
                  "The published fits, whose interior and exterior meet at 0.98 radii.",
                  "Interior fit extended to 1.0 radii so the rim lies at the stated diameter, as synthterrain's FT_Crater; leaves a small step at the rim.",
                  "A flat rim at the fresh rim height from 0.98 to 1.02 radii, after Fassett et al. (2022), as synthterrain's FTmod_Crater."
                ]
              },
              "default": "original"
            }
          ],
          "default": {
            "type": "fassett_thomson",
            "rim": "original"
          }
        },
        {
          "type": "martin_parkes_dunstan",
          "description": "Simple-crater profile of Martin, Parkes and Dunstan (2014), developed for the PANGU simulator; degradation rounds its rim.",
          "fields": [],
          "default": {
            "type": "martin_parkes_dunstan"
          }
        },
        {
          "type": "complex",
          "description": "A simple profile below the body's simple-to-complex transition, and complex craters with flat floors and central peaks above it.",
          "fields": [
            {
              "name": "simple",
              "description": "Profile of the simple craters, those below the body's simple-to-complex transition diameter.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d11"
              },
              "default": {
                "type": "martin_parkes_dunstan"
              }
            }
          ],
          "default": {
            "type": "complex",
            "simple": {
              "type": "martin_parkes_dunstan"
            }
          }
        }
      ]
    },
    "d13": {
      "kind": "object",
      "fields": [
        {
          "name": "coefficient",
          "description": "Diffusivity of a 1 km crater, in m^2/Myr, positive; higher values wear craters down faster.",
          "unit": "m^2/Myr",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "exponent",
          "description": "Exponent of the diameter in coefficient (D / 1 km)^exponent; 0 gives the same diffusivity for every crater size.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0
        },
        {
          "name": "min_diameter",
          "description": "Diameter in metres below which the diffusivity is held at its value at this diameter; not negative.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        }
      ]
    },
    "d12": {
      "kind": "choice",
      "alternatives": [
        {
          "type": "freshness",
          "description": "Scales depth and rim height linearly with freshness, down to a cutoff depth ratio at the end of a crater's lifetime.",
          "fields": [
            {
              "name": "cutoff_depth_ratio",
              "description": "Depth over diameter of a crater at the end of its lifetime, in (0, 0.1); lower values let old craters wear shallower.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.04,
              "minimum": 0.0,
              "exclusive_minimum": true,
              "maximum": 0.1,
              "exclusive_maximum": true
            }
          ],
          "default": {
            "type": "freshness",
            "cutoff_depth_ratio": 0.04
          }
        },
        {
          "type": "none",
          "description": "Craters stay fresh, optionally all with one depth to diameter ratio.",
          "fields": [
            {
              "name": "depth_ratio",
              "description": "Depth over diameter given to every crater, positive; unset keeps each crater's fresh depth for the body.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": true
            }
          ],
          "default": {
            "type": "none",
            "depth_ratio": null
          }
        },
        {
          "type": "diffusion",
          "description": "Wears craters down by topographic diffusion, from each crater's diameter and age.",
          "fields": [
            {
              "name": "diffusivity",
              "description": "Model of the diffusion age each crater has from its diameter and age; on Mars only power_law is allowed.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "matched",
                  "fassett_2022_hartmann",
                  "fassett_2022_trask",
                  "fassett_thomson_2014",
                  "fassett_thomson_2014_calibration",
                  "power_law"
                ],
                "descriptions": [
                  "The Fassett et al. (2022) diffusivity fitted to the steady-state ages' equilibrium (Trask or Hartmann), so craters wear as that equilibrium expects; Hartmann's for other ages.",
                  "Lunar size-dependent diffusivity of Fassett et al. (2022) for the Hartmann equilibrium, 3.6 D^0.87 m^2/Myr with D in km.",
                  "Lunar size-dependent diffusivity of Fassett et al. (2022) for the Trask equilibrium, 3.1 D^1.05 m^2/Myr with D in km.",
                  "Lunar diffusivity of Fassett and Thomson (2014), 5.5 m^2/Myr for every crater size; it erases craters below a few hundred metres within a small share of their lifetimes.",
                  "Fassett and Thomson's (2014) lunar diffusion age against crater age, independent of size; suits kilometre-scale craters.",
                  "A diffusivity of your own, coefficient (D / 1 km)^exponent m^2/Myr, from the power_law settings."
                ]
              },
              "default": "matched"
            },
            {
              "name": "power_law",
              "description": "The diffusivity used when the diffusivity model is power_law.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d13"
              },
              "default": {
                "coefficient": 1.0,
                "exponent": 0.0,
                "min_diameter": 0.0
              }
            },
            {
              "name": "reach_radii",
              "description": "Distance from the centre, in crater radii, out to which the diffused profile is solved and held at 0; at least the fresh profile's reach.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 3.0
            }
          ],
          "default": {
            "type": "diffusion",
            "diffusivity": "matched",
            "power_law": {
              "coefficient": 1.0,
              "exponent": 0.0,
              "min_diameter": 0.0
            },
            "reach_radii": 3.0
          }
        }
      ]
    },
    "d15": {
      "kind": "object",
      "fields": [
        {
          "name": "start_samples",
          "description": "Samples across a feature's diameter up to which it is left out entirely.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 2.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "end_samples",
          "description": "Samples across a feature's diameter from which it is applied in full; it fades in between the two counts.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 4.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "shape",
          "description": "Curve of the fade between the start and end sample counts.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "linear",
              "smoothstep",
              "smootherstep",
              "gaussian"
            ],
            "descriptions": [
              "Straight ramp: continuous, with kinks at both ends.",
              "Cubic 3t^2 - 2t^3: continuous slope across the transition.",
              "Quintic 6t^5 - 15t^4 + 10t^3: continuous slope and curvature, the smoothest join.",
              "Gaussian falloff with sigma a third of the band, rescaled to end at zero."
            ]
          },
          "default": "smoothstep"
        }
      ]
    },
    "d16": {
      "kind": "object",
      "fields": [
        {
          "name": "start_radii",
          "description": "Distance from the centre, in crater radii, up to which the interior is fully replaced.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.8,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "end_radii",
          "description": "Distance from the centre, in crater radii, from which the surrounding terrain is draped unchanged.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.2,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "shape",
          "description": "Curve of the transition from the replaced interior to the exterior.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "linear",
              "smoothstep",
              "smootherstep",
              "gaussian"
            ],
            "descriptions": [
              "Straight ramp: continuous, with kinks at both ends.",
              "Cubic 3t^2 - 2t^3: continuous slope across the transition.",
              "Quintic 6t^5 - 15t^4 + 10t^3: continuous slope and curvature, the smoothest join.",
              "Gaussian falloff with sigma a third of the band, rescaled to end at zero."
            ]
          },
          "default": "smootherstep"
        }
      ]
    },
    "d18": {
      "kind": "object",
      "fields": [
        {
          "name": "kind",
          "description": "Kind of distribution the value is drawn from.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "constant",
              "uniform",
              "normal",
              "log_normal"
            ],
            "descriptions": [
              "Always a.",
              "Uniform between a and b.",
              "Normal with mean a and standard deviation b.",
              "Log-normal with median a and standard deviation b of the natural logarithm."
            ]
          },
          "default": "constant"
        },
        {
          "name": "a",
          "description": "The constant value, the uniform's lower bound, the normal's mean or the log-normal's median.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0
        },
        {
          "name": "b",
          "description": "The uniform's upper bound, or the standard deviation (of the natural logarithm for a log-normal); unused for a constant.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0
        },
        {
          "name": "min",
          "description": "Lower bound drawn values are clamped to; unset leaves them unbounded below.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null
        },
        {
          "name": "max",
          "description": "Upper bound drawn values are clamped to; unset leaves them unbounded above, which normal and log-normal kinds do not allow.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null
        }
      ]
    },
    "d17": {
      "kind": "object",
      "fields": [
        {
          "name": "enabled",
          "description": "Gives eligible craters irregular, non-circular outlines; off keeps every crater round.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": false
        },
        {
          "name": "seed",
          "description": "Seed the outlines are drawn with, along with each crater's ID; changing it reshapes every irregular crater.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        },
        {
          "name": "min_diameter",
          "description": "Smallest diameter, in metres, of craters made irregular.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "max_diameter",
          "description": "Largest diameter, in metres, of craters made irregular; unset has no upper limit.",
          "unit": "m",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "min_age_gyr",
          "description": "Youngest age, in Gyr, of craters made irregular.",
          "unit": "Gyr",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "max_age_gyr",
          "description": "Oldest age, in Gyr, of craters made irregular; unset has no upper limit.",
          "unit": "Gyr",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "manual",
          "description": "Makes manual craters irregular too; otherwise only generated craters are.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": false
        },
        {
          "name": "rough_share",
          "description": "Share of eligible craters, from 0 to 1, given rough, wavy rims.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "model",
          "description": "How rough rims are drawn.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "power_law",
              "du_2024"
            ],
            "descriptions": [
              "Rim harmonics with amplitudes falling as a power of the harmonic number, of a given RMS: a simple, configurable spectrum.",
              "The fitted rim-crest spectra of fresh lunar craters of Du et al. (2024), from each crater's diameter."
            ]
          },
          "default": "power_law"
        },
        {
          "name": "scatter",
          "description": "With du_2024, scatters each crater's spectrum by the fits' measured misfits and noise.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": true
        },
        {
          "name": "max_deviation",
          "description": "With du_2024, the largest deviation of a rim from a circle, in radii; outlines beyond it are scaled down to it.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.3,
          "minimum": 0.0,
          "exclusive_minimum": true,
          "maximum": 0.5,
          "exclusive_maximum": false
        },
        {
          "name": "roughness",
          "description": "With power_law, the RMS deviation of a rough rim from a circle, in crater radii, drawn per crater.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "uniform",
            "a": 0.01,
            "b": 0.03,
            "min": null,
            "max": null
          }
        },
        {
          "name": "spectral_slope",
          "description": "With power_law, the exponent s of the rim harmonics' amplitudes, falling as k^-s, drawn per crater; higher values leave less fine waviness.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "constant",
            "a": 1.5,
            "b": 0.0,
            "min": null,
            "max": null
          }
        },
        {
          "name": "min_harmonic",
          "description": "With power_law, the lowest harmonic of the rim's waviness, from 1 to 64.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 2,
          "minimum": 1.0,
          "exclusive_minimum": false,
          "maximum": 64.0,
          "exclusive_maximum": false
        },
        {
          "name": "max_harmonic",
          "description": "With power_law, the highest harmonic of the rim's waviness, at most 64; higher harmonics add finer wiggles.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 12,
          "minimum": 1.0,
          "exclusive_minimum": false,
          "maximum": 64.0,
          "exclusive_maximum": false
        },
        {
          "name": "elongated_share",
          "description": "Share of eligible craters, from 0 to 1, made elliptical, keeping their area.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.054,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "ellipticity",
          "description": "Long over short rim-to-rim diameter of elliptical craters, drawn per crater; at least 1.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "uniform",
            "a": 1.1,
            "b": 1.5,
            "min": null,
            "max": null
          }
        },
        {
          "name": "heading",
          "description": "Heading of elliptical craters' long axes, in radians counter-clockwise from +x; unset gives random headings.",
          "unit": "rad",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null
        },
        {
          "name": "heading_spread",
          "description": "Largest random turn of a long axis either way from the heading, in radians.",
          "unit": "rad",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "marks_share",
          "description": "Share of eligible craters, from 0 to 1, given radial marks: ridges and grooves down the wall, strongest where it is steepest.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "marks_amplitude",
          "description": "Largest radial shift of the wall by the marks, in crater radii, drawn per crater; below marks_fade_radii / 3.75.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "uniform",
            "a": 0.0,
            "b": 0.005,
            "min": null,
            "max": null
          }
        },
        {
          "name": "marks_knots",
          "description": "Random shifts around the crater the marks pass through, from 3 to 1024; more knots give narrower marks.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 45,
          "minimum": 3.0,
          "exclusive_minimum": false,
          "maximum": 1024.0,
          "exclusive_maximum": false
        },
        {
          "name": "marks_inner_radii",
          "description": "Distance from the centre, in crater radii, where the marks reach full strength.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.3,
          "minimum": 0.0,
          "exclusive_minimum": true,
          "maximum": 1.0,
          "exclusive_maximum": true
        },
        {
          "name": "marks_outer_radii",
          "description": "Distance from the centre, in crater radii, where the marks start to fade; at most 1 minus marks_fade_radii.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.9,
          "minimum": 0.0,
          "exclusive_minimum": true,
          "maximum": 1.0,
          "exclusive_maximum": true
        },
        {
          "name": "marks_fade_radii",
          "description": "Width, in crater radii, over which the marks fade in and out.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.1,
          "minimum": 0.0,
          "exclusive_minimum": true,
          "maximum": 0.5,
          "exclusive_maximum": false
        }
      ]
    },
    "d19": {
      "kind": "object",
      "fields": [
        {
          "name": "sigma_radii",
          "description": "Deviation of the Gaussian the profile is smoothed with across distance, in crater radii; larger values round rims more, and 0 leaves them sharp.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "inner_radii",
          "description": "Inner edge of the smoothed band around the rim, in crater radii; below 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.8,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": true
        },
        {
          "name": "outer_radii",
          "description": "Outer edge of the smoothed band around the rim, in crater radii; above 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.2,
          "minimum": 1.0,
          "exclusive_minimum": true
        },
        {
          "name": "shape",
          "description": "How the smoothing fades from full at the rim to none at the band's edges.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "linear",
              "smoothstep",
              "smootherstep",
              "gaussian"
            ],
            "descriptions": [
              "Straight ramp: continuous, with kinks at both ends.",
              "Cubic 3t^2 - 2t^3: continuous slope across the transition.",
              "Quintic 6t^5 - 15t^4 + 10t^3: continuous slope and curvature, the smoothest join.",
              "Gaussian falloff with sigma a third of the band, rescaled to end at zero."
            ]
          },
          "default": "smootherstep"
        },
        {
          "name": "strength",
          "description": "Share of the smoothed height used at the rim, from 0 to 1; lower values keep more of the sharp crest.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        }
      ]
    },
    "d20": {
      "kind": "object",
      "fields": [
        {
          "name": "amplitude",
          "description": "Amplitude of the noise over the whole footprint, as a share of the crater diameter; it fades out beyond the rim to the profile's reach, and 0 adds none.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "wavelength_radii",
          "description": "Wavelength of the footprint noise's first octave, in crater radii.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.5,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "octaves",
          "description": "Octaves of both noises, from 1 to 12.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 4,
          "minimum": 1.0,
          "exclusive_minimum": false,
          "maximum": 12.0,
          "exclusive_maximum": false
        },
        {
          "name": "gain",
          "description": "Weight ratio between successive octaves; positive.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.5,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "rim_amplitude",
          "description": "Amplitude of the extra noise in the band around the rim, as a share of the crater diameter; 0 adds none.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "rim_wavelength_radii",
          "description": "Wavelength of the rim noise's first octave, in crater radii.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.1,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "rim_inner_radii",
          "description": "Inner edge of the rim noise band, in crater radii; below 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.8,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": true
        },
        {
          "name": "rim_outer_radii",
          "description": "Outer edge of the rim noise band, in crater radii; above 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.2,
          "minimum": 1.0,
          "exclusive_minimum": true
        },
        {
          "name": "seed",
          "description": "Varies the noise of every crater.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        }
      ]
    },
    "d21": {
      "kind": "object",
      "fields": [
        {
          "name": "wall_streaks",
          "description": "Amplitude of the radial gullies down a fresh crater's inner wall, as a share of its diameter; 0 adds none.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "wall_streak_width_radii",
          "description": "Width of the gullies across the wall, in crater radii.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.15,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "ejecta",
          "description": "Amplitude of the hummocky, radially lineated ejecta around a fresh crater, as a share of the ejecta's thickness (McGetchin et al. 1973); 0 adds none.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "ejecta_lineation_radii",
          "description": "Width of the ejecta's lineations across, in crater radii at the rim.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.15,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "mantling",
          "description": "Share of older relief buried under the ejecta at the rim, falling with their thickness, from 0 to 1; needs a datum.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "ejecta_reach_radii",
          "description": "How far ejecta texture and burial reach, in crater radii; above 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 3.0,
          "minimum": 1.0,
          "exclusive_minimum": true
        },
        {
          "name": "min_freshness",
          "description": "Freshness (depth over fresh depth) at or below which gullies and ejecta texture are worn away, from 0 to below 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.5,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": true
        },
        {
          "name": "seed",
          "description": "Varies the texture of every crater.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        }
      ]
    },
    "d22": {
      "kind": "object",
      "fields": [
        {
          "name": "enabled",
          "description": "Shapes craters asymmetrically along the slope of the ground beneath the layer; off keeps them the same on any slope.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": false
        },
        {
          "name": "seed",
          "description": "Varies how far each crater's floor is offset.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        },
        {
          "name": "floor_offset",
          "description": "How far the deepest point lies downslope of the centre, in diameters, drawn per crater; below 0.23.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "uniform",
            "a": 0.045,
            "b": 0.194,
            "min": null,
            "max": null
          }
        },
        {
          "name": "upslope_rim",
          "description": "Share of the raised rim and ejecta kept straight upslope, from 0 to 1; the rest returns toward the sides.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "full_slope",
          "description": "Slope at which the asymmetry is complete, in radians; it rises from none on level ground.",
          "unit": "rad",
          "schema": {
            "kind": "number"
          },
          "default": 0.08726646259971647,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "critical_gradient",
          "description": "Critical gradient Sc, rise over run, toward which downslope transport grows without bound: a crater on a regional gradient S wears 1 / (1 - (S / Sc)^2) times as fast (Roering et al. 1999). Unset wears craters alike on any slope; no lunar value is published.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "max_wear_rate",
          "description": "Fastest a slope makes craters wear, over level ground: a numerical cap as S nears Sc.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 10.0,
          "minimum": 1.0,
          "exclusive_minimum": false
        }
      ]
    },
    "d14": {
      "kind": "object",
      "fields": [
        {
          "name": "order",
          "description": "Order in which overlapping craters are applied; later craters overprint earlier ones.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "oldest_first",
              "largest_first"
            ],
            "descriptions": [
              "Oldest craters first, then larger first: the physical order, so younger craters overprint older ones.",
              "Largest craters first, then older first, so smaller craters overprint larger ones."
            ]
          },
          "default": "oldest_first"
        },
        {
          "name": "fade",
          "description": "How craters too small to resolve at the sample spacing fade out.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d15"
          },
          "default": {
            "start_samples": 2.0,
            "end_samples": 4.0,
            "shape": "smoothstep"
          }
        },
        {
          "name": "datum",
          "description": "Reference surface each crater's interior is cut relative to, fitted to the ground beneath it; none adds craters onto the terrain everywhere.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "none",
              "plane",
              "mean_height",
              "centre_height"
            ],
            "descriptions": [
              "No datum: the crater profile is added onto the terrain everywhere.",
              "Interior cut relative to a least-squares plane over the fit footprint, keeping regional slopes.",
              "Interior cut relative to a flat datum at the mean height over the fit footprint.",
              "Interior cut relative to a flat datum at the terrain height under the crater centre."
            ]
          },
          "default": "none"
        },
        {
          "name": "datum_fit_radii",
          "description": "Radius of the footprint the datum is fitted over, in crater radii.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "interior_replacement",
          "description": "Share of the interior replaced by datum plus profile, from 0 to 1: 1 erases older relief inside the crater, 0 keeps it.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "blend",
          "description": "Where and how a crater's replaced interior blends into the surrounding terrain.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d16"
          },
          "default": {
            "start_radii": 0.8,
            "end_radii": 1.2,
            "shape": "smootherstep"
          }
        },
        {
          "name": "irregularity",
          "description": "Irregular, non-circular crater outlines: which craters have them and how their shapes are drawn.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d17"
          },
          "default": {
            "enabled": false,
            "seed": 0,
            "min_diameter": 0.0,
            "max_diameter": null,
            "min_age_gyr": 0.0,
            "max_age_gyr": null,
            "manual": false,
            "rough_share": 1.0,
            "model": "power_law",
            "scatter": true,
            "max_deviation": 0.3,
            "roughness": {
              "kind": "uniform",
              "a": 0.01,
              "b": 0.03,
              "min": null,
              "max": null
            },
            "spectral_slope": {
              "kind": "constant",
              "a": 1.5,
              "b": 0.0,
              "min": null,
              "max": null
            },
            "min_harmonic": 2,
            "max_harmonic": 12,
            "elongated_share": 0.054,
            "ellipticity": {
              "kind": "uniform",
              "a": 1.1,
              "b": 1.5,
              "min": null,
              "max": null
            },
            "heading": null,
            "heading_spread": 0.0,
            "marks_share": 0.0,
            "marks_amplitude": {
              "kind": "uniform",
              "a": 0.0,
              "b": 0.005,
              "min": null,
              "max": null
            },
            "marks_knots": 45,
            "marks_inner_radii": 0.3,
            "marks_outer_radii": 0.9,
            "marks_fade_radii": 0.1
          }
        },
        {
          "name": "rim_smoothing",
          "description": "Rounded rims: each crater's profile smoothed across distance near its rim; off unless sigma_radii is set.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d19"
          },
          "default": {
            "sigma_radii": 0.0,
            "inner_radii": 0.8,
            "outer_radii": 1.2,
            "shape": "smootherstep",
            "strength": 1.0
          }
        },
        {
          "name": "noise",
          "description": "Fractal noise over each crater's footprint and around its rim, keyed to the crater; off unless an amplitude is set.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d20"
          },
          "default": {
            "amplitude": 0.0,
            "wavelength_radii": 0.5,
            "octaves": 4,
            "gain": 0.5,
            "rim_amplitude": 0.0,
            "rim_wavelength_radii": 0.1,
            "rim_inner_radii": 0.8,
            "rim_outer_radii": 1.2,
            "seed": 0
          }
        },
        {
          "name": "texture",
          "description": "Gullies down fresh walls, textured ejecta and older relief buried under the ejecta; off unless an amplitude or mantling is set.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d21"
          },
          "default": {
            "wall_streaks": 0.0,
            "wall_streak_width_radii": 0.15,
            "ejecta": 0.0,
            "ejecta_lineation_radii": 0.15,
            "mantling": 0.0,
            "ejecta_reach_radii": 3.0,
            "min_freshness": 0.5,
            "seed": 0
          }
        },
        {
          "name": "slope",
          "description": "Craters on sloping ground with floors offset downslope and rims lowered upslope; needs the plane datum.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d22"
          },
          "default": {
            "enabled": false,
            "seed": 0,
            "floor_offset": {
              "kind": "uniform",
              "a": 0.045,
              "b": 0.194,
              "min": null,
              "max": null
            },
            "upslope_rim": 0.0,
            "full_slope": 0.08726646259971647,
            "critical_gradient": null,
            "max_wear_rate": 10.0
          }
        }
      ]
    },
    "d24": {
      "kind": "object",
      "fields": [
        {
          "name": "path",
          "description": "GeoTIFF read in the surface's coordinates, relative to the configuration's folder: metres on a plane, longitude and latitude in degrees on a sphere. Empty uses value.",
          "unit": "",
          "schema": {
            "kind": "string"
          },
          "default": ""
        },
        {
          "name": "value",
          "description": "The field everywhere when no path is given.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0
        },
        {
          "name": "band",
          "description": "Band of the GeoTIFF read, from 0.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        },
        {
          "name": "method",
          "description": "How the GeoTIFF is interpolated: nearest or bilinear, which stay within the cells read.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "nearest",
              "bilinear",
              "cubic"
            ],
            "descriptions": [
              "The value of the nearest cell centre: blocky, but never mixes values.",
              "Linear in each axis over the four surrounding cells.",
              "Keys cubic convolution over the sixteen surrounding cells: the smoothest, for upscaling DEMs."
            ]
          },
          "default": "bilinear"
        },
        {
          "name": "scale",
          "description": "Multiplies every cell, such as 0.001 for a map stored in thousandths; positive.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "fallback",
          "description": "Value outside the GeoTIFF and where its cells are no-data or NaN; unset leaves none, and the layer then keeps its own setting there.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null
        },
        {
          "name": "periodic_longitude",
          "description": "The GeoTIFF's x is longitude repeating every 360 degrees, so a map from 0 to 360 serves -180 to 180.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": false
        }
      ]
    },
    "d23": {
      "kind": "object",
      "fields": [
        {
          "name": "field",
          "description": "The map.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d24"
          },
          "default": {
            "path": "",
            "value": 0.0,
            "band": 0,
            "method": "bilinear",
            "scale": 1.0,
            "fallback": null,
            "periodic_longitude": false
          }
        },
        {
          "name": "measure",
          "description": "What the map's values measure.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "scale",
              "count",
              "areal_fraction"
            ],
            "descriptions": [
              "The local density over the layer's own; 1 keeps it as the size distribution gives it.",
              "Features with diameters in the map's range per area unit, such as boulders per km^2.",
              "Share of the ground covered by features in the map's range, such as rock abundance."
            ]
          },
          "default": "scale"
        },
        {
          "name": "min_diameter",
          "description": "Smallest diameter the map measures, in metres; positive for a count or areal fraction.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.0
        },
        {
          "name": "max_diameter",
          "description": "Largest diameter the map measures, in metres, exclusive; unset for no limit.",
          "unit": "m",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null
        },
        {
          "name": "area_unit",
          "description": "Square metres per area unit of a count: 1 for per m^2, 1e6 for per km^2.",
          "unit": "m^2",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "total",
          "description": "The map counts every feature of its kind, including the secondaries thrown from a crater layer's craters and the boulders a layer throws out around craters, which are taken out of it first; off when it counts only what the layer generates.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": true
        }
      ]
    },
    "d25": {
      "kind": "choice",
      "alternatives": [
        {
          "type": "golombek_rapp",
          "description": "Golombek and Rapp boulder sizes, set by the fraction of ground the boulders cover and the layer's qa and qb.",
          "fields": [],
          "default": {
            "type": "golombek_rapp"
          }
        },
        {
          "type": "sp8023_intercrater",
          "description": "Blocks between craters from NASA SP-8023, the lunar surface design model (Figure 7).",
          "fields": [
            {
              "name": "curve",
              "description": "Which of the model's minimum, nominal and maximum curves to use, from fewest to most boulders.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "minimum",
                  "nominal",
                  "maximum"
                ],
                "descriptions": [
                  "The model's minimum curve: the fewest boulders.",
                  "The model's nominal curve.",
                  "The model's maximum curve: the most boulders."
                ]
              },
              "default": "nominal"
            }
          ],
          "default": {
            "type": "sp8023_intercrater",
            "curve": "nominal"
          }
        },
        {
          "type": "sp8023_crater",
          "description": "Blocks around blocky craters from NASA SP-8023 (Figure 9), for the ejecta of craters that reached bedrock.",
          "fields": [
            {
              "name": "curve",
              "description": "Which of the model's minimum, nominal and maximum curves to use, from fewest to most boulders.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "minimum",
                  "nominal",
                  "maximum"
                ],
                "descriptions": [
                  "The model's minimum curve: the fewest boulders.",
                  "The model's nominal curve.",
                  "The model's maximum curve: the most boulders."
                ]
              },
              "default": "nominal"
            }
          ],
          "default": {
            "type": "sp8023_crater",
            "curve": "nominal"
          }
        },
        {
          "type": "synthterrain",
          "description": "One of the power-law boulder distributions synthterrain offers, for comparison with it.",
          "fields": [
            {
              "name": "model",
              "description": "Which of synthterrain's power-law boulder distributions to use.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "intercrater",
                  "haworth",
                  "viper_specification"
                ],
                "descriptions": [
                  "0.0001 D^-1.75457 per m^2 with D in metres: synthetic_moon's \"low blockiness\".",
                  "0.002 D^-2.6607 per m^2 with D in metres: synthetic_moon's \"high blockiness\".",
                  "0.0003 D^-2.482 per m^2 with D in metres: the VIPER Environmental Specification."
                ]
              },
              "default": "intercrater"
            }
          ],
          "default": {
            "type": "synthterrain",
            "model": "intercrater"
          }
        },
        {
          "type": "power_law",
          "description": "A cumulative power law, N(>=D) = coefficient D^-exponent per m^2 with D in metres.",
          "fields": [
            {
              "name": "coefficient",
              "description": "Coefficient of N(>=D) = coefficient D^-exponent, the cumulative count per m^2 with D in metres; scales how many there are.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.1,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "exponent",
              "description": "Exponent of the power law; larger values give relatively more small craters or boulders.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 2.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            }
          ],
          "default": {
            "type": "power_law",
            "coefficient": 0.1,
            "exponent": 2.0
          }
        },
        {
          "type": "piecewise_power_law",
          "description": "A cumulative distribution made of power-law segments over diameter ranges.",
          "fields": [
            {
              "name": "segments",
              "description": "Power-law segments in strictly increasing order of start, each running to the next one's start; they must meet at their joins.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "ref",
                  "ref": "d5"
                },
                "default": {
                  "start": 0.0,
                  "coefficient": 1.0,
                  "exponent": 2.0
                }
              },
              "default": [
                {
                  "start": 0.0,
                  "coefficient": 1.0,
                  "exponent": 2.0
                }
              ]
            }
          ],
          "default": {
            "type": "piecewise_power_law",
            "segments": [
              {
                "start": 0.0,
                "coefficient": 1.0,
                "exponent": 2.0
              }
            ]
          }
        },
        {
          "type": "tabulated",
          "description": "A cumulative distribution from a table of diameters and counts N(>=D), in units you choose.",
          "fields": [
            {
              "name": "diameters",
              "description": "Table diameters in diameter units, at least two, positive and strictly increasing; counts are interpolated linearly in log D and log N between them.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": [],
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "cumulative",
              "description": "Cumulative count N(>=D) at each diameter, per area unit; positive and not increasing.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": [],
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "diameter_unit",
              "description": "Metres per table diameter unit: 1 for metres, 1000 for km.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "area_unit",
              "description": "Square metres per table area unit: 1 for m^2, 1e6 for km^2.",
              "unit": "m^2",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            }
          ],
          "default": {
            "type": "tabulated",
            "diameters": [],
            "cumulative": [],
            "diameter_unit": 1.0,
            "area_unit": 1.0
          }
        },
        {
          "type": "piecewise_uniform",
          "description": "Counts per m^2 in diameter bands, each with diameters spread uniformly across it; none outside the bands.",
          "fields": [
            {
              "name": "bands",
              "description": "Diameter bands with their counts; overlapping bands add, and gaps between them hold none.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "ref",
                  "ref": "d6"
                },
                "default": {
                  "min": 1.0,
                  "max": 2.0,
                  "density": 0.01
                }
              },
              "default": [
                {
                  "min": 1.0,
                  "max": 2.0,
                  "density": 0.01
                }
              ]
            },
            {
              "name": "total",
              "description": "Count per m^2 of all bands together, shared in proportion to each band's density; 0 uses the densities as given.",
              "unit": "1/m^2",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            }
          ],
          "default": {
            "type": "piecewise_uniform",
            "bands": [
              {
                "min": 1.0,
                "max": 2.0,
                "density": 0.01
              }
            ],
            "total": 0.0
          }
        }
      ]
    },
    "d26": {
      "kind": "object",
      "fields": [
        {
          "name": "spread",
          "description": "Boulder abundance varies from 1 / spread to spread times its mean, at least 1; 1 is the same everywhere.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 1.0,
          "exclusive_minimum": false
        },
        {
          "name": "size",
          "description": "Typical width of a patch of richer or poorer boulder cover, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 200.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        }
      ]
    },
    "d27": {
      "kind": "object",
      "fields": [
        {
          "name": "share",
          "description": "Share of the boulders between craters gathered in clusters, from 0 to 1; 0 leaves them scattered.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "spacing",
          "description": "Typical distance between cluster centres, in metres; with thomas, one centre per spacing squared on average.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 50.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "radius",
          "description": "Gaussian radius of a cluster, in metres; below the spacing with nearest, at most twice it with thomas.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 5.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "model",
          "description": "How cluster centres are laid out and their clusters combine.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "nearest",
              "thomas"
            ],
            "descriptions": [
              "One centre per cell of a jittered lattice, each point weighted by its nearest centre only.",
              "A Thomas cluster process: Poisson-scattered centres whose Gaussian clusters add where they overlap."
            ]
          },
          "default": "nearest"
        }
      ]
    },
    "d28": {
      "kind": "object",
      "fields": [
        {
          "name": "min_crater_diameter",
          "description": "Smallest crater, in metres, that throws blocks out; 0 with no regolith thickness disables crater blocks.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "regolith_thickness",
          "description": "Regolith thickness in metres: craters smaller than it over the excavation depth ratio dig no boulder and throw no blocks. Unset ignores the regolith.",
          "unit": "m",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "excavation_depth_ratio",
          "description": "Depth of excavation over crater diameter, in (0, 1]; with the regolith thickness it sets the smallest crater that throws blocks.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.1,
          "minimum": 0.0,
          "exclusive_minimum": true,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "coverage",
          "description": "Golombek-Rapp k, the fraction of ground covered by blocks at the rim of a fresh crater, between 0 and 1; used with golombek_rapp ejecta sizes.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.1,
          "minimum": 0.0,
          "exclusive_minimum": true,
          "maximum": 1.0,
          "exclusive_maximum": true
        },
        {
          "name": "profile",
          "description": "How the share of a crater's blocks falls off with distance from its centre.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "smoothstep",
              "exponential"
            ],
            "descriptions": [
              "Every block inside the rim, falling along a smoothstep to none at the reach.",
              "Exponential decay outside the rim, a fixed share on the floor and none beyond the reach: synthterrain's crater probability map."
            ]
          },
          "default": "smoothstep"
        },
        {
          "name": "reach",
          "description": "Distance from the crater's centre, in crater radii, beyond which it adds no blocks; over 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 3.0,
          "minimum": 1.0,
          "exclusive_minimum": true
        },
        {
          "name": "decay_radii",
          "description": "With the exponential profile, the e-folding distance of the blocks outside the rim, in crater radii.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.7,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "floor_share",
          "description": "With the exponential profile, the crater floor's share of the rim's blocks, from 0 to 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.05,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "aging",
          "description": "How a crater's blocks wear away with time, so that few are left around old craters.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "freshness",
              "age"
            ],
            "descriptions": [
              "Blocks wear away with the crater's freshness (current over fresh depth): all when fresh, none at or below the minimum freshness.",
              "Blocks wear away with the crater's age as (1 - age / lifetime)^exponent, synthterrain's form."
            ]
          },
          "default": "freshness"
        },
        {
          "name": "min_freshness",
          "description": "With freshness aging, the freshness (current over fresh depth) at or below which a crater keeps no blocks; from 0 to below 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.7,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": true
        },
        {
          "name": "lifetime_gyr",
          "description": "With age aging, the crater age in Gyr at which a crater keeps no blocks.",
          "unit": "Gyr",
          "schema": {
            "kind": "number"
          },
          "default": 4.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "aging_exponent",
          "description": "With age aging, the exponent of (1 - age / lifetime); higher values strip blocks from craters sooner.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 3.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "gravity",
          "description": "Surface gravity in m/s^2: with the regolith thickness, it limits how far blocks are thrown, after Bart and Melosh (2010). Unset applies no such limit.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null,
          "minimum": 0.0,
          "exclusive_minimum": true
        }
      ]
    },
    "d29": {
      "kind": "object",
      "fields": [
        {
          "name": "reach",
          "description": "Distance in metres around a point at which its surroundings are read, to tell rises from lows.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 12.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "rise_soil",
          "description": "Height above the surroundings, as a share of the reach, at or below which the ground is soil.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.01
        },
        {
          "name": "rise_boulder",
          "description": "Height above the surroundings, as a share of the reach, at or above which the ground is bedrock; above the soil threshold.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.035
        },
        {
          "name": "slope_soil",
          "description": "Slope, as rise over run, at or under which soil holds.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.2
        },
        {
          "name": "slope_boulder",
          "description": "Slope, as rise over run, at or over which no soil holds and the ground is bedrock; above the soil threshold.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.4
        },
        {
          "name": "floor_cover",
          "description": "Share of level ground that is bedrock too, in noise patches, as on a swept lava floor; from 0 to below 1, and 0 for none.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": true
        },
        {
          "name": "floor_patch",
          "description": "Width of the bedrock patches on level ground, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 60.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "seed",
          "description": "Seed of the bedrock patches on level ground.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        }
      ]
    },
    "d30": {
      "kind": "object",
      "fields": [
        {
          "name": "height_share",
          "description": "Height of the regolith piled against a boulder, as a share of its exposed height, from 0 to 1; 0 draws no fillets.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "width_ratio",
          "description": "How far the fillet reaches beyond the boulder's edge, over its diameter; it falls to nothing there.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.3,
          "minimum": 0.0,
          "exclusive_minimum": true
        }
      ]
    },
    "d31": {
      "kind": "object",
      "fields": [
        {
          "name": "share",
          "description": "Share of boulders with a windward facet planed by sand-laden wind, from 0 to 1; 0 for none. Gale crater: 0.39 (Bridges et al. 2014).",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "wind_azimuth",
          "description": "Where the abrading wind blows toward, in radians counter-clockwise from east; facets face the other way.",
          "unit": "rad",
          "schema": {
            "kind": "number"
          },
          "default": 0.0
        },
        {
          "name": "min_angle",
          "description": "Gentlest facet slope from horizontal, in radians; 50 to 60 deg on basalt (Laity and Bridges 2009).",
          "unit": "rad",
          "schema": {
            "kind": "number"
          },
          "default": 0.8726646259971648,
          "minimum": 0.0,
          "exclusive_minimum": true,
          "maximum": 1.5707963267948966,
          "exclusive_maximum": true
        },
        {
          "name": "max_angle",
          "description": "Steepest facet slope from horizontal, in radians.",
          "unit": "rad",
          "schema": {
            "kind": "number"
          },
          "default": 1.0471975511965976,
          "minimum": 0.0,
          "exclusive_minimum": true,
          "maximum": 1.5707963267948966,
          "exclusive_maximum": true
        },
        {
          "name": "second_wind_azimuth",
          "description": "A second abrading wind, where it blows toward, in radians; some faceted boulders get a second facet facing it and a keel between. Unset for none.",
          "unit": "rad",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null
        },
        {
          "name": "keel_share",
          "description": "Share of faceted boulders with the second facet, from 0 to 1. Gale crater: 12 of 39 (Bridges et al. 2014).",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        }
      ]
    },
    "d32": {
      "kind": "object",
      "fields": [
        {
          "name": "min_diameter",
          "description": "Smallest boulder that breaks, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "split_wear",
          "description": "Wear from 0 (fresh) to 1 from which boulders split into pieces that still fit; 1 breaks nothing.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "rubble_wear",
          "description": "Wear from which the pieces scatter as rubble, turn and sink; at least split_wear.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "min_pieces",
          "description": "Fewest pieces a boulder breaks into, at least 2.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 2,
          "minimum": 2.0,
          "exclusive_minimum": false,
          "maximum": 12.0,
          "exclusive_maximum": false
        },
        {
          "name": "max_pieces",
          "description": "Most pieces a boulder breaks into, at most 12.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 5,
          "minimum": 2.0,
          "exclusive_minimum": false,
          "maximum": 12.0,
          "exclusive_maximum": false
        },
        {
          "name": "gap_ratio",
          "description": "Widest crack between split pieces, as a share of the boulder's diameter.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.04,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "spread_ratio",
          "description": "How far rubble scatters beyond the cracks, as a share of the boulder's diameter.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.6,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "slab_share",
          "description": "Share of broken boulders split by roughly parallel cracks right through them; the rest crack out from the middle.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.7,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        }
      ]
    },
    "d33": {
      "kind": "object",
      "fields": [
        {
          "name": "min_diameter",
          "description": "Boulders at least this many metres across become 3D models; unset applies no diameter threshold.",
          "unit": "m",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "min_samples",
          "description": "Boulders spanning at least this many samples at the spacing evaluated become 3D models, so finer levels of detail make more of them; unset applies no such threshold.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "max_diameter",
          "description": "Boulders this many metres across or wider are not models, keeping a band of sizes as models; unset applies no upper limit.",
          "unit": "m",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "max_samples",
          "description": "Boulders spanning this many samples or more are not models; unset applies no such limit.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null,
          "minimum": 0.0,
          "exclusive_minimum": true
        }
      ]
    },
    "d34": {
      "kind": "object",
      "fields": [
        {
          "name": "min_diameter",
          "description": "Smallest boulder drawn into the heights, in metres; smaller ones stay in the lists only, for the renderer's surface detail.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "max_diameter",
          "description": "Boulders this many metres across or wider are not drawn into the heights; unset applies no upper limit.",
          "unit": "m",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "models",
          "description": "Draws the 3D model boulders into the heights as well, as a stand-in for far views.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": false
        }
      ]
    },
    "d37": {
      "kind": "object",
      "fields": [
        {
          "name": "min",
          "description": "Lower end of the interval the value is drawn uniformly from.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0
        },
        {
          "name": "max",
          "description": "Upper end of the interval the value is drawn uniformly from.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0
        }
      ]
    },
    "d36": {
      "kind": "object",
      "fields": [
        {
          "name": "name",
          "description": "Label of the style, for reference; it does not change the shapes.",
          "unit": "",
          "schema": {
            "kind": "string"
          },
          "default": ""
        },
        {
          "name": "weight",
          "description": "Relative share of boulders given this style, not negative; the styles' weights must not all be 0.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "solid",
          "description": "Solid the shape starts from, before it is stretched, rounded, roughened and fractured.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "icosahedron",
              "cube",
              "pyramid",
              "prism",
              "tetrahedron"
            ],
            "descriptions": [
              "Boulders start from an icosahedron, twenty triangles on the unit sphere: rounder shapes.",
              "Boulders start from a cube: blocky shapes.",
              "Boulders start from a square-based pyramid.",
              "Boulders start from a triangular prism, a wedge.",
              "Boulders start from a regular tetrahedron: angular shapes."
            ]
          },
          "default": "icosahedron"
        },
        {
          "name": "intermediate",
          "description": "Range of the intermediate axis over the long one, b / a, within (0, 1]; lower values give more elongated boulders.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d37"
          },
          "default": {
            "min": 0.6,
            "max": 0.85
          }
        },
        {
          "name": "short_axis",
          "description": "Range of the short, vertical axis over the long one, c / a, within (0, 1] and at most the intermediate ratio; lower values give flatter boulders.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d37"
          },
          "default": {
            "min": 0.4,
            "max": 0.6
          }
        },
        {
          "name": "rounding",
          "description": "Range of the share, from 0 to 1, by which the shape is rounded toward the ellipsoid of its axes: 0 keeps the solid's edges and corners, 1 is the ellipsoid.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d37"
          },
          "default": {
            "min": 0.0,
            "max": 0.0
          }
        },
        {
          "name": "min_fractures",
          "description": "Fewest flat fracture planes cutting a boulder, from 0; each boulder's count is drawn between the two.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 64.0,
          "exclusive_maximum": false
        },
        {
          "name": "max_fractures",
          "description": "Most flat fracture planes cutting a boulder, at most 64 and at least the fewest.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 64.0,
          "exclusive_maximum": false
        },
        {
          "name": "fracture_depth",
          "description": "Range of where each fracture plane lies, as a share of the shape's reach along its normal, within (0, 1]; lower values cut more away.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d37"
          },
          "default": {
            "min": 0.6,
            "max": 0.9
          }
        },
        {
          "name": "max_fracture_tilt",
          "description": "Largest vertical component of a fracture plane's unit normal, from 0 to 1: 0 keeps normals horizontal, cutting a slab about its rim only.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "noise_amplitude",
          "description": "Largest relative change of the radius by the roughening noise, in [0, 1); 0 leaves the surface unroughened.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.05,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": true
        },
        {
          "name": "noise_wavelength",
          "description": "Wavelength of the roughening noise's first octave, in long-axis lengths; positive, with smaller values giving finer bumps.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.6,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "noise_octaves",
          "description": "Octaves of the roughening noise, 1 to 12, each halving in wavelength; more add finer detail.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 3,
          "minimum": 1.0,
          "exclusive_minimum": false,
          "maximum": 12.0,
          "exclusive_maximum": false
        },
        {
          "name": "edge_softness",
          "description": "Range of how far edges and corners are worn back where faces meet, as weathering rounds them, in long-axis lengths from 0 to 0.5; 0 keeps them sharp.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d37"
          },
          "default": {
            "min": 0.0,
            "max": 0.0
          }
        },
        {
          "name": "face_roughness",
          "description": "How far fracture faces undulate, as a share of each plane's offset from 0 to 0.5; 0 keeps them flat.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 0.5,
          "exclusive_maximum": false
        }
      ]
    },
    "d35": {
      "kind": "object",
      "fields": [
        {
          "name": "styles",
          "description": "Kinds of boulder each shape is drawn from, picked by weight; at least one.",
          "unit": "",
          "schema": {
            "kind": "array",
            "of": {
              "kind": "ref",
              "ref": "d36"
            },
            "default": {
              "name": "",
              "weight": 1.0,
              "solid": "icosahedron",
              "intermediate": {
                "min": 0.6,
                "max": 0.85
              },
              "short_axis": {
                "min": 0.4,
                "max": 0.6
              },
              "rounding": {
                "min": 0.0,
                "max": 0.0
              },
              "min_fractures": 0,
              "max_fractures": 0,
              "fracture_depth": {
                "min": 0.6,
                "max": 0.9
              },
              "max_fracture_tilt": 1.0,
              "noise_amplitude": 0.05,
              "noise_wavelength": 0.6,
              "noise_octaves": 3,
              "edge_softness": {
                "min": 0.0,
                "max": 0.0
              },
              "face_roughness": 0.0
            }
          },
          "default": [
            {
              "name": "angular",
              "weight": 0.2,
              "solid": "icosahedron",
              "intermediate": {
                "min": 0.6,
                "max": 0.9
              },
              "short_axis": {
                "min": 0.45,
                "max": 0.7
              },
              "rounding": {
                "min": 0.0,
                "max": 0.0
              },
              "min_fractures": 7,
              "max_fractures": 12,
              "fracture_depth": {
                "min": 0.55,
                "max": 0.85
              },
              "max_fracture_tilt": 1.0,
              "noise_amplitude": 0.06,
              "noise_wavelength": 0.9,
              "noise_octaves": 4,
              "edge_softness": {
                "min": 0.02,
                "max": 0.06
              },
              "face_roughness": 0.03
            },
            {
              "name": "platy",
              "weight": 0.12,
              "solid": "icosahedron",
              "intermediate": {
                "min": 0.6,
                "max": 0.9
              },
              "short_axis": {
                "min": 0.22,
                "max": 0.38
              },
              "rounding": {
                "min": 0.0,
                "max": 0.0
              },
              "min_fractures": 5,
              "max_fractures": 9,
              "fracture_depth": {
                "min": 0.6,
                "max": 0.88
              },
              "max_fracture_tilt": 0.7,
              "noise_amplitude": 0.05,
              "noise_wavelength": 0.9,
              "noise_octaves": 4,
              "edge_softness": {
                "min": 0.02,
                "max": 0.05
              },
              "face_roughness": 0.03
            },
            {
              "name": "subrounded",
              "weight": 0.15,
              "solid": "icosahedron",
              "intermediate": {
                "min": 0.65,
                "max": 0.9
              },
              "short_axis": {
                "min": 0.45,
                "max": 0.7
              },
              "rounding": {
                "min": 0.0,
                "max": 0.0
              },
              "min_fractures": 4,
              "max_fractures": 7,
              "fracture_depth": {
                "min": 0.65,
                "max": 0.9
              },
              "max_fracture_tilt": 1.0,
              "noise_amplitude": 0.07,
              "noise_wavelength": 0.8,
              "noise_octaves": 4,
              "edge_softness": {
                "min": 0.06,
                "max": 0.12
              },
              "face_roughness": 0.02
            },
            {
              "name": "rounded",
              "weight": 0.1,
              "solid": "icosahedron",
              "intermediate": {
                "min": 0.7,
                "max": 0.95
              },
              "short_axis": {
                "min": 0.5,
                "max": 0.75
              },
              "rounding": {
                "min": 0.0,
                "max": 0.0
              },
              "min_fractures": 0,
              "max_fractures": 3,
              "fracture_depth": {
                "min": 0.75,
                "max": 0.95
              },
              "max_fracture_tilt": 1.0,
              "noise_amplitude": 0.1,
              "noise_wavelength": 0.7,
              "noise_octaves": 4,
              "edge_softness": {
                "min": 0.1,
                "max": 0.18
              },
              "face_roughness": 0.02
            },
            {
              "name": "block",
              "weight": 0.13,
              "solid": "cube",
              "intermediate": {
                "min": 0.6,
                "max": 0.85
              },
              "short_axis": {
                "min": 0.4,
                "max": 0.6
              },
              "rounding": {
                "min": 0.0,
                "max": 0.15
              },
              "min_fractures": 3,
              "max_fractures": 7,
              "fracture_depth": {
                "min": 0.6,
                "max": 0.85
              },
              "max_fracture_tilt": 1.0,
              "noise_amplitude": 0.07,
              "noise_wavelength": 0.8,
              "noise_octaves": 4,
              "edge_softness": {
                "min": 0.06,
                "max": 0.12
              },
              "face_roughness": 0.06
            },
            {
              "name": "wedge",
              "weight": 0.1,
              "solid": "prism",
              "intermediate": {
                "min": 0.55,
                "max": 0.85
              },
              "short_axis": {
                "min": 0.4,
                "max": 0.6
              },
              "rounding": {
                "min": 0.0,
                "max": 0.2
              },
              "min_fractures": 2,
              "max_fractures": 5,
              "fracture_depth": {
                "min": 0.65,
                "max": 0.9
              },
              "max_fracture_tilt": 1.0,
              "noise_amplitude": 0.07,
              "noise_wavelength": 0.8,
              "noise_octaves": 4,
              "edge_softness": {
                "min": 0.06,
                "max": 0.12
              },
              "face_roughness": 0.06
            },
            {
              "name": "pyramid",
              "weight": 0.1,
              "solid": "pyramid",
              "intermediate": {
                "min": 0.7,
                "max": 0.95
              },
              "short_axis": {
                "min": 0.45,
                "max": 0.7
              },
              "rounding": {
                "min": 0.0,
                "max": 0.2
              },
              "min_fractures": 2,
              "max_fractures": 4,
              "fracture_depth": {
                "min": 0.7,
                "max": 0.92
              },
              "max_fracture_tilt": 1.0,
              "noise_amplitude": 0.07,
              "noise_wavelength": 0.8,
              "noise_octaves": 4,
              "edge_softness": {
                "min": 0.06,
                "max": 0.12
              },
              "face_roughness": 0.06
            },
            {
              "name": "shard",
              "weight": 0.05,
              "solid": "tetrahedron",
              "intermediate": {
                "min": 0.6,
                "max": 0.9
              },
              "short_axis": {
                "min": 0.4,
                "max": 0.6
              },
              "rounding": {
                "min": 0.0,
                "max": 0.2
              },
              "min_fractures": 2,
              "max_fractures": 4,
              "fracture_depth": {
                "min": 0.7,
                "max": 0.92
              },
              "max_fracture_tilt": 1.0,
              "noise_amplitude": 0.04,
              "noise_wavelength": 0.8,
              "noise_octaves": 4,
              "edge_softness": {
                "min": 0.02,
                "max": 0.05
              },
              "face_roughness": 0.03
            },
            {
              "name": "sphere",
              "weight": 0.05,
              "solid": "icosahedron",
              "intermediate": {
                "min": 0.85,
                "max": 1.0
              },
              "short_axis": {
                "min": 0.7,
                "max": 0.9
              },
              "rounding": {
                "min": 0.0,
                "max": 0.0
              },
              "min_fractures": 0,
              "max_fractures": 1,
              "fracture_depth": {
                "min": 0.8,
                "max": 0.95
              },
              "max_fracture_tilt": 1.0,
              "noise_amplitude": 0.08,
              "noise_wavelength": 0.7,
              "noise_octaves": 4,
              "edge_softness": {
                "min": 0.12,
                "max": 0.2
              },
              "face_roughness": 0.02
            }
          ]
        },
        {
          "name": "subdivisions",
          "description": "Times the solid's triangles are split in four, 0 to 6; more give finer, smoother shapes with more triangles.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 3,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 6.0,
          "exclusive_maximum": false
        },
        {
          "name": "weathering",
          "description": "Scales every style's edge softness: 0 gives sharp edges, 1 the styles' own, more is more worn.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "seed",
          "description": "Seed the shapes are drawn with, along with each shape's own seed; changing it reshapes every boulder.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        }
      ]
    },
    "d38": {
      "kind": "object",
      "fields": [
        {
          "name": "field",
          "description": "The map.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d24"
          },
          "default": {
            "path": "",
            "value": 0.0,
            "band": 0,
            "method": "bilinear",
            "scale": 1.0,
            "fallback": null,
            "periodic_longitude": false
          }
        },
        {
          "name": "measure",
          "description": "What the map's values measure.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "exponent",
              "mean_diameter"
            ],
            "descriptions": [
              "The cumulative exponent alpha, counts falling as D^-alpha.",
              "The mean diameter in metres of the features from the reference diameter up, from which alpha = mean / (mean - D0)."
            ]
          },
          "default": "exponent"
        },
        {
          "name": "reference_diameter",
          "description": "Diameter D0 in metres where the local power law meets the layer's own count, as N(>=D) = N(>=D0) (D / D0)^-alpha; for a mean diameter map, the smallest diameter averaged.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "min_exponent",
          "description": "Smallest exponent alpha the map's values are clamped to; with the largest it bounds the boulders drawn, so generous bounds draw more to thin.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "max_exponent",
          "description": "Largest exponent alpha the map's values are clamped to; above the smallest.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 6.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        }
      ]
    },
    "d39": {
      "kind": "choice",
      "alternatives": [
        {
          "type": "rectangle",
          "description": "An axis-aligned rectangle in the surface's coordinates.",
          "fields": [
            {
              "name": "min_x",
              "description": "Lower edge along x in the surface's coordinates; the longitude in degrees on a sphere.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "min_y",
              "description": "Lower edge along y in the surface's coordinates; the latitude in degrees on a sphere.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "max_x",
              "description": "Upper edge along x in the surface's coordinates; the longitude in degrees on a sphere.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "max_y",
              "description": "Upper edge along y in the surface's coordinates; the latitude in degrees on a sphere.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            }
          ],
          "default": {
            "type": "rectangle",
            "min_x": 0.0,
            "min_y": 0.0,
            "max_x": 0.0,
            "max_y": 0.0
          }
        },
        {
          "type": "circle",
          "description": "A circle in the surface's coordinates, its radius in metres.",
          "fields": [
            {
              "name": "x",
              "description": "Centre along x in the surface's coordinates; the longitude in degrees on a sphere.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "y",
              "description": "Centre along y in the surface's coordinates; the latitude in degrees on a sphere.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "radius",
              "description": "Radius of the circle in metres, also on a sphere.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            }
          ],
          "default": {
            "type": "circle",
            "x": 0.0,
            "y": 0.0,
            "radius": 0.0
          }
        }
      ]
    },
    "d41": {
      "kind": "object",
      "fields": [
        {
          "name": "seed",
          "description": "Seed of the rays' directions; layers with the same layout share the same rays.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        },
        {
          "name": "count",
          "description": "Number of rays of a crater, drawn per crater and rounded; 0 to 64.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "normal",
            "a": 10.7,
            "b": 3.1,
            "min": 6.0,
            "max": 20.0
          }
        },
        {
          "name": "width_degrees",
          "description": "Angle in degrees a ray spans 2 radii from the centre, drawn per ray, within (0, 180).",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "normal",
            "a": 22.0,
            "b": 8.3,
            "min": 5.4,
            "max": 38.6
          }
        }
      ]
    },
    "d40": {
      "kind": "object",
      "fields": [
        {
          "name": "enabled",
          "description": "Gathers secondaries into their primary's rays and clumps them along each ray, as radial chains and clusters; off spreads them evenly.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": false
        },
        {
          "name": "layout",
          "description": "The rays; give a crater albedo layer's rays the same layout for bright rays over the secondaries.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d41"
          },
          "default": {
            "seed": 0,
            "count": {
              "kind": "normal",
              "a": 10.7,
              "b": 3.1,
              "min": 6.0,
              "max": 20.0
            },
            "width_degrees": {
              "kind": "normal",
              "a": 22.0,
              "b": 8.3,
              "min": 5.4,
              "max": 38.6
            }
          }
        },
        {
          "name": "share",
          "description": "Share of secondaries in rays, from 0 to 1; the rest stay spread evenly. Illustrative.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.7,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "min_half_angle_degrees",
          "description": "Narrowest half width of a ray, in degrees from 0 to 90 excluded, so rays widen with range beyond their width near the primary. Illustrative.",
          "unit": "deg",
          "schema": {
            "kind": "number"
          },
          "default": 2.0,
          "minimum": 0.0,
          "exclusive_minimum": true,
          "maximum": 90.0,
          "exclusive_maximum": true
        },
        {
          "name": "clustering",
          "description": "How strongly secondaries clump along a ray, from 0 for evenly along it to 1 for only in clumps. Illustrative.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.8,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "cluster_spacing",
          "description": "Typical spacing of clumps along a ray, in natural log of range; positive, smaller values give shorter, more frequent clumps. Illustrative.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.15,
          "minimum": 0.0,
          "exclusive_minimum": true
        }
      ]
    },
    "d42": {
      "kind": "object",
      "fields": [
        {
          "name": "elongated_share",
          "description": "Share of secondaries, from 0 to 1, stretched along the line back to their primary; 0 keeps them round.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "ellipticity",
          "description": "Long over short axis of an elongated secondary near the primary, drawn per secondary; at least 1, falling to 1 at the outer range.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "uniform",
            "a": 1.2,
            "b": 1.8,
            "min": null,
            "max": null
          }
        }
      ]
    },
    "d43": {
      "kind": "object",
      "fields": [
        {
          "name": "wavelength",
          "description": "Crest-to-crest spacing of the ripples on flat sand, in metres; 0 gives no ripples.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "height",
          "description": "Trough-to-crest height of the ripples on flat sand, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "lee_fraction",
          "description": "Share of a ripple wavelength the lee face takes, in (0, 1): 0.5 is symmetric, lower values give a steeper lee face.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.5,
          "minimum": 0.0,
          "exclusive_minimum": true,
          "maximum": 1.0,
          "exclusive_maximum": true
        },
        {
          "name": "sinuosity",
          "description": "How far a ripple crest wanders along its length, in wavelengths.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.3,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "slope_coupling",
          "description": "How strongly the dune's slope turns and tightens the ripples: they shorten on steep lee faces and turn on the flanks; 0 keeps them straight across the wind.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "interdune_cover",
          "description": "Share of the ripple height kept on the ground between dunes, from 0 to 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "defect_density",
          "description": "Forked crests (Y-junctions): pairs of crest ends per metre of crest, as measured on dune fields (Ewing et al. 2010); 0 for none. Mars large ripples: 0.099.",
          "unit": "1/m",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "flank_straightening",
          "description": "How far crests straighten off the stoss, from 0 to 1: 1 keeps the sinuosity on flat sand and stoss slopes and takes it away on flanks and lee slopes, as Martian large ripples do.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "fade",
          "description": "How ripples too fine for the sample spacing fade out, by samples per wavelength.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d15"
          },
          "default": {
            "start_samples": 2.0,
            "end_samples": 4.0,
            "shape": "smoothstep"
          }
        }
      ]
    },
    "d44": {
      "kind": "object",
      "fields": [
        {
          "name": "cover",
          "description": "Chance, from 0 to 1, that each lattice cell of the slip faces holds a grainflow; 0 for none.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "min_scarp_width",
          "description": "Narrowest scarp, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.5,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "max_scarp_width",
          "description": "Widest scarp, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.5,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "min_scarp_length",
          "description": "Shortest scarp downslope, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "max_scarp_length",
          "description": "Longest scarp downslope, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "min_lobe_width",
          "description": "Narrowest lobe, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.5,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "max_lobe_width",
          "description": "Widest lobe, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.5,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "min_lobe_length",
          "description": "Shortest lobe downslope, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 3.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "max_lobe_length",
          "description": "Longest lobe downslope, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 3.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "thickness",
          "description": "Depth of a scarp and height of a lobe, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.015,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "fade",
          "description": "How grainflows too narrow for the sample spacing fade out, by samples across a lobe.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d15"
          },
          "default": {
            "start_samples": 2.0,
            "end_samples": 4.0,
            "shape": "smoothstep"
          }
        }
      ]
    },
    "d2": {
      "kind": "choice",
      "alternatives": [
        {
          "type": "noise",
          "description": "A stack of fractal noise layers added to the terrain, for hills, ridges and rolling relief.",
          "fields": [
            {
              "name": "stack",
              "description": "Noise layers, 1 to 8, combined in order: the first enabled layer sets the height and each later one is combined with it by its blend mode.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "ref",
                  "ref": "d3"
                },
                "default": {
                  "enabled": true,
                  "basis": "perlin",
                  "fractal": "fbm",
                  "blend": "add",
                  "seed": 0,
                  "wavelength": 1000.0,
                  "amplitude": 100.0,
                  "octaves": 8,
                  "lacunarity": 2.0,
                  "gain": 0.5,
                  "hurst": null,
                  "offset": 1.0,
                  "warp_amplitude": 0.0,
                  "warp_wavelength": 500.0
                }
              },
              "default": [
                {
                  "enabled": true,
                  "basis": "perlin",
                  "fractal": "fbm",
                  "blend": "add",
                  "seed": 0,
                  "wavelength": 1000.0,
                  "amplitude": 100.0,
                  "octaves": 8,
                  "lacunarity": 2.0,
                  "gain": 0.5,
                  "hurst": null,
                  "offset": 1.0,
                  "warp_amplitude": 0.0,
                  "warp_wavelength": 500.0
                }
              ]
            }
          ],
          "default": {
            "type": "noise",
            "stack": [
              {
                "enabled": true,
                "basis": "perlin",
                "fractal": "fbm",
                "blend": "add",
                "seed": 0,
                "wavelength": 1000.0,
                "amplitude": 100.0,
                "octaves": 8,
                "lacunarity": 2.0,
                "gain": 0.5,
                "hurst": null,
                "offset": 1.0,
                "warp_amplitude": 0.0,
                "warp_wavelength": 500.0
              }
            ]
          }
        },
        {
          "type": "craters",
          "description": "Impact craters generated from a density and age model, or placed by hand, and cut into the terrain.",
          "fields": [
            {
              "name": "morphometry",
              "description": "Published fits of fresh crater depth, rim height and complex crater shape the craters are shaped with.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "lunar",
                  "mars"
                ],
                "descriptions": [
                  "Fresh lunar craters: Fassett et al. (2022) depth and rim height below 15 km, Pike's (1977) complex crater fits above.",
                  "Fresh Martian craters: depth and rim height capped for small craters, Garvin et al.'s (2003) fits for large and complex craters from 7 km."
                ]
              },
              "default": "lunar"
            },
            {
              "name": "generate",
              "description": "Generates craters from the density; off places only the manual craters.",
              "unit": "",
              "schema": {
                "kind": "boolean"
              },
              "default": true
            },
            {
              "name": "seed",
              "description": "Seed the craters are generated with; changing it gives a different crater field of the same statistics.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 1
            },
            {
              "name": "density",
              "description": "Size-frequency distribution of the generated craters: how many of each diameter per unit area.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d4"
              },
              "default": {
                "type": "power_law",
                "coefficient": 0.1,
                "exponent": 2.0
              }
            },
            {
              "name": "ages",
              "description": "How generated craters are given ages, which the degradation model wears them down by.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d7"
              },
              "default": {
                "type": "uniform",
                "lifetime_gyr": 1.0
              }
            },
            {
              "name": "min_diameter",
              "description": "Smallest crater generated, in metres; lower values add many more small craters.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 4.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "max_diameter",
              "description": "Largest crater generated, in metres; above the smallest.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 250.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "spacing",
              "description": "Keeps craters of similar size apart by removing conflicting ones, which lowers the density below the model's.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d8"
              },
              "default": {
                "diameter_ratio": 1.5,
                "separation": 0.0
              }
            },
            {
              "name": "max_craters",
              "description": "Most generated craters kept, the largest first; 0 keeps all. Manual craters are always kept, and a cap means tiles no longer match the whole grid.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 0
            },
            {
              "name": "manual",
              "description": "Craters placed by hand in the surface's coordinates, added to any generated ones.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "ref",
                  "ref": "d9"
                },
                "default": {
                  "x": 0.0,
                  "y": 0.0,
                  "diameter": 0.0,
                  "age_gyr": 0.0,
                  "id": 0
                }
              },
              "default": []
            },
            {
              "name": "profile",
              "description": "Shape of a fresh crater's cross-section, scaled to each crater's diameter.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d10"
              },
              "default": {
                "type": "martin_parkes_dunstan"
              }
            },
            {
              "name": "degradation",
              "description": "How craters wear down from their fresh shape with age.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d12"
              },
              "default": {
                "type": "freshness",
                "cutoff_depth_ratio": 0.04
              }
            },
            {
              "name": "apply",
              "description": "How craters are cut into the terrain: their order, datum, blending, fading and irregular outlines.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d14"
              },
              "default": {
                "order": "oldest_first",
                "fade": {
                  "start_samples": 2.0,
                  "end_samples": 4.0,
                  "shape": "smoothstep"
                },
                "datum": "none",
                "datum_fit_radii": 1.0,
                "interior_replacement": 1.0,
                "blend": {
                  "start_radii": 0.8,
                  "end_radii": 1.2,
                  "shape": "smootherstep"
                },
                "irregularity": {
                  "enabled": false,
                  "seed": 0,
                  "min_diameter": 0.0,
                  "max_diameter": null,
                  "min_age_gyr": 0.0,
                  "max_age_gyr": null,
                  "manual": false,
                  "rough_share": 1.0,
                  "model": "power_law",
                  "scatter": true,
                  "max_deviation": 0.3,
                  "roughness": {
                    "kind": "uniform",
                    "a": 0.01,
                    "b": 0.03,
                    "min": null,
                    "max": null
                  },
                  "spectral_slope": {
                    "kind": "constant",
                    "a": 1.5,
                    "b": 0.0,
                    "min": null,
                    "max": null
                  },
                  "min_harmonic": 2,
                  "max_harmonic": 12,
                  "elongated_share": 0.054,
                  "ellipticity": {
                    "kind": "uniform",
                    "a": 1.1,
                    "b": 1.5,
                    "min": null,
                    "max": null
                  },
                  "heading": null,
                  "heading_spread": 0.0,
                  "marks_share": 0.0,
                  "marks_amplitude": {
                    "kind": "uniform",
                    "a": 0.0,
                    "b": 0.005,
                    "min": null,
                    "max": null
                  },
                  "marks_knots": 45,
                  "marks_inner_radii": 0.3,
                  "marks_outer_radii": 0.9,
                  "marks_fade_radii": 0.1
                },
                "rim_smoothing": {
                  "sigma_radii": 0.0,
                  "inner_radii": 0.8,
                  "outer_radii": 1.2,
                  "shape": "smootherstep",
                  "strength": 1.0
                },
                "noise": {
                  "amplitude": 0.0,
                  "wavelength_radii": 0.5,
                  "octaves": 4,
                  "gain": 0.5,
                  "rim_amplitude": 0.0,
                  "rim_wavelength_radii": 0.1,
                  "rim_inner_radii": 0.8,
                  "rim_outer_radii": 1.2,
                  "seed": 0
                },
                "texture": {
                  "wall_streaks": 0.0,
                  "wall_streak_width_radii": 0.15,
                  "ejecta": 0.0,
                  "ejecta_lineation_radii": 0.15,
                  "mantling": 0.0,
                  "ejecta_reach_radii": 3.0,
                  "min_freshness": 0.5,
                  "seed": 0
                },
                "slope": {
                  "enabled": false,
                  "seed": 0,
                  "floor_offset": {
                    "kind": "uniform",
                    "a": 0.045,
                    "b": 0.194,
                    "min": null,
                    "max": null
                  },
                  "upslope_rim": 0.0,
                  "full_slope": 0.08726646259971647,
                  "critical_gradient": null,
                  "max_wear_rate": 10.0
                }
              }
            },
            {
              "name": "density_map",
              "description": "Map that sets the crater density point by point, scaling the density's size distribution to what it measures; unset keeps the density the same everywhere.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d23"
                },
                "default": {
                  "field": {
                    "path": "",
                    "value": 0.0,
                    "band": 0,
                    "method": "bilinear",
                    "scale": 1.0,
                    "fallback": null,
                    "periodic_longitude": false
                  },
                  "measure": "scale",
                  "min_diameter": 0.0,
                  "max_diameter": null,
                  "area_unit": 1.0,
                  "total": true
                }
              },
              "default": null
            },
            {
              "name": "completeness",
              "description": "Where the manual craters are a complete catalog: the diameter in metres from which they stand in for generated craters, infinite or no value where there is no catalog. Unset keeps every generated crater.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d24"
                },
                "default": {
                  "path": "",
                  "value": 0.0,
                  "band": 0,
                  "method": "bilinear",
                  "scale": 1.0,
                  "fallback": null,
                  "periodic_longitude": false
                }
              },
              "default": null
            }
          ],
          "default": {
            "type": "craters",
            "morphometry": "lunar",
            "generate": true,
            "seed": 1,
            "density": {
              "type": "power_law",
              "coefficient": 0.1,
              "exponent": 2.0
            },
            "ages": {
              "type": "uniform",
              "lifetime_gyr": 1.0
            },
            "min_diameter": 4.0,
            "max_diameter": 250.0,
            "spacing": {
              "diameter_ratio": 1.5,
              "separation": 0.0
            },
            "max_craters": 0,
            "manual": [],
            "profile": {
              "type": "martin_parkes_dunstan"
            },
            "degradation": {
              "type": "freshness",
              "cutoff_depth_ratio": 0.04
            },
            "apply": {
              "order": "oldest_first",
              "fade": {
                "start_samples": 2.0,
                "end_samples": 4.0,
                "shape": "smoothstep"
              },
              "datum": "none",
              "datum_fit_radii": 1.0,
              "interior_replacement": 1.0,
              "blend": {
                "start_radii": 0.8,
                "end_radii": 1.2,
                "shape": "smootherstep"
              },
              "irregularity": {
                "enabled": false,
                "seed": 0,
                "min_diameter": 0.0,
                "max_diameter": null,
                "min_age_gyr": 0.0,
                "max_age_gyr": null,
                "manual": false,
                "rough_share": 1.0,
                "model": "power_law",
                "scatter": true,
                "max_deviation": 0.3,
                "roughness": {
                  "kind": "uniform",
                  "a": 0.01,
                  "b": 0.03,
                  "min": null,
                  "max": null
                },
                "spectral_slope": {
                  "kind": "constant",
                  "a": 1.5,
                  "b": 0.0,
                  "min": null,
                  "max": null
                },
                "min_harmonic": 2,
                "max_harmonic": 12,
                "elongated_share": 0.054,
                "ellipticity": {
                  "kind": "uniform",
                  "a": 1.1,
                  "b": 1.5,
                  "min": null,
                  "max": null
                },
                "heading": null,
                "heading_spread": 0.0,
                "marks_share": 0.0,
                "marks_amplitude": {
                  "kind": "uniform",
                  "a": 0.0,
                  "b": 0.005,
                  "min": null,
                  "max": null
                },
                "marks_knots": 45,
                "marks_inner_radii": 0.3,
                "marks_outer_radii": 0.9,
                "marks_fade_radii": 0.1
              },
              "rim_smoothing": {
                "sigma_radii": 0.0,
                "inner_radii": 0.8,
                "outer_radii": 1.2,
                "shape": "smootherstep",
                "strength": 1.0
              },
              "noise": {
                "amplitude": 0.0,
                "wavelength_radii": 0.5,
                "octaves": 4,
                "gain": 0.5,
                "rim_amplitude": 0.0,
                "rim_wavelength_radii": 0.1,
                "rim_inner_radii": 0.8,
                "rim_outer_radii": 1.2,
                "seed": 0
              },
              "texture": {
                "wall_streaks": 0.0,
                "wall_streak_width_radii": 0.15,
                "ejecta": 0.0,
                "ejecta_lineation_radii": 0.15,
                "mantling": 0.0,
                "ejecta_reach_radii": 3.0,
                "min_freshness": 0.5,
                "seed": 0
              },
              "slope": {
                "enabled": false,
                "seed": 0,
                "floor_offset": {
                  "kind": "uniform",
                  "a": 0.045,
                  "b": 0.194,
                  "min": null,
                  "max": null
                },
                "upslope_rim": 0.0,
                "full_slope": 0.08726646259971647,
                "critical_gradient": null,
                "max_wear_rate": 10.0
              }
            },
            "density_map": null,
            "completeness": null
          }
        },
        {
          "type": "boulders",
          "description": "Boulders scattered over the ground from a size distribution, in patches and around fresh craters, as relief or 3D models.",
          "fields": [
            {
              "name": "coverage",
              "description": "Golombek-Rapp k, the fraction of the ground covered by boulders, between 0 and 1; used with golombek_rapp sizes, where higher values give more boulders.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.02,
              "minimum": 0.0,
              "exclusive_minimum": true,
              "maximum": 1.0,
              "exclusive_maximum": true
            },
            {
              "name": "qa",
              "description": "Constant term of the Golombek-Rapp q = qa + qb / k, per metre; a larger q leaves fewer large boulders. Also used for golombek_rapp ejecta.",
              "unit": "1/m",
              "schema": {
                "kind": "number"
              },
              "default": 1.79
            },
            {
              "name": "qb",
              "description": "Term of the Golombek-Rapp q = qa + qb / k divided by the coverage k, per metre.",
              "unit": "1/m",
              "schema": {
                "kind": "number"
              },
              "default": 0.152
            },
            {
              "name": "min_diameter",
              "description": "Smallest boulder generated, in metres; lower values add many more small boulders.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.1,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "max_diameter",
              "description": "Largest boulder generated, in metres, exclusive; above the smallest.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 4.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "sizes",
              "description": "Size distribution of the boulders between craters, per m^2; patches and bedrock scale its density.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d25"
              },
              "default": {
                "type": "golombek_rapp"
              }
            },
            {
              "name": "seed",
              "description": "Seed of the boulders, their attributes and the patches; changing it gives a different boulder field of the same statistics.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 1
            },
            {
              "name": "patches",
              "description": "Patches of richer and poorer boulder cover across the ground.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d26"
              },
              "default": {
                "spread": 1.0,
                "size": 200.0
              }
            },
            {
              "name": "clusters",
              "description": "Clusters of the boulders between craters around scattered centres; off unless share is set.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d27"
              },
              "default": {
                "share": 0.0,
                "spacing": 50.0,
                "radius": 5.0,
                "model": "nearest"
              }
            },
            {
              "name": "ejecta",
              "description": "Blocks thrown out by craters of the nearest crater layer before this one that dug into boulder, densest at the rim and thinning outward.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d28"
              },
              "default": {
                "min_crater_diameter": 0.0,
                "regolith_thickness": null,
                "excavation_depth_ratio": 0.1,
                "coverage": 0.1,
                "profile": "smoothstep",
                "reach": 3.0,
                "decay_radii": 0.7,
                "floor_share": 0.05,
                "aging": "freshness",
                "min_freshness": 0.7,
                "lifetime_gyr": 4.0,
                "aging_exponent": 3.0,
                "gravity": null
              }
            },
            {
              "name": "ejecta_sizes",
              "description": "Size distribution of the blocks at the rim of a fresh crater, per m^2; golombek_rapp uses the ejecta's coverage with qa and qb.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d25"
              },
              "default": {
                "type": "golombek_rapp"
              }
            },
            {
              "name": "extrapolate",
              "description": "Lets the size distributions be evaluated outside their valid diameters, such as beyond a table's published ones; otherwise they must cover the boulder sizes.",
              "unit": "",
              "schema": {
                "kind": "boolean"
              },
              "default": false
            },
            {
              "name": "exposure",
              "description": "Raises the abundance of boulders where the ground beneath is bedrock, judged from its shape; unset disables it.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d29"
                },
                "default": {
                  "reach": 12.0,
                  "rise_soil": 0.01,
                  "rise_boulder": 0.035,
                  "slope_soil": 0.2,
                  "slope_boulder": 0.4,
                  "floor_cover": 0.0,
                  "floor_patch": 60.0,
                  "seed": 0
                }
              },
              "default": null
            },
            {
              "name": "bedrock_abundance",
              "description": "Boulder abundance on bedrock over that on soil, and in between in proportion; used with the exposure field.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 3.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "exposure_spacing",
              "description": "Spacing in metres the ground is read at for the exposure field, fixed so that which boulders exist does not depend on the level of detail.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "bedrock_mean_size",
              "description": "With a density map, the side in metres of the squares bedrock is held to the map's mean over, so it gathers boulders without adding any; a GeoTIFF map uses its own cells.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 1000.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "min_height_ratio",
              "description": "Smallest boulder height over diameter; each boulder's is drawn uniformly between the two ratios.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.4,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "max_height_ratio",
              "description": "Largest boulder height over diameter; at least the smallest.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.6,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "min_burial",
              "description": "Smallest buried share of a boulder's height; each boulder's is drawn uniformly between the two shares.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.1,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": true
            },
            {
              "name": "max_burial",
              "description": "Largest buried share of a boulder's height, below 1; more burial leaves less of the boulder exposed.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.4,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": true
            },
            {
              "name": "max_lean",
              "description": "Largest tilt of a boulder from the vertical, in radians.",
              "unit": "rad",
              "schema": {
                "kind": "number"
              },
              "default": 0.26,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "side_share",
              "description": "Share of boulders resting on a side, their intermediate axis up, rather than on their broadest face.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "end_share",
              "description": "Share of boulders standing on an end, their long axis up; with side_share, at most 1.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "max_tilt",
              "description": "Largest tilt of a boulder's up axis from the vertical in a random direction, after its lean, in radians; tilts are spread evenly over that cap of directions.",
              "unit": "rad",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 3.141592653589793,
              "exclusive_maximum": false
            },
            {
              "name": "follow_slope",
              "description": "Settles each boulder on the slope of the ground beneath it before its tilt.",
              "unit": "",
              "schema": {
                "kind": "boolean"
              },
              "default": false
            },
            {
              "name": "settle",
              "description": "Tips each boulder model over until it rests stably on a face, its centre of mass over what it stands on, rather than balanced on an edge or corner.",
              "unit": "",
              "schema": {
                "kind": "boolean"
              },
              "default": true
            },
            {
              "name": "max_slope",
              "description": "Steepest ground, across a boulder's diameter, that boulders stay on, in radians; steeper ground has none, models and drawn boulders alike. Unset keeps boulders on any slope.",
              "unit": "rad",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": true,
              "maximum": 1.5707963267948966,
              "exclusive_maximum": true
            },
            {
              "name": "roll_distance",
              "description": "With max_slope, boulders on steeper ground roll down it and rest where it is gentle enough, gathering at the foot of slopes; those that would roll farther than this many metres are left out. Unset leaves out every boulder on steeper ground.",
              "unit": "m",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "burial_by_wear",
              "description": "How far wear sets burial, from 0 to 1: blocks of fresh craters sit near the smallest burial and those of worn ones sink toward the largest, while boulders between craters span every stage; 0 draws burial uniformly.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "fillet",
              "description": "Regolith piled against each boulder's base, around relief and models alike; off unless height_share is set.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d30"
              },
              "default": {
                "height_share": 0.0,
                "width_ratio": 0.3
              }
            },
            {
              "name": "ventifacts",
              "description": "Windward facets planed on boulders by sand-laden wind, from wear; off unless share is set.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d31"
              },
              "default": {
                "share": 0.0,
                "wind_azimuth": 0.0,
                "min_angle": 0.8726646259971648,
                "max_angle": 1.0471975511965976,
                "second_wind_azimuth": null,
                "keel_share": 0.0
              }
            },
            {
              "name": "fragmentation",
              "description": "Boulders broken by wear into pieces that replace them, split and then scattered as rubble; off unless split_wear is below 1.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d32"
              },
              "default": {
                "min_diameter": 1.0,
                "split_wear": 1.0,
                "rubble_wear": 1.0,
                "min_pieces": 2,
                "max_pieces": 5,
                "gap_ratio": 0.04,
                "spread_ratio": 0.6,
                "slab_share": 0.7
              }
            },
            {
              "name": "relief",
              "description": "How the boulders drawn into the heights look there.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "dome",
                  "shape",
                  "none"
                ],
                "descriptions": [
                  "Each boulder's exposed part drawn as a dome: cheap, and enough for small boulders.",
                  "The top surface of each boulder's 3D boulder shape drawn into the heights.",
                  "No rock relief in the heights, only fillets when set, for programs that place every boulder as a model of its own."
                ]
              },
              "default": "dome"
            },
            {
              "name": "models",
              "description": "Which boulders become 3D models of their own rather than relief in the heights; neither threshold set means no models.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d33"
              },
              "default": {
                "min_diameter": null,
                "min_samples": null,
                "max_diameter": null,
                "max_samples": null
              }
            },
            {
              "name": "relief_range",
              "description": "Which boulders are drawn into the heights by diameter: none below min_diameter or from max_diameter, and models only when asked.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d34"
              },
              "default": {
                "min_diameter": 0.0,
                "max_diameter": null,
                "models": false
              }
            },
            {
              "name": "shapes",
              "description": "The boulders' 3D boulder shapes, used by shape relief and by models.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d35"
              },
              "default": {
                "styles": [
                  {
                    "name": "angular",
                    "weight": 0.2,
                    "solid": "icosahedron",
                    "intermediate": {
                      "min": 0.6,
                      "max": 0.9
                    },
                    "short_axis": {
                      "min": 0.45,
                      "max": 0.7
                    },
                    "rounding": {
                      "min": 0.0,
                      "max": 0.0
                    },
                    "min_fractures": 7,
                    "max_fractures": 12,
                    "fracture_depth": {
                      "min": 0.55,
                      "max": 0.85
                    },
                    "max_fracture_tilt": 1.0,
                    "noise_amplitude": 0.06,
                    "noise_wavelength": 0.9,
                    "noise_octaves": 4,
                    "edge_softness": {
                      "min": 0.02,
                      "max": 0.06
                    },
                    "face_roughness": 0.03
                  },
                  {
                    "name": "platy",
                    "weight": 0.12,
                    "solid": "icosahedron",
                    "intermediate": {
                      "min": 0.6,
                      "max": 0.9
                    },
                    "short_axis": {
                      "min": 0.22,
                      "max": 0.38
                    },
                    "rounding": {
                      "min": 0.0,
                      "max": 0.0
                    },
                    "min_fractures": 5,
                    "max_fractures": 9,
                    "fracture_depth": {
                      "min": 0.6,
                      "max": 0.88
                    },
                    "max_fracture_tilt": 0.7,
                    "noise_amplitude": 0.05,
                    "noise_wavelength": 0.9,
                    "noise_octaves": 4,
                    "edge_softness": {
                      "min": 0.02,
                      "max": 0.05
                    },
                    "face_roughness": 0.03
                  },
                  {
                    "name": "subrounded",
                    "weight": 0.15,
                    "solid": "icosahedron",
                    "intermediate": {
                      "min": 0.65,
                      "max": 0.9
                    },
                    "short_axis": {
                      "min": 0.45,
                      "max": 0.7
                    },
                    "rounding": {
                      "min": 0.0,
                      "max": 0.0
                    },
                    "min_fractures": 4,
                    "max_fractures": 7,
                    "fracture_depth": {
                      "min": 0.65,
                      "max": 0.9
                    },
                    "max_fracture_tilt": 1.0,
                    "noise_amplitude": 0.07,
                    "noise_wavelength": 0.8,
                    "noise_octaves": 4,
                    "edge_softness": {
                      "min": 0.06,
                      "max": 0.12
                    },
                    "face_roughness": 0.02
                  },
                  {
                    "name": "rounded",
                    "weight": 0.1,
                    "solid": "icosahedron",
                    "intermediate": {
                      "min": 0.7,
                      "max": 0.95
                    },
                    "short_axis": {
                      "min": 0.5,
                      "max": 0.75
                    },
                    "rounding": {
                      "min": 0.0,
                      "max": 0.0
                    },
                    "min_fractures": 0,
                    "max_fractures": 3,
                    "fracture_depth": {
                      "min": 0.75,
                      "max": 0.95
                    },
                    "max_fracture_tilt": 1.0,
                    "noise_amplitude": 0.1,
                    "noise_wavelength": 0.7,
                    "noise_octaves": 4,
                    "edge_softness": {
                      "min": 0.1,
                      "max": 0.18
                    },
                    "face_roughness": 0.02
                  },
                  {
                    "name": "block",
                    "weight": 0.13,
                    "solid": "cube",
                    "intermediate": {
                      "min": 0.6,
                      "max": 0.85
                    },
                    "short_axis": {
                      "min": 0.4,
                      "max": 0.6
                    },
                    "rounding": {
                      "min": 0.0,
                      "max": 0.15
                    },
                    "min_fractures": 3,
                    "max_fractures": 7,
                    "fracture_depth": {
                      "min": 0.6,
                      "max": 0.85
                    },
                    "max_fracture_tilt": 1.0,
                    "noise_amplitude": 0.07,
                    "noise_wavelength": 0.8,
                    "noise_octaves": 4,
                    "edge_softness": {
                      "min": 0.06,
                      "max": 0.12
                    },
                    "face_roughness": 0.06
                  },
                  {
                    "name": "wedge",
                    "weight": 0.1,
                    "solid": "prism",
                    "intermediate": {
                      "min": 0.55,
                      "max": 0.85
                    },
                    "short_axis": {
                      "min": 0.4,
                      "max": 0.6
                    },
                    "rounding": {
                      "min": 0.0,
                      "max": 0.2
                    },
                    "min_fractures": 2,
                    "max_fractures": 5,
                    "fracture_depth": {
                      "min": 0.65,
                      "max": 0.9
                    },
                    "max_fracture_tilt": 1.0,
                    "noise_amplitude": 0.07,
                    "noise_wavelength": 0.8,
                    "noise_octaves": 4,
                    "edge_softness": {
                      "min": 0.06,
                      "max": 0.12
                    },
                    "face_roughness": 0.06
                  },
                  {
                    "name": "pyramid",
                    "weight": 0.1,
                    "solid": "pyramid",
                    "intermediate": {
                      "min": 0.7,
                      "max": 0.95
                    },
                    "short_axis": {
                      "min": 0.45,
                      "max": 0.7
                    },
                    "rounding": {
                      "min": 0.0,
                      "max": 0.2
                    },
                    "min_fractures": 2,
                    "max_fractures": 4,
                    "fracture_depth": {
                      "min": 0.7,
                      "max": 0.92
                    },
                    "max_fracture_tilt": 1.0,
                    "noise_amplitude": 0.07,
                    "noise_wavelength": 0.8,
                    "noise_octaves": 4,
                    "edge_softness": {
                      "min": 0.06,
                      "max": 0.12
                    },
                    "face_roughness": 0.06
                  },
                  {
                    "name": "shard",
                    "weight": 0.05,
                    "solid": "tetrahedron",
                    "intermediate": {
                      "min": 0.6,
                      "max": 0.9
                    },
                    "short_axis": {
                      "min": 0.4,
                      "max": 0.6
                    },
                    "rounding": {
                      "min": 0.0,
                      "max": 0.2
                    },
                    "min_fractures": 2,
                    "max_fractures": 4,
                    "fracture_depth": {
                      "min": 0.7,
                      "max": 0.92
                    },
                    "max_fracture_tilt": 1.0,
                    "noise_amplitude": 0.04,
                    "noise_wavelength": 0.8,
                    "noise_octaves": 4,
                    "edge_softness": {
                      "min": 0.02,
                      "max": 0.05
                    },
                    "face_roughness": 0.03
                  },
                  {
                    "name": "sphere",
                    "weight": 0.05,
                    "solid": "icosahedron",
                    "intermediate": {
                      "min": 0.85,
                      "max": 1.0
                    },
                    "short_axis": {
                      "min": 0.7,
                      "max": 0.9
                    },
                    "rounding": {
                      "min": 0.0,
                      "max": 0.0
                    },
                    "min_fractures": 0,
                    "max_fractures": 1,
                    "fracture_depth": {
                      "min": 0.8,
                      "max": 0.95
                    },
                    "max_fracture_tilt": 1.0,
                    "noise_amplitude": 0.08,
                    "noise_wavelength": 0.7,
                    "noise_octaves": 4,
                    "edge_softness": {
                      "min": 0.12,
                      "max": 0.2
                    },
                    "face_roughness": 0.02
                  }
                ],
                "subdivisions": 3,
                "weathering": 1.0,
                "seed": 0
              }
            },
            {
              "name": "shape_files",
              "description": "Rock meshes (.obj with its .mtl, .gltf or .glb) the boulder shapes are drawn from instead of the procedural styles, each boulder picking one by its shape seed; paths relative to the configuration. Empty keeps the procedural shapes.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "string"
                },
                "default": ""
              },
              "default": []
            },
            {
              "name": "density_map",
              "description": "Map that sets the abundance of boulders between craters point by point, scaling the sizes to what it measures; unset keeps the abundance the sizes set everywhere.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d23"
                },
                "default": {
                  "field": {
                    "path": "",
                    "value": 0.0,
                    "band": 0,
                    "method": "bilinear",
                    "scale": 1.0,
                    "fallback": null,
                    "periodic_longitude": false
                  },
                  "measure": "scale",
                  "min_diameter": 0.0,
                  "max_diameter": null,
                  "area_unit": 1.0,
                  "total": true
                }
              },
              "default": null
            },
            {
              "name": "slope_map",
              "description": "Map of how steeply boulder counts fall with size, such as a mean diameter map, bending the sizes into a local power law through their count at its reference diameter; needs a size distribution. Unset keeps the sizes' shape everywhere.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d38"
                },
                "default": {
                  "field": {
                    "path": "",
                    "value": 0.0,
                    "band": 0,
                    "method": "bilinear",
                    "scale": 1.0,
                    "fallback": null,
                    "periodic_longitude": false
                  },
                  "measure": "exponent",
                  "reference_diameter": 1.0,
                  "min_exponent": 1.0,
                  "max_exponent": 6.0
                }
              },
              "default": null
            },
            {
              "name": "manual",
              "description": "Catalog boulders placed as given and never thinned or left out; x, y and diameter are read.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "ref",
                  "ref": "d9"
                },
                "default": {
                  "x": 0.0,
                  "y": 0.0,
                  "diameter": 0.0,
                  "age_gyr": 0.0,
                  "id": 0
                }
              },
              "default": []
            },
            {
              "name": "completeness",
              "description": "Where the manual boulders are a complete catalog: the diameter in metres from which they stand in for generated boulders, infinite or no value where there is no catalog. Unset keeps every generated boulder.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d24"
                },
                "default": {
                  "path": "",
                  "value": 0.0,
                  "band": 0,
                  "method": "bilinear",
                  "scale": 1.0,
                  "fallback": null,
                  "periodic_longitude": false
                }
              },
              "default": null
            },
            {
              "name": "shape_prototypes",
              "description": "How many shapes the boulders share, so they can be drawn as instances; 0 gives every boulder a shape of its own.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 64
            },
            {
              "name": "fade",
              "description": "How boulders too small to resolve at the sample spacing fade out.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d15"
              },
              "default": {
                "start_samples": 2.0,
                "end_samples": 4.0,
                "shape": "smoothstep"
              }
            }
          ],
          "default": {
            "type": "boulders",
            "coverage": 0.02,
            "qa": 1.79,
            "qb": 0.152,
            "min_diameter": 0.1,
            "max_diameter": 4.0,
            "sizes": {
              "type": "golombek_rapp"
            },
            "seed": 1,
            "patches": {
              "spread": 1.0,
              "size": 200.0
            },
            "clusters": {
              "share": 0.0,
              "spacing": 50.0,
              "radius": 5.0,
              "model": "nearest"
            },
            "ejecta": {
              "min_crater_diameter": 0.0,
              "regolith_thickness": null,
              "excavation_depth_ratio": 0.1,
              "coverage": 0.1,
              "profile": "smoothstep",
              "reach": 3.0,
              "decay_radii": 0.7,
              "floor_share": 0.05,
              "aging": "freshness",
              "min_freshness": 0.7,
              "lifetime_gyr": 4.0,
              "aging_exponent": 3.0,
              "gravity": null
            },
            "ejecta_sizes": {
              "type": "golombek_rapp"
            },
            "extrapolate": false,
            "exposure": null,
            "bedrock_abundance": 3.0,
            "exposure_spacing": 1.0,
            "bedrock_mean_size": 1000.0,
            "min_height_ratio": 0.4,
            "max_height_ratio": 0.6,
            "min_burial": 0.1,
            "max_burial": 0.4,
            "max_lean": 0.26,
            "side_share": 0.0,
            "end_share": 0.0,
            "max_tilt": 0.0,
            "follow_slope": false,
            "settle": true,
            "max_slope": null,
            "roll_distance": null,
            "burial_by_wear": 0.0,
            "fillet": {
              "height_share": 0.0,
              "width_ratio": 0.3
            },
            "ventifacts": {
              "share": 0.0,
              "wind_azimuth": 0.0,
              "min_angle": 0.8726646259971648,
              "max_angle": 1.0471975511965976,
              "second_wind_azimuth": null,
              "keel_share": 0.0
            },
            "fragmentation": {
              "min_diameter": 1.0,
              "split_wear": 1.0,
              "rubble_wear": 1.0,
              "min_pieces": 2,
              "max_pieces": 5,
              "gap_ratio": 0.04,
              "spread_ratio": 0.6,
              "slab_share": 0.7
            },
            "relief": "dome",
            "models": {
              "min_diameter": null,
              "min_samples": null,
              "max_diameter": null,
              "max_samples": null
            },
            "relief_range": {
              "min_diameter": 0.0,
              "max_diameter": null,
              "models": false
            },
            "shapes": {
              "styles": [
                {
                  "name": "angular",
                  "weight": 0.2,
                  "solid": "icosahedron",
                  "intermediate": {
                    "min": 0.6,
                    "max": 0.9
                  },
                  "short_axis": {
                    "min": 0.45,
                    "max": 0.7
                  },
                  "rounding": {
                    "min": 0.0,
                    "max": 0.0
                  },
                  "min_fractures": 7,
                  "max_fractures": 12,
                  "fracture_depth": {
                    "min": 0.55,
                    "max": 0.85
                  },
                  "max_fracture_tilt": 1.0,
                  "noise_amplitude": 0.06,
                  "noise_wavelength": 0.9,
                  "noise_octaves": 4,
                  "edge_softness": {
                    "min": 0.02,
                    "max": 0.06
                  },
                  "face_roughness": 0.03
                },
                {
                  "name": "platy",
                  "weight": 0.12,
                  "solid": "icosahedron",
                  "intermediate": {
                    "min": 0.6,
                    "max": 0.9
                  },
                  "short_axis": {
                    "min": 0.22,
                    "max": 0.38
                  },
                  "rounding": {
                    "min": 0.0,
                    "max": 0.0
                  },
                  "min_fractures": 5,
                  "max_fractures": 9,
                  "fracture_depth": {
                    "min": 0.6,
                    "max": 0.88
                  },
                  "max_fracture_tilt": 0.7,
                  "noise_amplitude": 0.05,
                  "noise_wavelength": 0.9,
                  "noise_octaves": 4,
                  "edge_softness": {
                    "min": 0.02,
                    "max": 0.05
                  },
                  "face_roughness": 0.03
                },
                {
                  "name": "subrounded",
                  "weight": 0.15,
                  "solid": "icosahedron",
                  "intermediate": {
                    "min": 0.65,
                    "max": 0.9
                  },
                  "short_axis": {
                    "min": 0.45,
                    "max": 0.7
                  },
                  "rounding": {
                    "min": 0.0,
                    "max": 0.0
                  },
                  "min_fractures": 4,
                  "max_fractures": 7,
                  "fracture_depth": {
                    "min": 0.65,
                    "max": 0.9
                  },
                  "max_fracture_tilt": 1.0,
                  "noise_amplitude": 0.07,
                  "noise_wavelength": 0.8,
                  "noise_octaves": 4,
                  "edge_softness": {
                    "min": 0.06,
                    "max": 0.12
                  },
                  "face_roughness": 0.02
                },
                {
                  "name": "rounded",
                  "weight": 0.1,
                  "solid": "icosahedron",
                  "intermediate": {
                    "min": 0.7,
                    "max": 0.95
                  },
                  "short_axis": {
                    "min": 0.5,
                    "max": 0.75
                  },
                  "rounding": {
                    "min": 0.0,
                    "max": 0.0
                  },
                  "min_fractures": 0,
                  "max_fractures": 3,
                  "fracture_depth": {
                    "min": 0.75,
                    "max": 0.95
                  },
                  "max_fracture_tilt": 1.0,
                  "noise_amplitude": 0.1,
                  "noise_wavelength": 0.7,
                  "noise_octaves": 4,
                  "edge_softness": {
                    "min": 0.1,
                    "max": 0.18
                  },
                  "face_roughness": 0.02
                },
                {
                  "name": "block",
                  "weight": 0.13,
                  "solid": "cube",
                  "intermediate": {
                    "min": 0.6,
                    "max": 0.85
                  },
                  "short_axis": {
                    "min": 0.4,
                    "max": 0.6
                  },
                  "rounding": {
                    "min": 0.0,
                    "max": 0.15
                  },
                  "min_fractures": 3,
                  "max_fractures": 7,
                  "fracture_depth": {
                    "min": 0.6,
                    "max": 0.85
                  },
                  "max_fracture_tilt": 1.0,
                  "noise_amplitude": 0.07,
                  "noise_wavelength": 0.8,
                  "noise_octaves": 4,
                  "edge_softness": {
                    "min": 0.06,
                    "max": 0.12
                  },
                  "face_roughness": 0.06
                },
                {
                  "name": "wedge",
                  "weight": 0.1,
                  "solid": "prism",
                  "intermediate": {
                    "min": 0.55,
                    "max": 0.85
                  },
                  "short_axis": {
                    "min": 0.4,
                    "max": 0.6
                  },
                  "rounding": {
                    "min": 0.0,
                    "max": 0.2
                  },
                  "min_fractures": 2,
                  "max_fractures": 5,
                  "fracture_depth": {
                    "min": 0.65,
                    "max": 0.9
                  },
                  "max_fracture_tilt": 1.0,
                  "noise_amplitude": 0.07,
                  "noise_wavelength": 0.8,
                  "noise_octaves": 4,
                  "edge_softness": {
                    "min": 0.06,
                    "max": 0.12
                  },
                  "face_roughness": 0.06
                },
                {
                  "name": "pyramid",
                  "weight": 0.1,
                  "solid": "pyramid",
                  "intermediate": {
                    "min": 0.7,
                    "max": 0.95
                  },
                  "short_axis": {
                    "min": 0.45,
                    "max": 0.7
                  },
                  "rounding": {
                    "min": 0.0,
                    "max": 0.2
                  },
                  "min_fractures": 2,
                  "max_fractures": 4,
                  "fracture_depth": {
                    "min": 0.7,
                    "max": 0.92
                  },
                  "max_fracture_tilt": 1.0,
                  "noise_amplitude": 0.07,
                  "noise_wavelength": 0.8,
                  "noise_octaves": 4,
                  "edge_softness": {
                    "min": 0.06,
                    "max": 0.12
                  },
                  "face_roughness": 0.06
                },
                {
                  "name": "shard",
                  "weight": 0.05,
                  "solid": "tetrahedron",
                  "intermediate": {
                    "min": 0.6,
                    "max": 0.9
                  },
                  "short_axis": {
                    "min": 0.4,
                    "max": 0.6
                  },
                  "rounding": {
                    "min": 0.0,
                    "max": 0.2
                  },
                  "min_fractures": 2,
                  "max_fractures": 4,
                  "fracture_depth": {
                    "min": 0.7,
                    "max": 0.92
                  },
                  "max_fracture_tilt": 1.0,
                  "noise_amplitude": 0.04,
                  "noise_wavelength": 0.8,
                  "noise_octaves": 4,
                  "edge_softness": {
                    "min": 0.02,
                    "max": 0.05
                  },
                  "face_roughness": 0.03
                },
                {
                  "name": "sphere",
                  "weight": 0.05,
                  "solid": "icosahedron",
                  "intermediate": {
                    "min": 0.85,
                    "max": 1.0
                  },
                  "short_axis": {
                    "min": 0.7,
                    "max": 0.9
                  },
                  "rounding": {
                    "min": 0.0,
                    "max": 0.0
                  },
                  "min_fractures": 0,
                  "max_fractures": 1,
                  "fracture_depth": {
                    "min": 0.8,
                    "max": 0.95
                  },
                  "max_fracture_tilt": 1.0,
                  "noise_amplitude": 0.08,
                  "noise_wavelength": 0.7,
                  "noise_octaves": 4,
                  "edge_softness": {
                    "min": 0.12,
                    "max": 0.2
                  },
                  "face_roughness": 0.02
                }
              ],
              "subdivisions": 3,
              "weathering": 1.0,
              "seed": 0
            },
            "shape_files": [],
            "density_map": null,
            "slope_map": null,
            "manual": [],
            "completeness": null,
            "shape_prototypes": 64,
            "fade": {
              "start_samples": 2.0,
              "end_samples": 4.0,
              "shape": "smoothstep"
            }
          }
        },
        {
          "type": "roughness",
          "description": "Fine roughness from octaves of noise, scaled to a given RMS slope over a baseline.",
          "fields": [
            {
              "name": "rms_slope",
              "description": "RMS slope, as rise over run, over the baseline when every octave is resolved; higher values give rougher ground.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.15,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "baseline",
              "description": "Baseline the RMS slope is given over, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.25,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "hurst",
              "description": "Hurst exponent, in (0, 1]: octave amplitudes grow as wavelength^hurst, so lower values put relatively more roughness at short wavelengths.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.8,
              "minimum": 0.0,
              "exclusive_minimum": true,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "max_wavelength",
              "description": "Wavelength of the longest octave, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 4.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "min_wavelength",
              "description": "Wavelength of the shortest octave, in metres; octaves halve from the longest down to it, spanning at most 40 octaves.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.01,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "seed",
              "description": "Seed of the noise; changing it gives a different pattern of the same roughness.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 1
            },
            {
              "name": "fade",
              "description": "How octaves too fine to resolve at the sample spacing fade out, by samples per wavelength.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d15"
              },
              "default": {
                "start_samples": 2.0,
                "end_samples": 4.0,
                "shape": "smoothstep"
              }
            }
          ],
          "default": {
            "type": "roughness",
            "rms_slope": 0.15,
            "baseline": 0.25,
            "hurst": 0.8,
            "max_wavelength": 4.0,
            "min_wavelength": 0.01,
            "seed": 1,
            "fade": {
              "start_samples": 2.0,
              "end_samples": 4.0,
              "shape": "smoothstep"
            }
          }
        },
        {
          "type": "bedforms",
          "description": "Fields of wind-blown ripples or dunes added to the terrain.",
          "fields": [
            {
              "name": "wavelength",
              "description": "Crest-to-crest spacing, in metres; each field's varies from 0.8 to 1.2 times it.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "height",
              "description": "Trough-to-crest height, in metres, scaled with each field's wavelength.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.1,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "wind_azimuth",
              "description": "Direction the wind blows toward, in radians counter-clockwise from +x (local east on a sphere); crests lie across it.",
              "unit": "rad",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "azimuth_spread",
              "description": "Largest difference of each field's wind from the azimuth, in radians.",
              "unit": "rad",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "lee_fraction",
              "description": "Share of a wavelength the lee face takes, in (0, 1): 0.5 is symmetric, lower values give a steeper lee face.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.5,
              "minimum": 0.0,
              "exclusive_minimum": true,
              "maximum": 1.0,
              "exclusive_maximum": true
            },
            {
              "name": "sinuosity",
              "description": "How far a crest wanders along its length, in wavelengths; 0 gives straight crests.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.5,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "cover",
              "description": "Share of the ground under bedform fields, from 0 to 0.9; 0 gives no bedforms.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 0.9,
              "exclusive_maximum": false
            },
            {
              "name": "field_size",
              "description": "Typical width of a bedform field, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 100.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "seed",
              "description": "Seed of the fields and their crests; changing it gives a different layout of the same statistics.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 1
            },
            {
              "name": "exposure",
              "description": "Leaves out fields whose centres lie on bedrock, the likelier the barer the ground, as sand settles in lows; unset disables it.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d29"
                },
                "default": {
                  "reach": 12.0,
                  "rise_soil": 0.01,
                  "rise_boulder": 0.035,
                  "slope_soil": 0.2,
                  "slope_boulder": 0.4,
                  "floor_cover": 0.0,
                  "floor_patch": 60.0,
                  "seed": 0
                }
              },
              "default": null
            },
            {
              "name": "exposure_spacing",
              "description": "Spacing in metres the ground is read at for the exposure field.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "fade",
              "description": "How bedforms too fine for the sample spacing fade out, by samples per wavelength.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d15"
              },
              "default": {
                "start_samples": 2.0,
                "end_samples": 4.0,
                "shape": "smoothstep"
              }
            }
          ],
          "default": {
            "type": "bedforms",
            "wavelength": 1.0,
            "height": 0.1,
            "wind_azimuth": 0.0,
            "azimuth_spread": 0.0,
            "lee_fraction": 0.5,
            "sinuosity": 0.5,
            "cover": 0.0,
            "field_size": 100.0,
            "seed": 1,
            "exposure": null,
            "exposure_spacing": 1.0,
            "fade": {
              "start_samples": 2.0,
              "end_samples": 4.0,
              "shape": "smoothstep"
            }
          }
        },
        {
          "type": "scale",
          "description": "Scales and shifts the heights so far, for vertical exaggeration or a datum shift.",
          "fields": [
            {
              "name": "scale",
              "description": "Factor every height so far is multiplied by, as for vertical exaggeration.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 1.0
            },
            {
              "name": "offset",
              "description": "Metres added to every height after scaling, to shift the datum.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            }
          ],
          "default": {
            "type": "scale",
            "scale": 1.0,
            "offset": 0.0
          }
        },
        {
          "type": "clamp",
          "description": "Clamps the heights so far between optional bounds, to flatten a basin floor or cap peaks.",
          "fields": [
            {
              "name": "min",
              "description": "Lowest height kept, in metres; lower heights are raised to it, flattening basin floors. Unset leaves heights unbounded below.",
              "unit": "m",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null
            },
            {
              "name": "max",
              "description": "Highest height kept, in metres; higher heights are lowered to it, capping peaks. Unset leaves heights unbounded above.",
              "unit": "m",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null
            }
          ],
          "default": {
            "type": "clamp",
            "min": null,
            "max": null
          }
        },
        {
          "type": "region",
          "description": "Another layer applied only inside a rectangle or circle, feathered outside it: to confine craters to an area or flatten a landing pad.",
          "fields": [
            {
              "name": "shape",
              "description": "Area the inner layer is applied in: a rectangle or a circle.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d39"
              },
              "default": {
                "type": "rectangle",
                "min_x": 0.0,
                "min_y": 0.0,
                "max_x": 0.0,
                "max_y": 0.0
              }
            },
            {
              "name": "feather",
              "description": "Distance in metres outside the shape over which the inner layer fades back to the unchanged height; 0 gives a hard edge.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "blend",
              "description": "Curve of the fade across the feather.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "linear",
                  "smoothstep",
                  "smootherstep",
                  "gaussian"
                ],
                "descriptions": [
                  "Straight ramp: continuous, with kinks at both ends.",
                  "Cubic 3t^2 - 2t^3: continuous slope across the transition.",
                  "Quintic 6t^5 - 15t^4 + 10t^3: continuous slope and curvature, the smoothest join.",
                  "Gaussian falloff with sigma a third of the band, rescaled to end at zero."
                ]
              },
              "default": "smoothstep"
            },
            {
              "name": "layer",
              "description": "Layer applied only inside the shape. A crater layer here does not count as the crater layer for later boulder ejecta or secondaries.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d2"
              },
              "default": {
                "type": "noise",
                "stack": [
                  {
                    "enabled": true,
                    "basis": "perlin",
                    "fractal": "fbm",
                    "blend": "add",
                    "seed": 0,
                    "wavelength": 1000.0,
                    "amplitude": 100.0,
                    "octaves": 8,
                    "lacunarity": 2.0,
                    "gain": 0.5,
                    "hurst": null,
                    "offset": 1.0,
                    "warp_amplitude": 0.0,
                    "warp_wavelength": 500.0
                  }
                ]
              }
            }
          ],
          "default": {
            "type": "region",
            "shape": {
              "type": "rectangle",
              "min_x": 0.0,
              "min_y": 0.0,
              "max_x": 0.0,
              "max_y": 0.0
            },
            "feather": 0.0,
            "blend": "smoothstep",
            "layer": {
              "type": "noise",
              "stack": [
                {
                  "enabled": true,
                  "basis": "perlin",
                  "fractal": "fbm",
                  "blend": "add",
                  "seed": 0,
                  "wavelength": 1000.0,
                  "amplitude": 100.0,
                  "octaves": 8,
                  "lacunarity": 2.0,
                  "gain": 0.5,
                  "hurst": null,
                  "offset": 1.0,
                  "warp_amplitude": 0.0,
                  "warp_wavelength": 500.0
                }
              ]
            }
          }
        },
        {
          "type": "secondaries",
          "description": "Secondary craters around the craters of the last crater layer before this one, after Singer et al. (2020).",
          "fields": [
            {
              "name": "seed",
              "description": "Seed the secondaries are drawn with; changing it gives a different field of the same statistics.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 0
            },
            {
              "name": "onset_count",
              "description": "Secondaries at least count_fraction primary diameters across, in an area the size of the primary at the onset range. Required: the sources give sizes, not numbers.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "count_fraction",
              "description": "Size, as a fraction of the primary's diameter, from which the onset count counts secondaries.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.01,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "size_slope",
              "description": "Cumulative size slope of the secondaries, their number falling as d^-slope; higher values give relatively more small secondaries.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 4.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "min_diameter",
              "description": "Smallest secondary generated, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "max_diameter",
              "description": "Largest secondary generated, in metres; unset has no limit beyond Singer et al.'s largest secondary at each range.",
              "unit": "m",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "outer_range",
              "description": "How far secondaries reach, in primary diameters from its centre; unset uses the longest typical ray of Elliott et al. (2018).",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "min_primary_diameter",
              "description": "Smallest primary crater, in metres, that throws secondaries.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "max_primary_diameter",
              "description": "Largest primary crater, in metres, that throws secondaries; unset has no upper limit.",
              "unit": "m",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "min_age_gyr",
              "description": "Youngest primary, in Gyr, that throws secondaries.",
              "unit": "Gyr",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "max_age_gyr",
              "description": "Oldest primary, in Gyr, that throws secondaries; unset has no upper limit.",
              "unit": "Gyr",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "manual",
              "description": "Lets manual primary craters throw secondaries too; otherwise only generated ones do.",
              "unit": "",
              "schema": {
                "kind": "boolean"
              },
              "default": true
            },
            {
              "name": "cell_size_factor",
              "description": "Side of the polar cells secondaries are drawn in, as a multiple of each size band's largest diameter.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 16.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "rays",
              "description": "Secondaries gathered into rays and clumped along them; off by default.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d40"
              },
              "default": {
                "enabled": false,
                "layout": {
                  "seed": 0,
                  "count": {
                    "kind": "normal",
                    "a": 10.7,
                    "b": 3.1,
                    "min": 6.0,
                    "max": 20.0
                  },
                  "width_degrees": {
                    "kind": "normal",
                    "a": 22.0,
                    "b": 8.3,
                    "min": 5.4,
                    "max": 38.6
                  }
                },
                "share": 0.7,
                "min_half_angle_degrees": 2.0,
                "clustering": 0.8,
                "cluster_spacing": 0.15
              }
            },
            {
              "name": "shapes",
              "description": "Secondaries stretched toward their primary; round by default.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d42"
              },
              "default": {
                "elongated_share": 0.0,
                "ellipticity": {
                  "kind": "uniform",
                  "a": 1.2,
                  "b": 1.8,
                  "min": null,
                  "max": null
                }
              }
            },
            {
              "name": "depth_ratio",
              "description": "Depth over diameter every secondary is given, with no wear by age; lower values give shallower secondaries.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.11,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "morphometry",
              "description": "Published fits whose fresh crater rim the secondaries are shaped with.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "lunar",
                  "mars"
                ],
                "descriptions": [
                  "Fresh lunar craters: Fassett et al. (2022) depth and rim height below 15 km, Pike's (1977) complex crater fits above.",
                  "Fresh Martian craters: depth and rim height capped for small craters, Garvin et al.'s (2003) fits for large and complex craters from 7 km."
                ]
              },
              "default": "lunar"
            }
          ],
          "default": {
            "type": "secondaries",
            "seed": 0,
            "onset_count": null,
            "count_fraction": 0.01,
            "size_slope": 4.0,
            "min_diameter": 1.0,
            "max_diameter": null,
            "outer_range": null,
            "min_primary_diameter": 0.0,
            "max_primary_diameter": null,
            "min_age_gyr": 0.0,
            "max_age_gyr": null,
            "manual": true,
            "cell_size_factor": 16.0,
            "rays": {
              "enabled": false,
              "layout": {
                "seed": 0,
                "count": {
                  "kind": "normal",
                  "a": 10.7,
                  "b": 3.1,
                  "min": 6.0,
                  "max": 20.0
                },
                "width_degrees": {
                  "kind": "normal",
                  "a": 22.0,
                  "b": 8.3,
                  "min": 5.4,
                  "max": 38.6
                }
              },
              "share": 0.7,
              "min_half_angle_degrees": 2.0,
              "clustering": 0.8,
              "cluster_spacing": 0.15
            },
            "shapes": {
              "elongated_share": 0.0,
              "ellipticity": {
                "kind": "uniform",
                "a": 1.2,
                "b": 1.8,
                "min": null,
                "max": null
              }
            },
            "depth_ratio": 0.11,
            "morphometry": "lunar"
          }
        },
        {
          "type": "dem_detail",
          "description": "Adds the detail a GeoTIFF DEM has above its own low-pass, to restore measured relief over a raster source read with the same low_pass.",
          "fields": [
            {
              "name": "path",
              "description": "GeoTIFF DEM to take the detail from; relative paths resolve against the configuration's folder.",
              "unit": "",
              "schema": {
                "kind": "string"
              },
              "default": ""
            },
            {
              "name": "band",
              "description": "Band of the file to read, counting from 0.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 0
            },
            {
              "name": "resampling",
              "description": "Interpolation used between the DEM's cells.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "nearest",
                  "bilinear",
                  "cubic"
                ],
                "descriptions": [
                  "The value of the nearest cell centre: blocky, but never mixes values.",
                  "Linear in each axis over the four surrounding cells.",
                  "Keys cubic convolution over the sixteen surrounding cells: the smoothest, for upscaling DEMs."
                ]
              },
              "default": "cubic"
            },
            {
              "name": "scale",
              "description": "Factor each sample is multiplied by, replacing the band's scale from the file's GDAL metadata. Unset keeps the file's.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null
            },
            {
              "name": "offset",
              "description": "Added to each scaled sample, replacing the band's offset from the file's GDAL metadata. Unset keeps the file's.",
              "unit": "m",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null
            },
            {
              "name": "low_pass",
              "description": "Standard deviation in metres of the Gaussian low-pass the detail is measured above; positive, and the same as the raster source's low_pass to restore the DEM whole.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 50.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "weight",
              "description": "Share of the detail added; 1 restores it whole, 0.5 halves it.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 1.0
            }
          ],
          "default": {
            "type": "dem_detail",
            "path": "",
            "band": 0,
            "resampling": "cubic",
            "scale": null,
            "offset": null,
            "low_pass": 50.0,
            "weight": 1.0
          }
        },
        {
          "type": "dunes",
          "description": "Wind-blown dunes added to the terrain: isolated barchans or domes, or fields of transverse, barchanoid or linear crests, with slip faces and optional ripples on them.",
          "fields": [
            {
              "name": "shape",
              "description": "The kind of dune.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "barchan",
                  "dome",
                  "transverse",
                  "barchanoid",
                  "linear"
                ],
                "descriptions": [
                  "Isolated crescents with a slip face and horns downwind; domes below min_width.",
                  "Isolated rounded heaps without a slip face.",
                  "Continuous crests across the wind, each with a slip face.",
                  "Transverse crests bent into linked crescents, as where sand supply rises.",
                  "Symmetric crests along the wind, as under two winds on scarce sand."
                ]
              },
              "default": "barchan"
            },
            {
              "name": "wind_azimuth",
              "description": "Direction the wind blows toward, in radians counter-clockwise from +x (local east of the anchor on a body); slip faces face it.",
              "unit": "rad",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "azimuth_spread",
              "description": "Largest difference of each barchan or dome's wind from the azimuth, in radians.",
              "unit": "rad",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "slip_face_angle",
              "description": "Slope of the lee slip faces, in radians: the sand's angle of repose.",
              "unit": "rad",
              "schema": {
                "kind": "number"
              },
              "default": 0.5585053606381855,
              "minimum": 0.0,
              "exclusive_minimum": true,
              "maximum": 1.5707963267948966,
              "exclusive_maximum": true
            },
            {
              "name": "stoss_slope",
              "description": "Mean slope of the windward faces, in radians; below the slip face angle.",
              "unit": "rad",
              "schema": {
                "kind": "number"
              },
              "default": 0.17453292519943295,
              "minimum": 0.0,
              "exclusive_minimum": true,
              "maximum": 1.5707963267948966,
              "exclusive_maximum": true
            },
            {
              "name": "stoss_exponent",
              "description": "Exponent alpha of the cos^alpha windward profile of dunes; higher is blunter.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 3.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "dome_exponent",
              "description": "Exponent alpha of the cos^alpha profile of domes.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 1.8,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "spacing",
              "description": "Barchans and domes: side of the lattice cells, each holding at most one dune, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 800.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "density",
              "description": "Barchans and domes: chance a cell holds a dune, from 0 to 1.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.5,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "width",
              "description": "Barchans and domes: mean width, horn to horn, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 400.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "width_spread",
              "description": "Barchans and domes: each width varies from (1 - spread) to (1 + spread) times the mean, spread in [0, 1).",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.3,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": true
            },
            {
              "name": "min_width",
              "description": "Barchans: width in metres below which a dune is a dome without a slip face, blending into barchans up to 1.5 times it.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 200.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "height_ratio",
              "description": "Barchans and domes: height over width.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.06666666666666667,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "horn_length",
              "description": "Barchans: how far the horns reach downwind of the crest, in dune heights.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 9.1,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "dome_length",
              "description": "Domes: length along the wind over width.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 2.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "wavelength",
              "description": "Transverse, barchanoid and linear dunes: crest-to-crest spacing, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 550.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "height",
              "description": "Transverse, barchanoid and linear dunes: crest height, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 20.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "sinuosity",
              "description": "Transverse, barchanoid and linear dunes: how far a crest wanders along its length, in wavelengths.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.3,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "defects",
              "description": "Transverse, barchanoid and linear dunes: share of the height that varies along crests, lowering and ending some, from 0 to 1.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.3,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "defect_density",
              "description": "Transverse, barchanoid and linear dunes: pairs of crest ends per metre of crest, so crests break into segments about 1 / defect_density long; 0 for none. Olympia Undae: 0.0027 (Ewing et al. 2010).",
              "unit": "1/m",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "flank_slope",
              "description": "Linear dunes: mean slope of both flanks, in radians.",
              "unit": "rad",
              "schema": {
                "kind": "number"
              },
              "default": 0.3490658503988659,
              "minimum": 0.0,
              "exclusive_minimum": true,
              "maximum": 1.5707963267948966,
              "exclusive_maximum": true
            },
            {
              "name": "seed",
              "description": "Seed of the dunes and ripples; changing it gives a different layout of the same statistics.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 1
            },
            {
              "name": "anchor_x",
              "description": "On a body, the longitude in degrees of the point whose tangent frame the dunes are laid out in; they are true to scale near it and absent on the far hemisphere.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "anchor_y",
              "description": "On a body, the latitude in degrees of the anchor.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "fade",
              "description": "How dunes too fine for the sample spacing fade out, by samples across their width or wavelength.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d15"
              },
              "default": {
                "start_samples": 2.0,
                "end_samples": 4.0,
                "shape": "smoothstep"
              }
            },
            {
              "name": "ripples",
              "description": "Ripples superposed on the dunes.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d43"
              },
              "default": {
                "wavelength": 0.0,
                "height": 0.0,
                "lee_fraction": 0.5,
                "sinuosity": 0.3,
                "slope_coupling": 1.0,
                "interdune_cover": 0.0,
                "defect_density": 0.0,
                "flank_straightening": 0.0,
                "fade": {
                  "start_samples": 2.0,
                  "end_samples": 4.0,
                  "shape": "smoothstep"
                }
              }
            },
            {
              "name": "grainflows",
              "description": "Grainflows on the slip faces: scarps below the brink and lobes below them; off unless cover is set.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d44"
              },
              "default": {
                "cover": 0.0,
                "min_scarp_width": 0.5,
                "max_scarp_width": 0.5,
                "min_scarp_length": 1.0,
                "max_scarp_length": 1.0,
                "min_lobe_width": 0.5,
                "max_lobe_width": 0.5,
                "min_lobe_length": 3.0,
                "max_lobe_length": 3.0,
                "thickness": 0.015,
                "fade": {
                  "start_samples": 2.0,
                  "end_samples": 4.0,
                  "shape": "smoothstep"
                }
              }
            }
          ],
          "default": {
            "type": "dunes",
            "shape": "barchan",
            "wind_azimuth": 0.0,
            "azimuth_spread": 0.0,
            "slip_face_angle": 0.5585053606381855,
            "stoss_slope": 0.17453292519943295,
            "stoss_exponent": 3.0,
            "dome_exponent": 1.8,
            "spacing": 800.0,
            "density": 0.5,
            "width": 400.0,
            "width_spread": 0.3,
            "min_width": 200.0,
            "height_ratio": 0.06666666666666667,
            "horn_length": 9.1,
            "dome_length": 2.0,
            "wavelength": 550.0,
            "height": 20.0,
            "sinuosity": 0.3,
            "defects": 0.3,
            "defect_density": 0.0,
            "flank_slope": 0.3490658503988659,
            "seed": 1,
            "anchor_x": 0.0,
            "anchor_y": 0.0,
            "fade": {
              "start_samples": 2.0,
              "end_samples": 4.0,
              "shape": "smoothstep"
            },
            "ripples": {
              "wavelength": 0.0,
              "height": 0.0,
              "lee_fraction": 0.5,
              "sinuosity": 0.3,
              "slope_coupling": 1.0,
              "interdune_cover": 0.0,
              "defect_density": 0.0,
              "flank_straightening": 0.0,
              "fade": {
                "start_samples": 2.0,
                "end_samples": 4.0,
                "shape": "smoothstep"
              }
            },
            "grainflows": {
              "cover": 0.0,
              "min_scarp_width": 0.5,
              "max_scarp_width": 0.5,
              "min_scarp_length": 1.0,
              "max_scarp_length": 1.0,
              "min_lobe_width": 0.5,
              "max_lobe_width": 0.5,
              "min_lobe_length": 3.0,
              "max_lobe_length": 3.0,
              "thickness": 0.015,
              "fade": {
                "start_samples": 2.0,
                "end_samples": 4.0,
                "shape": "smoothstep"
              }
            }
          }
        },
        {
          "type": "sand_fill",
          "description": "Sand pooled in the lows of the ground beneath: cracks, troughs and hollows between rises, laying sand over the material map.",
          "fields": [
            {
              "name": "reach",
              "description": "Radius in metres of the surroundings a low is measured against: two rings, at half the reach and at the reach.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 10.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "fill",
              "description": "Share of a low's depth below its surroundings that sand fills, 0 to 1.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.6,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "max_thickness",
              "description": "The thickest the sand gets, in metres, approached smoothly.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.5,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "cover_thickness",
              "description": "Sand thickness in metres from which it fully covers the ground in the material map.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.02,
              "minimum": 0.0,
              "exclusive_minimum": true
            }
          ],
          "default": {
            "type": "sand_fill",
            "reach": 10.0,
            "fill": 0.6,
            "max_thickness": 0.5,
            "cover_thickness": 0.02
          }
        },
        {
          "type": "pavement",
          "description": "Fractured bedrock: polygonal plates, each tilted and stepped, parted by cracks or raised ridges, split again by finer octaves of cracks; lays bedrock over the material map.",
          "fields": [
            {
              "name": "plate_size",
              "description": "Mean plate width, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "jitter",
              "description": "How far plate centres stray from a square lattice, from 0 (square plates) to 1.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "warp",
              "description": "Bend and roughness of the plate edges, in plate sizes.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.15,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "crack_width",
              "description": "Width of the cracks between plates, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.05,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "crack_depth",
              "description": "Depth of the cracks, or height of the ridges when raised, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.05,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "raised",
              "description": "Whether plates are parted by raised ridges instead of cracks.",
              "unit": "",
              "schema": {
                "kind": "boolean"
              },
              "default": false
            },
            {
              "name": "edge_rounding",
              "description": "Width of the rounded shoulder beside each crack, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.02,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "max_tilt",
              "description": "Largest tilt of a plate, in radians.",
              "unit": "rad",
              "schema": {
                "kind": "number"
              },
              "default": 0.05,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.5707963267948966,
              "exclusive_maximum": true
            },
            {
              "name": "max_step",
              "description": "Largest height offset of a plate, up or down, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.03,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "octaves",
              "description": "Crack octaves, 1 to 8: each finer octave splits every plate again, its cracks ending at the plate's edges.",
              "unit": "",
              "schema": {
                "kind": "integer"
              },
              "default": 1,
              "minimum": 1.0,
              "exclusive_minimum": false,
              "maximum": 8.0,
              "exclusive_maximum": false
            },
            {
              "name": "lacunarity",
              "description": "Plate size ratio between octaves, above 1.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 2.0,
              "minimum": 1.0,
              "exclusive_minimum": true
            },
            {
              "name": "gain",
              "description": "Ratio of crack width, depth, rounding, tilt and step between octaves, in (0, 1].",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.5,
              "minimum": 0.0,
              "exclusive_minimum": true,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "seed",
              "description": "Seed of the plates.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 1
            },
            {
              "name": "exposure",
              "description": "Shows plates only where the ground beneath is bare bedrock, fading out over soil; unset shows them everywhere.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d29"
                },
                "default": {
                  "reach": 12.0,
                  "rise_soil": 0.01,
                  "rise_boulder": 0.035,
                  "slope_soil": 0.2,
                  "slope_boulder": 0.4,
                  "floor_cover": 0.0,
                  "floor_patch": 60.0,
                  "seed": 0
                }
              },
              "default": null
            },
            {
              "name": "exposure_spacing",
              "description": "Spacing in metres the ground is read at for the exposure field.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "anchor_x",
              "description": "On a body, the longitude in degrees of the point whose tangent frame the plates are laid out in.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "anchor_y",
              "description": "On a body, the latitude in degrees of the anchor.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "fade",
              "description": "How plates and cracks too fine for the sample spacing fade out, by samples across them.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d15"
              },
              "default": {
                "start_samples": 2.0,
                "end_samples": 4.0,
                "shape": "smoothstep"
              }
            }
          ],
          "default": {
            "type": "pavement",
            "plate_size": 1.0,
            "jitter": 1.0,
            "warp": 0.15,
            "crack_width": 0.05,
            "crack_depth": 0.05,
            "raised": false,
            "edge_rounding": 0.02,
            "max_tilt": 0.05,
            "max_step": 0.03,
            "octaves": 1,
            "lacunarity": 2.0,
            "gain": 0.5,
            "seed": 1,
            "exposure": null,
            "exposure_spacing": 1.0,
            "anchor_x": 0.0,
            "anchor_y": 0.0,
            "fade": {
              "start_samples": 2.0,
              "end_samples": 4.0,
              "shape": "smoothstep"
            }
          }
        },
        {
          "type": "strata",
          "description": "Layered rock: the ground beneath terraced into dipping beds, each a flat bench below a cliff, so hills become stepped buttes and mesas; lays bedrock over the cliffs.",
          "fields": [
            {
              "name": "bed_thickness",
              "description": "Mean thickness of a bed, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 2.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "thickness_variation",
              "description": "How far each bed boundary strays from even spacing, in bed thicknesses, in [0, 1).",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.4,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": true
            },
            {
              "name": "dip",
              "description": "Dip of the beds from horizontal, in radians, below 90 deg.",
              "unit": "rad",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.5707963267948966,
              "exclusive_maximum": true
            },
            {
              "name": "dip_azimuth",
              "description": "Direction the beds dip toward, in radians counter-clockwise from +x (local east on a body).",
              "unit": "rad",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "sharpness",
              "description": "How sharply each bed is cut into a flat bench and a cliff, at least 1; 1 leaves the ground as it is.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 4.0,
              "minimum": 1.0,
              "exclusive_minimum": false
            },
            {
              "name": "strength",
              "description": "Share of the terracing applied, in [0, 1].",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "cliff_share",
              "description": "Share of each bed's height, at its top, laid as bedrock in the material map, in (0, 1].",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.3,
              "minimum": 0.0,
              "exclusive_minimum": true,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "seed",
              "description": "Seed of the bed boundaries.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 1
            },
            {
              "name": "anchor_x",
              "description": "On a body, the longitude in degrees of the point whose tangent frame the dip is measured in.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "anchor_y",
              "description": "On a body, the latitude in degrees of the anchor.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "hard_share",
              "description": "Share of the beds that are hard rock, from 0 to 1: hard beds form benches and cliffs of bedrock, soft beds slopes cut at soft_sharpness without bedrock.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "soft_sharpness",
              "description": "How sharply soft beds are cut into benches and slopes, at least 1; 1 leaves them as they are.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 1.0,
              "exclusive_minimum": false
            }
          ],
          "default": {
            "type": "strata",
            "bed_thickness": 2.0,
            "thickness_variation": 0.4,
            "dip": 0.0,
            "dip_azimuth": 0.0,
            "sharpness": 4.0,
            "strength": 1.0,
            "cliff_share": 0.3,
            "seed": 1,
            "anchor_x": 0.0,
            "anchor_y": 0.0,
            "hard_share": 1.0,
            "soft_sharpness": 1.0
          }
        },
        {
          "type": "sand_shadow",
          "description": "Sand shadows: a tapering sand tail in the lee of each boulder of the nearest boulder layer before this one; lays sand over the material map.",
          "fields": [
            {
              "name": "wind_azimuth",
              "description": "Where the wind blows toward, in radians counter-clockwise from +x (local east on a body).",
              "unit": "rad",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "length_ratio",
              "description": "Length of a tail beyond its boulder over the boulder's width; 1.1 is the reattachment length behind a dome, and modelled shadow dunes run 1.3 to 5.6, longer in lighter winds.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 1.1,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "flank_angle",
              "description": "Slope of a tail's flanks, in radians, at most the angle of repose (about 32 deg for dry sand); sets the tail's height with the boulder's width.",
              "unit": "rad",
              "schema": {
                "kind": "number"
              },
              "default": 0.5585053606381855,
              "minimum": 0.0,
              "exclusive_minimum": true,
              "maximum": 1.5707963267948966,
              "exclusive_maximum": true
            },
            {
              "name": "min_diameter",
              "description": "Smallest boulder with a tail, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "cover_thickness",
              "description": "Sand depth that fully covers the ground in the material map, in metres.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.02,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "fade",
              "description": "How tails behind boulders too small for the sample spacing fade out, by samples across the boulder.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d15"
              },
              "default": {
                "start_samples": 2.0,
                "end_samples": 4.0,
                "shape": "smoothstep"
              }
            }
          ],
          "default": {
            "type": "sand_shadow",
            "wind_azimuth": 0.0,
            "length_ratio": 1.1,
            "flank_angle": 0.5585053606381855,
            "min_diameter": 0.0,
            "cover_thickness": 0.02,
            "fade": {
              "start_samples": 2.0,
              "end_samples": 4.0,
              "shape": "smoothstep"
            }
          }
        }
      ]
    },
    "d46": {
      "kind": "object",
      "fields": [
        {
          "name": "width",
          "description": "Columns of the grid.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 513,
          "minimum": 2.0,
          "exclusive_minimum": false,
          "maximum": 65536.0,
          "exclusive_maximum": false
        },
        {
          "name": "height",
          "description": "Rows of the grid.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 513,
          "minimum": 2.0,
          "exclusive_minimum": false,
          "maximum": 65536.0,
          "exclusive_maximum": false
        },
        {
          "name": "pixel_size",
          "description": "Cell size in metres; on a body, metres along a meridian, the same in degrees of longitude.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 2.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "centre_x",
          "description": "Centre of the grid along x in surface coordinates; the longitude in degrees on a body.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0
        },
        {
          "name": "centre_y",
          "description": "Centre of the grid along y in surface coordinates; the latitude in degrees on a body.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0
        }
      ]
    },
    "d45": {
      "kind": "choice",
      "alternatives": [
        {
          "type": "heightmap",
          "description": "Writes the generated heights as a float32 GeoTIFF, with a raster base's projection.",
          "fields": [
            {
              "name": "path",
              "description": "GeoTIFF file to write; relative paths resolve against the output folder (the CLI's --output-dir), else the configuration's folder.",
              "unit": "",
              "schema": {
                "kind": "string"
              },
              "default": ""
            },
            {
              "name": "region",
              "description": "Grid of square cells the file covers; unset for the base's grid.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d46"
                },
                "default": {
                  "width": 513,
                  "height": 513,
                  "pixel_size": 2.0,
                  "centre_x": 0.0,
                  "centre_y": 0.0
                }
              },
              "default": null
            },
            {
              "name": "compression",
              "description": "Compression of the file; compressed files use the floating-point predictor.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "none",
                  "lzw",
                  "deflate",
                  "packbits"
                ],
                "descriptions": [
                  "Uncompressed: the largest files.",
                  "Lossless LZW compression, widely supported.",
                  "Lossless Deflate (zlib) compression.",
                  "PackBits run-length compression; read only, so outputs cannot use it."
                ]
              },
              "default": "lzw"
            },
            {
              "name": "tile_size",
              "description": "Width and height of the file's tiles in pixels; a positive multiple of 16.",
              "unit": "px",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 256,
              "minimum": 16.0,
              "exclusive_minimum": false
            }
          ],
          "default": {
            "type": "heightmap",
            "path": "",
            "region": null,
            "compression": "lzw",
            "tile_size": 256
          }
        },
        {
          "type": "crater_list",
          "description": "Writes the generated and manual craters as CSV or JSON.",
          "fields": [
            {
              "name": "path",
              "description": "File to write; relative paths resolve against the output folder (the CLI's --output-dir), else the configuration's folder.",
              "unit": "",
              "schema": {
                "kind": "string"
              },
              "default": ""
            },
            {
              "name": "format",
              "description": "Format of the file; when not given, .json paths are written as JSON and others as CSV.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "csv",
                  "json"
                ],
                "descriptions": [
                  "Comma-separated values, one row per item.",
                  "A JSON document."
                ]
              },
              "default": "csv"
            },
            {
              "name": "region",
              "description": "Grid of square cells the features are listed over; unset for the base's grid, or without a base the whole body on a body.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d46"
                },
                "default": {
                  "width": 513,
                  "height": 513,
                  "pixel_size": 2.0,
                  "centre_x": 0.0,
                  "centre_y": 0.0
                }
              },
              "default": null
            },
            {
              "name": "spacing",
              "description": "Sample spacing in metres the features are listed at, as a heightmap of that pixel size applies them; unset for the region's pixel size. A whole-body list needs it.",
              "unit": "m",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": true
            }
          ],
          "default": {
            "type": "crater_list",
            "path": "",
            "format": "csv",
            "region": null,
            "spacing": null
          }
        },
        {
          "type": "boulder_list",
          "description": "Writes every boulder the layers placed, models and relief alike, as CSV or JSON.",
          "fields": [
            {
              "name": "path",
              "description": "File to write; relative paths resolve against the output folder (the CLI's --output-dir), else the configuration's folder.",
              "unit": "",
              "schema": {
                "kind": "string"
              },
              "default": ""
            },
            {
              "name": "format",
              "description": "Format of the file; when not given, .json paths are written as JSON and others as CSV.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "csv",
                  "json"
                ],
                "descriptions": [
                  "Comma-separated values, one row per item.",
                  "A JSON document."
                ]
              },
              "default": "csv"
            },
            {
              "name": "region",
              "description": "Grid of square cells the features are listed over; unset for the base's grid, or without a base the whole body on a body.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d46"
                },
                "default": {
                  "width": 513,
                  "height": 513,
                  "pixel_size": 2.0,
                  "centre_x": 0.0,
                  "centre_y": 0.0
                }
              },
              "default": null
            },
            {
              "name": "spacing",
              "description": "Sample spacing in metres the features are listed at, as a heightmap of that pixel size applies them; unset for the region's pixel size. A whole-body list needs it.",
              "unit": "m",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": true
            }
          ],
          "default": {
            "type": "boulder_list",
            "path": "",
            "format": "csv",
            "region": null,
            "spacing": null
          }
        },
        {
          "type": "boulder_models",
          "description": "Writes the boulders placed as 3D models on the ground: as a glTF scene (.glb, or .gltf with a .bin) drawing each shape once per boulder, as OBJ (.obj with an .mtl) with one object per boulder, or as one merged STL mesh (.stl).",
          "fields": [
            {
              "name": "path",
              "description": "File to write, ending in .glb, .gltf, .obj or .stl; relative paths resolve against the output folder (the CLI's --output-dir), else the configuration's folder.",
              "unit": "",
              "schema": {
                "kind": "string"
              },
              "default": ""
            },
            {
              "name": "crease_angle",
              "description": "Angle in degrees, from 0 to 180: vertices are split where faces meet at more than it, giving sharp edges.",
              "unit": "deg",
              "schema": {
                "kind": "number"
              },
              "default": 60.0,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 180.0,
              "exclusive_maximum": false
            },
            {
              "name": "instanced",
              "description": "Writes each shared shape once and draws it per boulder (glTF instances, OBJ objects); false writes every boulder as its own placed mesh, for tools without instancing.",
              "unit": "",
              "schema": {
                "kind": "boolean"
              },
              "default": true
            },
            {
              "name": "region",
              "description": "Grid of square cells the features are listed over; unset for the base's grid, or without a base the whole body on a body.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d46"
                },
                "default": {
                  "width": 513,
                  "height": 513,
                  "pixel_size": 2.0,
                  "centre_x": 0.0,
                  "centre_y": 0.0
                }
              },
              "default": null
            },
            {
              "name": "spacing",
              "description": "Sample spacing in metres the features are listed at, as a heightmap of that pixel size applies them; unset for the region's pixel size. A whole-body list needs it.",
              "unit": "m",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": true
            }
          ],
          "default": {
            "type": "boulder_models",
            "path": "",
            "crease_angle": 60.0,
            "instanced": true,
            "region": null,
            "spacing": null
          }
        },
        {
          "type": "albedo",
          "description": "Writes the albedo as a float32 GeoTIFF of one band or three (red, green, blue).",
          "fields": [
            {
              "name": "path",
              "description": "GeoTIFF file to write; relative paths resolve against the output folder (the CLI's --output-dir), else the configuration's folder.",
              "unit": "",
              "schema": {
                "kind": "string"
              },
              "default": ""
            },
            {
              "name": "region",
              "description": "Grid of square cells the file covers; unset for the base's grid.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d46"
                },
                "default": {
                  "width": 513,
                  "height": 513,
                  "pixel_size": 2.0,
                  "centre_x": 0.0,
                  "centre_y": 0.0
                }
              },
              "default": null
            },
            {
              "name": "compression",
              "description": "Compression of the file; compressed files use the floating-point predictor.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "none",
                  "lzw",
                  "deflate",
                  "packbits"
                ],
                "descriptions": [
                  "Uncompressed: the largest files.",
                  "Lossless LZW compression, widely supported.",
                  "Lossless Deflate (zlib) compression.",
                  "PackBits run-length compression; read only, so outputs cannot use it."
                ]
              },
              "default": "lzw"
            },
            {
              "name": "tile_size",
              "description": "Width and height of the file's tiles in pixels; a positive multiple of 16.",
              "unit": "px",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 256,
              "minimum": 16.0,
              "exclusive_minimum": false
            }
          ],
          "default": {
            "type": "albedo",
            "path": "",
            "region": null,
            "compression": "lzw",
            "tile_size": 256
          }
        },
        {
          "type": "mesh",
          "description": "Writes the whole body, from six cube faces: a mesh as glTF (.glb or .gltf), OBJ (.obj) or STL (.stl), or a Gaskell ICQ shape model in kilometres (.icq), whose Q is cells_per_face.",
          "fields": [
            {
              "name": "path",
              "description": "File to write, ending in .glb, .gltf, .obj, .stl or .icq; relative paths resolve against the output folder (the CLI's --output-dir), else the configuration's folder.",
              "unit": "",
              "schema": {
                "kind": "string"
              },
              "default": ""
            },
            {
              "name": "cells_per_face",
              "description": "Quads along each edge of the six cube faces, 1 to 4096; more give a finer mesh, with two triangles per quad.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 128,
              "minimum": 1.0,
              "exclusive_minimum": false,
              "maximum": 4096.0,
              "exclusive_maximum": false
            },
            {
              "name": "spacing",
              "description": "Sample spacing in metres the heights are evaluated at, which sets the finest features kept; unset uses a quad's side at a face's centre.",
              "unit": "m",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": true
            }
          ],
          "default": {
            "type": "mesh",
            "path": "",
            "cells_per_face": 128,
            "spacing": null
          }
        },
        {
          "type": "terrain_mesh",
          "description": "Writes the generated heights as a triangle mesh, a vertex per cell with data, as glTF (.glb or .gltf), OBJ (.obj) or STL (.stl), in the frame boulder models are written in.",
          "fields": [
            {
              "name": "path",
              "description": "File to write, ending in .glb, .gltf, .obj or .stl; relative paths resolve against the output folder (the CLI's --output-dir), else the configuration's folder.",
              "unit": "",
              "schema": {
                "kind": "string"
              },
              "default": ""
            },
            {
              "name": "region",
              "description": "Grid of square cells the mesh covers; unset for the base's grid.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d46"
                },
                "default": {
                  "width": 513,
                  "height": 513,
                  "pixel_size": 2.0,
                  "centre_x": 0.0,
                  "centre_y": 0.0
                }
              },
              "default": null
            }
          ],
          "default": {
            "type": "terrain_mesh",
            "path": "",
            "region": null
          }
        },
        {
          "type": "materials",
          "description": "Writes the material map as a float32 GeoTIFF of five bands: the share of soil, sand, dust, bedrock and rock at each cell.",
          "fields": [
            {
              "name": "path",
              "description": "GeoTIFF file to write; relative paths resolve against the output folder (the CLI's --output-dir), else the configuration's folder.",
              "unit": "",
              "schema": {
                "kind": "string"
              },
              "default": ""
            },
            {
              "name": "region",
              "description": "Grid of square cells the file covers; unset for the base's grid.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d46"
                },
                "default": {
                  "width": 513,
                  "height": 513,
                  "pixel_size": 2.0,
                  "centre_x": 0.0,
                  "centre_y": 0.0
                }
              },
              "default": null
            },
            {
              "name": "compression",
              "description": "Compression of the file; compressed files use the floating-point predictor.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "none",
                  "lzw",
                  "deflate",
                  "packbits"
                ],
                "descriptions": [
                  "Uncompressed: the largest files.",
                  "Lossless LZW compression, widely supported.",
                  "Lossless Deflate (zlib) compression.",
                  "PackBits run-length compression; read only, so outputs cannot use it."
                ]
              },
              "default": "lzw"
            },
            {
              "name": "tile_size",
              "description": "Width and height of the file's tiles in pixels; a positive multiple of 16.",
              "unit": "px",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 256,
              "minimum": 16.0,
              "exclusive_minimum": false
            }
          ],
          "default": {
            "type": "materials",
            "path": "",
            "region": null,
            "compression": "lzw",
            "tile_size": 256
          }
        },
        {
          "type": "photometry",
          "description": "Writes the Hapke parameters the materials mix to as a float32 GeoTIFF of four bands: single-scattering albedo, b, c and roughness in degrees.",
          "fields": [
            {
              "name": "path",
              "description": "GeoTIFF file to write; relative paths resolve against the output folder (the CLI's --output-dir), else the configuration's folder.",
              "unit": "",
              "schema": {
                "kind": "string"
              },
              "default": ""
            },
            {
              "name": "region",
              "description": "Grid of square cells the file covers; unset for the base's grid.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "ref",
                  "ref": "d46"
                },
                "default": {
                  "width": 513,
                  "height": 513,
                  "pixel_size": 2.0,
                  "centre_x": 0.0,
                  "centre_y": 0.0
                }
              },
              "default": null
            },
            {
              "name": "compression",
              "description": "Compression of the file; compressed files use the floating-point predictor.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "none",
                  "lzw",
                  "deflate",
                  "packbits"
                ],
                "descriptions": [
                  "Uncompressed: the largest files.",
                  "Lossless LZW compression, widely supported.",
                  "Lossless Deflate (zlib) compression.",
                  "PackBits run-length compression; read only, so outputs cannot use it."
                ]
              },
              "default": "lzw"
            },
            {
              "name": "tile_size",
              "description": "Width and height of the file's tiles in pixels; a positive multiple of 16.",
              "unit": "px",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 256,
              "minimum": 16.0,
              "exclusive_minimum": false
            }
          ],
          "default": {
            "type": "photometry",
            "path": "",
            "region": null,
            "compression": "lzw",
            "tile_size": 256
          }
        }
      ]
    },
    "d49": {
      "kind": "object",
      "fields": [
        {
          "name": "enabled",
          "description": "Adds fractal detail below the map's resolution; off leaves the interpolated map as it is.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": true
        },
        {
          "name": "seed",
          "description": "Seed of the detail noise; changing it gives a different pattern of the same roughness.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        },
        {
          "name": "octaves",
          "description": "Octaves of detail, 1 to 16, from half the map's cell size down, each half the wavelength of the one before.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 4,
          "minimum": 1.0,
          "exclusive_minimum": false,
          "maximum": 16.0,
          "exclusive_maximum": false
        },
        {
          "name": "scale",
          "description": "Factor on the RMS of every octave, not negative; 0 adds no detail, higher values give a more mottled albedo.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "hurst",
          "description": "Hurst exponent, in [0, 1], used instead of the one measured from the map; lower values keep more contrast at fine scales. Unset uses the measured one.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "fade",
          "description": "How octaves of detail too fine for the sample spacing fade out.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d15"
          },
          "default": {
            "start_samples": 2.0,
            "end_samples": 4.0,
            "shape": "smoothstep"
          }
        }
      ]
    },
    "d48": {
      "kind": "choice",
      "alternatives": [
        {
          "type": "synthetic",
          "description": "A base colour in hue, saturation and value, each varied by noise: an albedo for terrain without data.",
          "fields": [
            {
              "name": "rgb",
              "description": "Gives three bands, red, green and blue, from the colour; off gives one band of the value alone, ignoring hue and saturation.",
              "unit": "",
              "schema": {
                "kind": "boolean"
              },
              "default": false
            },
            {
              "name": "hue",
              "description": "Hue of the base colour in degrees, wrapping around; used with rgb only.",
              "unit": "deg",
              "schema": {
                "kind": "number"
              },
              "default": 0.0
            },
            {
              "name": "saturation",
              "description": "Saturation of the base colour, from 0 for grey to 1; used with rgb only.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "value",
              "description": "Reflectance of the brightest band, from 0 to 1; the one band's value without rgb. Higher values give a brighter surface.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.11,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "hue_noise",
              "description": "Noise layers, 0 to 8, whose sum in degrees is added to the hue; used with rgb only.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "ref",
                  "ref": "d3"
                },
                "default": {
                  "enabled": true,
                  "basis": "perlin",
                  "fractal": "fbm",
                  "blend": "add",
                  "seed": 0,
                  "wavelength": 1000.0,
                  "amplitude": 100.0,
                  "octaves": 8,
                  "lacunarity": 2.0,
                  "gain": 0.5,
                  "hurst": null,
                  "offset": 1.0,
                  "warp_amplitude": 0.0,
                  "warp_wavelength": 500.0
                }
              },
              "default": []
            },
            {
              "name": "saturation_noise",
              "description": "Noise layers, 0 to 8, added to the saturation, which is then clamped to [0, 1]; used with rgb only.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "ref",
                  "ref": "d3"
                },
                "default": {
                  "enabled": true,
                  "basis": "perlin",
                  "fractal": "fbm",
                  "blend": "add",
                  "seed": 0,
                  "wavelength": 1000.0,
                  "amplitude": 100.0,
                  "octaves": 8,
                  "lacunarity": 2.0,
                  "gain": 0.5,
                  "hurst": null,
                  "offset": 1.0,
                  "warp_amplitude": 0.0,
                  "warp_wavelength": 500.0
                }
              },
              "default": []
            },
            {
              "name": "value_noise",
              "description": "Noise layers, 0 to 8: the value is multiplied by 1 plus their sum and clamped to [0, 1], so their amplitude sets the relative contrast.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "ref",
                  "ref": "d3"
                },
                "default": {
                  "enabled": true,
                  "basis": "perlin",
                  "fractal": "fbm",
                  "blend": "add",
                  "seed": 0,
                  "wavelength": 1000.0,
                  "amplitude": 100.0,
                  "octaves": 8,
                  "lacunarity": 2.0,
                  "gain": 0.5,
                  "hurst": null,
                  "offset": 1.0,
                  "warp_amplitude": 0.0,
                  "warp_wavelength": 500.0
                }
              },
              "default": []
            }
          ],
          "default": {
            "type": "synthetic",
            "rgb": false,
            "hue": 0.0,
            "saturation": 0.0,
            "value": 0.11,
            "hue_noise": [],
            "saturation_noise": [],
            "value_noise": []
          }
        },
        {
          "type": "raster",
          "description": "Albedo read from one or three bands of a GeoTIFF in the terrain's projection, such as an orbital albedo map.",
          "fields": [
            {
              "name": "path",
              "description": "GeoTIFF albedo map in the terrain's projected coordinates; relative paths resolve against the configuration's folder.",
              "unit": "",
              "schema": {
                "kind": "string"
              },
              "default": ""
            },
            {
              "name": "bands",
              "description": "Bands of the file to read, counting from 0: one for a single albedo band, or three for red, green and blue.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "integer",
                  "minimum": 0
                },
                "default": 0
              },
              "default": [
                0
              ]
            },
            {
              "name": "scale",
              "description": "Factor each sample is multiplied by, replacing the band's scale from the file's GDAL metadata, as for maps stored as integers. Unset keeps the file's.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null
            },
            {
              "name": "offset",
              "description": "Added to each scaled sample, replacing the band's offset from the file's GDAL metadata. Unset keeps the file's.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null
            },
            {
              "name": "resampling",
              "description": "Interpolation used to sample the map at the terrain's points.",
              "unit": "",
              "schema": {
                "kind": "enum",
                "choices": [
                  "nearest",
                  "bilinear",
                  "cubic"
                ],
                "descriptions": [
                  "The value of the nearest cell centre: blocky, but never mixes values.",
                  "Linear in each axis over the four surrounding cells.",
                  "Keys cubic convolution over the sixteen surrounding cells: the smoothest, for upscaling DEMs."
                ]
              },
              "default": "cubic"
            },
            {
              "name": "detail",
              "description": "Fractal detail below the map's resolution, continuing the map's own measured roughness to finer scales.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d49"
              },
              "default": {
                "enabled": true,
                "seed": 0,
                "octaves": 4,
                "scale": 1.0,
                "hurst": null,
                "fade": {
                  "start_samples": 2.0,
                  "end_samples": 4.0,
                  "shape": "smoothstep"
                }
              }
            }
          ],
          "default": {
            "type": "raster",
            "path": "",
            "bands": [
              0
            ],
            "scale": null,
            "offset": null,
            "resampling": "cubic",
            "detail": {
              "enabled": true,
              "seed": 0,
              "octaves": 4,
              "scale": 1.0,
              "hurst": null,
              "fade": {
                "start_samples": 2.0,
                "end_samples": 4.0,
                "shape": "smoothstep"
              }
            }
          }
        }
      ]
    },
    "d51": {
      "kind": "object",
      "fields": [
        {
          "name": "streaks",
          "description": "Share of the excess radial streaks take away between filaments, from 0 to 1, breaking ejecta, rays and interiors into fine streaks; 0 leaves them smooth.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "streak_width_degrees",
          "description": "Typical width of a filament around the crater, in degrees.",
          "unit": "deg",
          "schema": {
            "kind": "number"
          },
          "default": 3.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "streak_length_radii",
          "description": "Typical length of a filament outward from the crater, in crater radii.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.5,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "continuous_radii",
          "description": "How far beyond the rim the ejecta stay continuous before breaking into filaments, in crater radii; 0 streaks them from the rim.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "lobes",
          "description": "How far the ejecta's edge wanders in and out, as a share of its reach from 0 to 0.9; 0 keeps it circular.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 0.9,
          "exclusive_maximum": false
        },
        {
          "name": "lobe_count",
          "description": "Typical number of lobes around a crater, 1 to 64.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 8,
          "minimum": 1.0,
          "exclusive_minimum": false,
          "maximum": 64.0,
          "exclusive_maximum": false
        },
        {
          "name": "floor_share",
          "description": "Interior excess on the floor over that at the rim, from 0 to 1; 1 keeps the interior even, lower values brighten the walls over the floor.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "seed",
          "description": "Varies every crater's texture.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        }
      ]
    },
    "d53": {
      "kind": "object",
      "fields": [
        {
          "name": "share",
          "description": "Share of craters, from 0 to 1, with the zone.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "change",
          "description": "Reflectance change relative to the pre-impact surface, drawn per crater; above -1, negative values darken.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "constant",
            "a": 0.0,
            "b": 0.0,
            "min": null,
            "max": null
          }
        },
        {
          "name": "coefficient",
          "description": "Coefficient of the zone's reach from the crater's centre, coefficient D^exponent metres for diameter D in metres; positive.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "exponent",
          "description": "Exponent of the diameter in the zone's reach; positive.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "scale",
          "description": "Factor on the reach, drawn per crater; positive and bounded, a wider distribution gives more varied zones.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "constant",
            "a": 0.0,
            "b": 0.0,
            "min": null,
            "max": null
          }
        },
        {
          "name": "raggedness",
          "description": "Share of the reach, from 0 up to 1, that fingers of the edge pull in by; 0 keeps the zone round, higher values make it ray-like.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": true
        },
        {
          "name": "finger_width_degrees",
          "description": "Typical width of the edge's fingers around the crater, in degrees.",
          "unit": "deg",
          "schema": {
            "kind": "number"
          },
          "default": 10.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "feather",
          "description": "Share of the reach, from 0 to 1 excluding 0, over which the zone fades out at its edge.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.3,
          "minimum": 0.0,
          "exclusive_minimum": true,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "retention_myr",
          "description": "How long the zone lasts, in Myr, fading like the bright material; unset lasts as long as the bright material.",
          "unit": "Myr",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null,
          "minimum": 0.0,
          "exclusive_minimum": true
        }
      ]
    },
    "d54": {
      "kind": "object",
      "fields": [
        {
          "name": "enabled",
          "description": "Gives the distal zones shadows behind rises such as crater rims, read from the terrain's heights; off by default.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": false
        },
        {
          "name": "jet_angle_degrees",
          "description": "Steepest angle in degrees, between 0 and 90 excluded, at which the jet forming the distal zones can drop behind a rise; lower values give longer shadows. Illustrative.",
          "unit": "deg",
          "schema": {
            "kind": "number"
          },
          "default": 3.0,
          "minimum": 0.0,
          "exclusive_minimum": true,
          "maximum": 90.0,
          "exclusive_maximum": true
        },
        {
          "name": "depth",
          "description": "Depth in metres of the ground below the jet at which the shadow is full; positive. Illustrative.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.5,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "azimuths",
          "description": "Rays around a crater the ground is sampled on, 8 to 8192.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 720,
          "minimum": 8.0,
          "exclusive_minimum": false,
          "maximum": 8192.0,
          "exclusive_maximum": false
        },
        {
          "name": "radial_samples",
          "description": "Samples along each ray out to the distal zones' reach, 8 to 8192.",
          "unit": "",
          "schema": {
            "kind": "integer"
          },
          "default": 400,
          "minimum": 8.0,
          "exclusive_minimum": false,
          "maximum": 8192.0,
          "exclusive_maximum": false
        }
      ]
    },
    "d52": {
      "kind": "object",
      "fields": [
        {
          "name": "enabled",
          "description": "Gives new small craters the reflectance zones of LROC temporal pairs; off by default.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": false
        },
        {
          "name": "max_diameter",
          "description": "Largest crater diameter, in metres, with zones; the published fits stop near 43 m.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 50.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "mature_depth",
          "description": "Depth in metres of mature regolith; only craters excavating deeper get the proximal high reflectance zone.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "excavation_ratio",
          "description": "Excavation depth over crater diameter; positive.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.1,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "proximal_high",
          "description": "Proximal high reflectance zone: immature ejecta, +12% to a median 1.5 D.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d53"
          },
          "default": {
            "share": 1.0,
            "change": {
              "kind": "normal",
              "a": 0.12,
              "b": 0.09,
              "min": 0.01,
              "max": 0.5
            },
            "coefficient": 1.5,
            "exponent": 1.0,
            "scale": {
              "kind": "log_normal",
              "a": 1.0,
              "b": 0.82,
              "min": 0.4,
              "max": 5.0
            },
            "raggedness": 0.3,
            "finger_width_degrees": 25.0,
            "feather": 0.3,
            "retention_myr": null
          }
        },
        {
          "name": "proximal_low",
          "description": "Proximal low reflectance zone: -9% to a median 2.9 D, around nearly every crater.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d53"
          },
          "default": {
            "share": 1.0,
            "change": {
              "kind": "normal",
              "a": -0.09,
              "b": 0.04,
              "min": -0.2,
              "max": -0.01
            },
            "coefficient": 2.9,
            "exponent": 1.0,
            "scale": {
              "kind": "log_normal",
              "a": 1.0,
              "b": 0.44,
              "min": 0.5,
              "max": 3.0
            },
            "raggedness": 0.3,
            "finger_width_degrees": 20.0,
            "feather": 0.3,
            "retention_myr": 0.081
          }
        },
        {
          "name": "distal_high",
          "description": "Distal high reflectance zone: +1% to +4% to 0.52 D^2.5 m, around 24% of craters.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d53"
          },
          "default": {
            "share": 0.24,
            "change": {
              "kind": "uniform",
              "a": 0.01,
              "b": 0.04,
              "min": null,
              "max": null
            },
            "coefficient": 0.52,
            "exponent": 2.5,
            "scale": {
              "kind": "constant",
              "a": 1.0,
              "b": 0.0,
              "min": null,
              "max": null
            },
            "raggedness": 0.5,
            "finger_width_degrees": 8.0,
            "feather": 0.4,
            "retention_myr": 0.081
          }
        },
        {
          "name": "distal_low",
          "description": "Distal low reflectance zone: -2% to -6%, ray-like, to 5.03 D^2 m, around 84% of craters.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d53"
          },
          "default": {
            "share": 0.84,
            "change": {
              "kind": "uniform",
              "a": -0.06,
              "b": -0.02,
              "min": null,
              "max": null
            },
            "coefficient": 5.03,
            "exponent": 2.0,
            "scale": {
              "kind": "constant",
              "a": 1.0,
              "b": 0.0,
              "min": null,
              "max": null
            },
            "raggedness": 0.6,
            "finger_width_degrees": 8.0,
            "feather": 0.6,
            "retention_myr": 0.081
          }
        },
        {
          "name": "shadows",
          "description": "Shadows of rises in the distal zones; off by default.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d54"
          },
          "default": {
            "enabled": false,
            "jet_angle_degrees": 3.0,
            "depth": 0.5,
            "azimuths": 720,
            "radial_samples": 400
          }
        },
        {
          "name": "seed",
          "description": "Varies every crater's zones.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        }
      ]
    },
    "d56": {
      "kind": "object",
      "fields": [
        {
          "name": "enabled",
          "description": "Draws an impact angle and direction per crater that shape its rays; off treats every impact as vertical.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": true
        },
        {
          "name": "heading",
          "description": "Downrange direction of every impact, in radians counter-clockwise from east; unset draws a random heading per crater.",
          "unit": "rad",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "number"
            },
            "default": 0.0
          },
          "default": null
        },
        {
          "name": "asymmetric_degrees",
          "description": "Impact angle from the horizontal, in degrees, below which ejecta leave faster downrange, lengthening rays there and shortening them uprange.",
          "unit": "deg",
          "schema": {
            "kind": "number"
          },
          "default": 45.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 90.0,
          "exclusive_maximum": false
        },
        {
          "name": "forbidden_degrees",
          "description": "Impact angle in degrees below which rays within the zone half width of uprange are dropped; at most the asymmetric angle.",
          "unit": "deg",
          "schema": {
            "kind": "number"
          },
          "default": 25.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 90.0,
          "exclusive_maximum": false
        },
        {
          "name": "butterfly_degrees",
          "description": "Impact angle in degrees below which rays within the zone half width of downrange are dropped too, a butterfly pattern; at most the forbidden angle.",
          "unit": "deg",
          "schema": {
            "kind": "number"
          },
          "default": 10.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 90.0,
          "exclusive_maximum": false
        },
        {
          "name": "downrange_speed_ratio",
          "description": "Downrange over uprange ejection speed below the asymmetric angle, drawn per crater; at least 1, higher values stretch downrange rays more.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "uniform",
            "a": 1.2,
            "b": 1.4,
            "min": null,
            "max": null
          }
        },
        {
          "name": "zone_half_width_degrees",
          "description": "Half width in degrees, 0 to 180, of the ray-free zones uprange and downrange; illustrative, as the sources do not measure it.",
          "unit": "deg",
          "schema": {
            "kind": "number"
          },
          "default": 45.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 180.0,
          "exclusive_maximum": false
        }
      ]
    },
    "d55": {
      "kind": "object",
      "fields": [
        {
          "name": "enabled",
          "description": "Gives craters rays of bright material; off leaves only their interiors and ejecta bright.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": true
        },
        {
          "name": "count",
          "description": "Number of rays of a crater, drawn per crater and rounded; from 0 to 64.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "normal",
            "a": 10.7,
            "b": 3.1,
            "min": 6.0,
            "max": 20.0
          }
        },
        {
          "name": "length_coefficient",
          "description": "Coefficient of the median ray length, coefficient R^exponent km for crater radius R in km; higher values give longer rays.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 6.59,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "length_exponent",
          "description": "Exponent of the crater radius in the median ray length, positive; higher values make large craters' rays relatively longer.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.27,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "length_spread",
          "description": "Natural logarithm of a ray's length over the median, drawn per ray; a wider distribution gives more varied lengths.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "uniform",
            "a": -0.356,
            "b": 0.468,
            "min": null,
            "max": null
          }
        },
        {
          "name": "width_degrees",
          "description": "Angle in degrees a ray spans 2 radii from the centre, drawn per ray, within (0, 180); beyond 2 radii a ray keeps the width it has there.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "normal",
            "a": 22.0,
            "b": 8.3,
            "min": 5.4,
            "max": 38.6
          }
        },
        {
          "name": "excess",
          "description": "Optical maturity above the background along a ray at the rim, falling linearly to 0 at its end; not negative, higher values give brighter rays.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.048,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "patchiness",
          "description": "Share of a ray's strength, from 0 to 1, that noise along it can take away, breaking it into patches; 0 gives unbroken rays.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.5,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "patch_radii",
          "description": "Wavelength of the noise along a ray, in crater radii; positive, smaller values give shorter patches.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.5,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "oblique",
          "description": "How oblique impacts lengthen rays downrange and clear them uprange.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d56"
          },
          "default": {
            "enabled": true,
            "heading": null,
            "asymmetric_degrees": 45.0,
            "forbidden_degrees": 25.0,
            "butterfly_degrees": 10.0,
            "downrange_speed_ratio": {
              "kind": "uniform",
              "a": 1.2,
              "b": 1.4,
              "min": null,
              "max": null
            },
            "zone_half_width_degrees": 45.0
          }
        },
        {
          "name": "layout",
          "description": "Takes the rays' number, directions and widths from this layout in place of count and width_degrees, so they lie over a secondaries layer with the same layout; unset draws them per crater.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "ref",
              "ref": "d41"
            },
            "default": {
              "seed": 0,
              "count": {
                "kind": "normal",
                "a": 10.7,
                "b": 3.1,
                "min": 6.0,
                "max": 20.0
              },
              "width_degrees": {
                "kind": "normal",
                "a": 22.0,
                "b": 8.3,
                "min": 5.4,
                "max": 38.6
              }
            }
          },
          "default": null
        }
      ]
    },
    "d57": {
      "kind": "object",
      "fields": [
        {
          "name": "small_diameter",
          "description": "Diameter in metres at or below which craters keep their bright material for the small time.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 1000.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "small_myr",
          "description": "Time in Myr craters up to the small diameter keep their bright material.",
          "unit": "Myr",
          "schema": {
            "kind": "number"
          },
          "default": 5.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "mid_diameter",
          "description": "Diameter in metres from which craters keep their bright material for the mid time; between the small and mid diameters the time follows a power law of diameter.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 5000.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "mid_myr",
          "description": "Time in Myr craters from the mid to the large diameter keep their bright material.",
          "unit": "Myr",
          "schema": {
            "kind": "number"
          },
          "default": 750.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "large_diameter",
          "description": "Diameter in metres above which craters keep their bright material for the large time.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 50000.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "large_myr",
          "description": "Time in Myr craters above the large diameter keep their bright material.",
          "unit": "Myr",
          "schema": {
            "kind": "number"
          },
          "default": 750.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "scale",
          "description": "Factor every retention time is multiplied by, positive; higher values keep craters bright for longer.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        }
      ]
    },
    "d58": {
      "kind": "object",
      "fields": [
        {
          "name": "enabled",
          "description": "Gives new craters swarms of splotches, their ejecta's secondaries (Robinson et al. 2015); off by default.",
          "unit": "",
          "schema": {
            "kind": "boolean"
          },
          "default": false
        },
        {
          "name": "crater_rate",
          "description": "New craters at least 10 m across per km^2 per year; 4.84e-6 from Speyerer et al. (2016).",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 4.84e-06,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "crater_slope",
          "description": "Cumulative size slope of the new craters; the Neukum production function has 2.97 to 3.15.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 3.06,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "min_crater_diameter",
          "description": "Smallest crater with a swarm, in metres; smaller craters throw few splotches.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 10.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "max_crater_diameter",
          "description": "Largest crater with a swarm, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 50.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "reference_diameter",
          "description": "Diameter in metres of the crater whose swarm was counted: 18.8 m, Robinson et al.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 18.8,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "reference_count",
          "description": "Splotches of the reference crater: 248 within 30 km, Robinson et al.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 248.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "mu",
          "description": "Velocity exponent of the target, between 0 and 1; 0.41 for sand (Housen and Holsapple 2011). Counts grow as D^(3 + 1.5 mu) and landing distances fall as r^(-1.5 mu).",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.41,
          "minimum": 0.0,
          "exclusive_minimum": true,
          "maximum": 1.0,
          "exclusive_maximum": true
        },
        {
          "name": "min_range",
          "description": "Nearest landing distance in metres, setting Robinson et al.'s median of 8.7 km.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 4300.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "max_range",
          "description": "Farthest landing distance in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 30000.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "splotch_diameter",
          "description": "Diameter of a swarm splotch in metres, drawn per splotch: 2 to 22 m, median 6 m.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "log_normal",
            "a": 6.0,
            "b": 0.6,
            "min": 2.0,
            "max": 22.0
          }
        },
        {
          "name": "dark_share",
          "description": "Share of swarm splotches darker than the ground.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.9637096774193549,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "bright_share",
          "description": "Share brighter than the ground; the rest are mixed.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.012096774193548387,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "dark_change",
          "description": "Reflectance change of a dark swarm splotch.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "constant",
            "a": -0.04,
            "b": 0.0,
            "min": null,
            "max": null
          }
        },
        {
          "name": "bright_change",
          "description": "Reflectance change of a bright swarm splotch.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d18"
          },
          "default": {
            "kind": "uniform",
            "a": 0.04,
            "b": 0.12,
            "min": null,
            "max": null
          }
        },
        {
          "name": "wedge_share",
          "description": "Share of swarm splotches shaped as wedges pointing back to their crater. Illustrative.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.2,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "wedge_elongation",
          "description": "Long over short axis of a wedge, at least 1. Illustrative.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 2.0,
          "minimum": 1.0,
          "exclusive_minimum": false
        },
        {
          "name": "craters",
          "description": "New craters given by hand, such as an observed impact, each throwing a swarm.",
          "unit": "",
          "schema": {
            "kind": "array",
            "of": {
              "kind": "ref",
              "ref": "d9"
            },
            "default": {
              "x": 0.0,
              "y": 0.0,
              "diameter": 0.0,
              "age_gyr": 0.0,
              "id": 0
            }
          },
          "default": []
        }
      ]
    },
    "d59": {
      "kind": "object",
      "fields": [
        {
          "name": "x",
          "description": "Surface x of the lander.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0
        },
        {
          "name": "y",
          "description": "Surface y of the lander.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0
        },
        {
          "name": "area",
          "description": "Area of the blast zone in m^2; measured: Apollo 18,725 to 53,872 (mean 28,785), Luna 987 to 3355 (mean 2100), Surveyor 131 to 279 (mean 215), Chang'e-3 2530.",
          "unit": "m^2",
          "schema": {
            "kind": "number"
          },
          "default": 28785.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "elongation",
          "description": "Long over short axis of the zone, at least 1; Apollo about 1.14, Chang'e-3 about 1.74.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.14,
          "minimum": 1.0,
          "exclusive_minimum": false
        },
        {
          "name": "heading_degrees",
          "description": "Direction of the long axis, degrees counter-clockwise from east, such as along the final approach.",
          "unit": "deg",
          "schema": {
            "kind": "number"
          },
          "default": 90.0
        },
        {
          "name": "change",
          "description": "Mean reflectance change over the zone relative to undisturbed ground at 30 degrees phase, above -1; measured +3.4% to +13.2%, Apollo mean +10.9%.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.109,
          "minimum": -1.0,
          "exclusive_minimum": true
        },
        {
          "name": "halo_change",
          "description": "Reflectance change of the fainter halo beyond the zone, above -1; +4% at Chang'e-3.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.04,
          "minimum": -1.0,
          "exclusive_minimum": true
        },
        {
          "name": "halo_reach",
          "description": "How far the halo reaches over the zone's own reach, at least 1; 1 for no halo.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 1.9,
          "minimum": 1.0,
          "exclusive_minimum": false
        },
        {
          "name": "core_radius",
          "description": "Radius in metres of the darker core beneath the engine and around the crew's tracks; 0 for none, a few metres at the Apollo sites.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false
        },
        {
          "name": "core_change",
          "description": "Reflectance change of the dark core, above -1; -15% to -30% at the Apollo sites.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": -0.2,
          "minimum": -1.0,
          "exclusive_minimum": true
        },
        {
          "name": "raggedness",
          "description": "Share of the zone's radius, from 0 up to 1, that lobes of its edge pull in by.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.15,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": true
        },
        {
          "name": "seed",
          "description": "Varies the edge's lobes.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        }
      ]
    },
    "d50": {
      "kind": "choice",
      "alternatives": [
        {
          "type": "craters",
          "description": "Bright ejecta, interiors and rays of the craters of a crater layer, fading with crater age.",
          "fields": [
            {
              "name": "crater_layer",
              "description": "Which top-level crater layer's craters to brighten, counting from 0; unset uses every top-level crater layer.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "integer",
                  "minimum": 0
                },
                "default": 0
              },
              "default": null
            },
            {
              "name": "seed",
              "description": "Seed of which craters get bright material, their rays and their impacts; changing it gives a different pattern of the same statistics.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 0
            },
            {
              "name": "min_diameter",
              "description": "Smallest diameter, in metres, of craters given bright material.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "max_diameter",
              "description": "Largest diameter, in metres, of craters given bright material; unset has no upper limit.",
              "unit": "m",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "min_age_gyr",
              "description": "Youngest age, in Gyr, of craters given bright material.",
              "unit": "Gyr",
              "schema": {
                "kind": "number"
              },
              "default": 0.0,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "max_age_gyr",
              "description": "Oldest age, in Gyr, of craters given bright material; unset has no upper limit.",
              "unit": "Gyr",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "manual",
              "description": "Gives manual craters bright material too; otherwise only generated craters have it.",
              "unit": "",
              "schema": {
                "kind": "boolean"
              },
              "default": true
            },
            {
              "name": "share",
              "description": "Share of eligible craters, from 0 to 1, given bright material.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "background_maturity",
              "description": "Optical maturity (OMAT) of the ground around the craters, positive; the excesses are added to it and the albedo is brightened from it.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.202,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "max_maturity",
              "description": "Cap on the optical maturity where craters' excesses add up, at least the background; it limits how bright overlapping craters get.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.42
            },
            {
              "name": "interior_excess",
              "description": "Optical maturity above the background inside a fresh crater's rim, not negative; higher values give brighter interiors.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.132,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "texture",
              "description": "Filaments, lobed ejecta edges and walls brighter than floors; off unless streaks, lobes or a floor share below 1 are set.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d51"
              },
              "default": {
                "streaks": 0.0,
                "streak_width_degrees": 3.0,
                "streak_length_radii": 1.5,
                "continuous_radii": 0.0,
                "lobes": 0.0,
                "lobe_count": 8,
                "floor_share": 1.0,
                "seed": 0
              }
            },
            {
              "name": "zones",
              "description": "Bright and dark reflectance zones around new small craters, after Robinson et al. (2015) and Speyerer et al. (2016); off by default.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d52"
              },
              "default": {
                "enabled": false,
                "max_diameter": 50.0,
                "mature_depth": 1.0,
                "excavation_ratio": 0.1,
                "proximal_high": {
                  "share": 1.0,
                  "change": {
                    "kind": "normal",
                    "a": 0.12,
                    "b": 0.09,
                    "min": 0.01,
                    "max": 0.5
                  },
                  "coefficient": 1.5,
                  "exponent": 1.0,
                  "scale": {
                    "kind": "log_normal",
                    "a": 1.0,
                    "b": 0.82,
                    "min": 0.4,
                    "max": 5.0
                  },
                  "raggedness": 0.3,
                  "finger_width_degrees": 25.0,
                  "feather": 0.3,
                  "retention_myr": null
                },
                "proximal_low": {
                  "share": 1.0,
                  "change": {
                    "kind": "normal",
                    "a": -0.09,
                    "b": 0.04,
                    "min": -0.2,
                    "max": -0.01
                  },
                  "coefficient": 2.9,
                  "exponent": 1.0,
                  "scale": {
                    "kind": "log_normal",
                    "a": 1.0,
                    "b": 0.44,
                    "min": 0.5,
                    "max": 3.0
                  },
                  "raggedness": 0.3,
                  "finger_width_degrees": 20.0,
                  "feather": 0.3,
                  "retention_myr": 0.081
                },
                "distal_high": {
                  "share": 0.24,
                  "change": {
                    "kind": "uniform",
                    "a": 0.01,
                    "b": 0.04,
                    "min": null,
                    "max": null
                  },
                  "coefficient": 0.52,
                  "exponent": 2.5,
                  "scale": {
                    "kind": "constant",
                    "a": 1.0,
                    "b": 0.0,
                    "min": null,
                    "max": null
                  },
                  "raggedness": 0.5,
                  "finger_width_degrees": 8.0,
                  "feather": 0.4,
                  "retention_myr": 0.081
                },
                "distal_low": {
                  "share": 0.84,
                  "change": {
                    "kind": "uniform",
                    "a": -0.06,
                    "b": -0.02,
                    "min": null,
                    "max": null
                  },
                  "coefficient": 5.03,
                  "exponent": 2.0,
                  "scale": {
                    "kind": "constant",
                    "a": 1.0,
                    "b": 0.0,
                    "min": null,
                    "max": null
                  },
                  "raggedness": 0.6,
                  "finger_width_degrees": 8.0,
                  "feather": 0.6,
                  "retention_myr": 0.081
                },
                "shadows": {
                  "enabled": false,
                  "jet_angle_degrees": 3.0,
                  "depth": 0.5,
                  "azimuths": 720,
                  "radial_samples": 400
                },
                "seed": 0
              }
            },
            {
              "name": "ejecta_excess",
              "description": "Optical maturity above the background on a fresh crater's continuous ejecta at the rim, not negative, falling with distance.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.076,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "ejecta_exponent",
              "description": "Exponent of the ejecta's fall with distance r, as (r / R)^-exponent for crater radius R; positive, higher values keep the bright ejecta nearer the rim.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 3.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "ejecta_reach_radii",
              "description": "Distance from the centre, in crater radii and over 1, at which the ejecta's excess reaches 0.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 3.0,
              "minimum": 1.0,
              "exclusive_minimum": true
            },
            {
              "name": "rays",
              "description": "Rays of bright material running out from the craters.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d55"
              },
              "default": {
                "enabled": true,
                "count": {
                  "kind": "normal",
                  "a": 10.7,
                  "b": 3.1,
                  "min": 6.0,
                  "max": 20.0
                },
                "length_coefficient": 6.59,
                "length_exponent": 1.27,
                "length_spread": {
                  "kind": "uniform",
                  "a": -0.356,
                  "b": 0.468,
                  "min": null,
                  "max": null
                },
                "width_degrees": {
                  "kind": "normal",
                  "a": 22.0,
                  "b": 8.3,
                  "min": 5.4,
                  "max": 38.6
                },
                "excess": 0.048,
                "patchiness": 0.5,
                "patch_radii": 0.5,
                "oblique": {
                  "enabled": true,
                  "heading": null,
                  "asymmetric_degrees": 45.0,
                  "forbidden_degrees": 25.0,
                  "butterfly_degrees": 10.0,
                  "downrange_speed_ratio": {
                    "kind": "uniform",
                    "a": 1.2,
                    "b": 1.4,
                    "min": null,
                    "max": null
                  },
                  "zone_half_width_degrees": 45.0
                },
                "layout": null
              }
            },
            {
              "name": "retention",
              "description": "How long craters of each diameter keep their bright material.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d57"
              },
              "default": {
                "small_diameter": 1000.0,
                "small_myr": 5.0,
                "mid_diameter": 5000.0,
                "mid_myr": 750.0,
                "large_diameter": 50000.0,
                "large_myr": 750.0,
                "scale": 1.0
              }
            },
            {
              "name": "fade_exponent",
              "description": "Exponent of the fade with age t, max(0, 1 - t / T)^exponent for retention time T; positive, 1 is a straight fade and higher values fade sooner.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "origin_reflectance",
              "description": "Reflectance of the optical maturity origin, the hypermature end-member, from which reflectance scales with maturity at fixed iron content.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.08
            },
            {
              "name": "fade",
              "description": "How bright material of craters too small to resolve at the sample spacing fades out.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d15"
              },
              "default": {
                "start_samples": 2.0,
                "end_samples": 4.0,
                "shape": "smoothstep"
              }
            }
          ],
          "default": {
            "type": "craters",
            "crater_layer": null,
            "seed": 0,
            "min_diameter": 0.0,
            "max_diameter": null,
            "min_age_gyr": 0.0,
            "max_age_gyr": null,
            "manual": true,
            "share": 1.0,
            "background_maturity": 0.202,
            "max_maturity": 0.42,
            "interior_excess": 0.132,
            "texture": {
              "streaks": 0.0,
              "streak_width_degrees": 3.0,
              "streak_length_radii": 1.5,
              "continuous_radii": 0.0,
              "lobes": 0.0,
              "lobe_count": 8,
              "floor_share": 1.0,
              "seed": 0
            },
            "zones": {
              "enabled": false,
              "max_diameter": 50.0,
              "mature_depth": 1.0,
              "excavation_ratio": 0.1,
              "proximal_high": {
                "share": 1.0,
                "change": {
                  "kind": "normal",
                  "a": 0.12,
                  "b": 0.09,
                  "min": 0.01,
                  "max": 0.5
                },
                "coefficient": 1.5,
                "exponent": 1.0,
                "scale": {
                  "kind": "log_normal",
                  "a": 1.0,
                  "b": 0.82,
                  "min": 0.4,
                  "max": 5.0
                },
                "raggedness": 0.3,
                "finger_width_degrees": 25.0,
                "feather": 0.3,
                "retention_myr": null
              },
              "proximal_low": {
                "share": 1.0,
                "change": {
                  "kind": "normal",
                  "a": -0.09,
                  "b": 0.04,
                  "min": -0.2,
                  "max": -0.01
                },
                "coefficient": 2.9,
                "exponent": 1.0,
                "scale": {
                  "kind": "log_normal",
                  "a": 1.0,
                  "b": 0.44,
                  "min": 0.5,
                  "max": 3.0
                },
                "raggedness": 0.3,
                "finger_width_degrees": 20.0,
                "feather": 0.3,
                "retention_myr": 0.081
              },
              "distal_high": {
                "share": 0.24,
                "change": {
                  "kind": "uniform",
                  "a": 0.01,
                  "b": 0.04,
                  "min": null,
                  "max": null
                },
                "coefficient": 0.52,
                "exponent": 2.5,
                "scale": {
                  "kind": "constant",
                  "a": 1.0,
                  "b": 0.0,
                  "min": null,
                  "max": null
                },
                "raggedness": 0.5,
                "finger_width_degrees": 8.0,
                "feather": 0.4,
                "retention_myr": 0.081
              },
              "distal_low": {
                "share": 0.84,
                "change": {
                  "kind": "uniform",
                  "a": -0.06,
                  "b": -0.02,
                  "min": null,
                  "max": null
                },
                "coefficient": 5.03,
                "exponent": 2.0,
                "scale": {
                  "kind": "constant",
                  "a": 1.0,
                  "b": 0.0,
                  "min": null,
                  "max": null
                },
                "raggedness": 0.6,
                "finger_width_degrees": 8.0,
                "feather": 0.6,
                "retention_myr": 0.081
              },
              "shadows": {
                "enabled": false,
                "jet_angle_degrees": 3.0,
                "depth": 0.5,
                "azimuths": 720,
                "radial_samples": 400
              },
              "seed": 0
            },
            "ejecta_excess": 0.076,
            "ejecta_exponent": 3.0,
            "ejecta_reach_radii": 3.0,
            "rays": {
              "enabled": true,
              "count": {
                "kind": "normal",
                "a": 10.7,
                "b": 3.1,
                "min": 6.0,
                "max": 20.0
              },
              "length_coefficient": 6.59,
              "length_exponent": 1.27,
              "length_spread": {
                "kind": "uniform",
                "a": -0.356,
                "b": 0.468,
                "min": null,
                "max": null
              },
              "width_degrees": {
                "kind": "normal",
                "a": 22.0,
                "b": 8.3,
                "min": 5.4,
                "max": 38.6
              },
              "excess": 0.048,
              "patchiness": 0.5,
              "patch_radii": 0.5,
              "oblique": {
                "enabled": true,
                "heading": null,
                "asymmetric_degrees": 45.0,
                "forbidden_degrees": 25.0,
                "butterfly_degrees": 10.0,
                "downrange_speed_ratio": {
                  "kind": "uniform",
                  "a": 1.2,
                  "b": 1.4,
                  "min": null,
                  "max": null
                },
                "zone_half_width_degrees": 45.0
              },
              "layout": null
            },
            "retention": {
              "small_diameter": 1000.0,
              "small_myr": 5.0,
              "mid_diameter": 5000.0,
              "mid_myr": 750.0,
              "large_diameter": 50000.0,
              "large_myr": 750.0,
              "scale": 1.0
            },
            "fade_exponent": 1.0,
            "origin_reflectance": 0.08,
            "fade": {
              "start_samples": 2.0,
              "end_samples": 4.0,
              "shape": "smoothstep"
            }
          }
        },
        {
          "type": "splotches",
          "description": "Dark and bright splotches that secondary impacts of loose regolith leave over the whole surface, after Speyerer et al. (2016).",
          "fields": [
            {
              "name": "seed",
              "description": "Seed of where splotches fall and what they are.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 0
            },
            {
              "name": "rate_coefficient",
              "description": "Coefficient a of the cumulative formation rate a d^-b per km^2 per year, d the diameter in km; positive, higher values give more splotches.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 1.483e-11,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "rate_exponent",
              "description": "Slope b of the cumulative formation rate; positive, higher values give relatively more small splotches.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 4.144,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "lifetime_myr",
              "description": "How long a splotch lasts in Myr, fading linearly; positive, the default is the time splotches take to churn the top centimetres.",
              "unit": "Myr",
              "schema": {
                "kind": "number"
              },
              "default": 0.081,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "min_diameter",
              "description": "Smallest splotch diameter in metres; the published fit is extrapolated below 10 m.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 1.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "max_diameter",
              "description": "Largest splotch diameter in metres, above the smallest.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 40.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "dark_share",
              "description": "Share of splotches, from 0 to 1, darker than the ground.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.907,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "bright_share",
              "description": "Share of splotches, from 0 to 1, brighter than the ground; the rest are mixed, dark on one side and bright on the other.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.074,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "dark_change",
              "description": "Reflectance change of a dark splotch relative to the ground before it, drawn per splotch; above -1.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d18"
              },
              "default": {
                "kind": "constant",
                "a": -0.04,
                "b": 0.0,
                "min": null,
                "max": null
              }
            },
            {
              "name": "bright_change",
              "description": "Reflectance change of a bright splotch, drawn per splotch; above -1.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d18"
              },
              "default": {
                "kind": "constant",
                "a": 0.1,
                "b": 0.0,
                "min": null,
                "max": null
              }
            },
            {
              "name": "steep_bright_share",
              "description": "Share of splotches on slopes steeper than the steep slope that are bright, from 0 to 1, read from the terrain's heights; unset keeps the bright share. Bright splotches are found mostly on such slopes, but the source gives no share.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "number"
                },
                "default": 0.0
              },
              "default": null,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "steep_slope_degrees",
              "description": "Slope in degrees, between 0 and 90 excluded, from which ground is steep.",
              "unit": "deg",
              "schema": {
                "kind": "number"
              },
              "default": 15.0,
              "minimum": 0.0,
              "exclusive_minimum": true,
              "maximum": 90.0,
              "exclusive_maximum": true
            },
            {
              "name": "softness",
              "description": "Share of a splotch's radius, from 0 to 1 excluding 0, over which its edge fades.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.3,
              "minimum": 0.0,
              "exclusive_minimum": true,
              "maximum": 1.0,
              "exclusive_maximum": false
            },
            {
              "name": "raggedness",
              "description": "Share of a splotch's radius, from 0 up to 1, that lobes of its edge pull in by; 0 keeps it round.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.15,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 1.0,
              "exclusive_maximum": true
            },
            {
              "name": "fade",
              "description": "How splotches too small to resolve at the sample spacing fade out.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d15"
              },
              "default": {
                "start_samples": 2.0,
                "end_samples": 4.0,
                "shape": "smoothstep"
              }
            },
            {
              "name": "swarms",
              "description": "Swarms of splotches around new craters; off by default.",
              "unit": "",
              "schema": {
                "kind": "ref",
                "ref": "d58"
              },
              "default": {
                "enabled": false,
                "crater_rate": 4.84e-06,
                "crater_slope": 3.06,
                "min_crater_diameter": 10.0,
                "max_crater_diameter": 50.0,
                "reference_diameter": 18.8,
                "reference_count": 248.0,
                "mu": 0.41,
                "min_range": 4300.0,
                "max_range": 30000.0,
                "splotch_diameter": {
                  "kind": "log_normal",
                  "a": 6.0,
                  "b": 0.6,
                  "min": 2.0,
                  "max": 22.0
                },
                "dark_share": 0.9637096774193549,
                "bright_share": 0.012096774193548387,
                "dark_change": {
                  "kind": "constant",
                  "a": -0.04,
                  "b": 0.0,
                  "min": null,
                  "max": null
                },
                "bright_change": {
                  "kind": "uniform",
                  "a": 0.04,
                  "b": 0.12,
                  "min": null,
                  "max": null
                },
                "wedge_share": 0.2,
                "wedge_elongation": 2.0,
                "craters": []
              }
            }
          ],
          "default": {
            "type": "splotches",
            "seed": 0,
            "rate_coefficient": 1.483e-11,
            "rate_exponent": 4.144,
            "lifetime_myr": 0.081,
            "min_diameter": 1.0,
            "max_diameter": 40.0,
            "dark_share": 0.907,
            "bright_share": 0.074,
            "dark_change": {
              "kind": "constant",
              "a": -0.04,
              "b": 0.0,
              "min": null,
              "max": null
            },
            "bright_change": {
              "kind": "constant",
              "a": 0.1,
              "b": 0.0,
              "min": null,
              "max": null
            },
            "steep_bright_share": null,
            "steep_slope_degrees": 15.0,
            "softness": 0.3,
            "raggedness": 0.15,
            "fade": {
              "start_samples": 2.0,
              "end_samples": 4.0,
              "shape": "smoothstep"
            },
            "swarms": {
              "enabled": false,
              "crater_rate": 4.84e-06,
              "crater_slope": 3.06,
              "min_crater_diameter": 10.0,
              "max_crater_diameter": 50.0,
              "reference_diameter": 18.8,
              "reference_count": 248.0,
              "mu": 0.41,
              "min_range": 4300.0,
              "max_range": 30000.0,
              "splotch_diameter": {
                "kind": "log_normal",
                "a": 6.0,
                "b": 0.6,
                "min": 2.0,
                "max": 22.0
              },
              "dark_share": 0.9637096774193549,
              "bright_share": 0.012096774193548387,
              "dark_change": {
                "kind": "constant",
                "a": -0.04,
                "b": 0.0,
                "min": null,
                "max": null
              },
              "bright_change": {
                "kind": "uniform",
                "a": 0.04,
                "b": 0.12,
                "min": null,
                "max": null
              },
              "wedge_share": 0.2,
              "wedge_elongation": 2.0,
              "craters": []
            }
          }
        },
        {
          "type": "blast_zones",
          "description": "Brighter zones of regolith around landers scoured by their descent engines, after Clegg et al. (2014) and Clegg-Watkins et al. (2016).",
          "fields": [
            {
              "name": "zones",
              "description": "One blast zone per lander.",
              "unit": "",
              "schema": {
                "kind": "array",
                "of": {
                  "kind": "ref",
                  "ref": "d59"
                },
                "default": {
                  "x": 0.0,
                  "y": 0.0,
                  "area": 28785.0,
                  "elongation": 1.14,
                  "heading_degrees": 90.0,
                  "change": 0.109,
                  "halo_change": 0.04,
                  "halo_reach": 1.9,
                  "core_radius": 0.0,
                  "core_change": -0.2,
                  "raggedness": 0.15,
                  "seed": 0
                }
              },
              "default": []
            }
          ],
          "default": {
            "type": "blast_zones",
            "zones": []
          }
        },
        {
          "type": "rocks",
          "description": "Rock brighter than the regolith: the boulders of boulder layers where resolved, and a speckle of the share of each sample covered by those too small to resolve.",
          "fields": [
            {
              "name": "boulder_layer",
              "description": "Which top-level boulder layer's rock to brighten, counting from 0; unset uses every top-level boulder layer.",
              "unit": "",
              "schema": {
                "kind": "optional",
                "of": {
                  "kind": "integer",
                  "minimum": 0
                },
                "default": 0
              },
              "default": null
            },
            {
              "name": "seed",
              "description": "Seed of the per-sample draws of rock too small to resolve.",
              "unit": "",
              "schema": {
                "kind": "integer",
                "minimum": 0
              },
              "default": 0
            },
            {
              "name": "reflectance_ratio",
              "description": "Rock reflectance over the regolith's; 2.5 after Marshal et al. (2023), within Holt's (1981) Apollo 16 rocks at 18 to 51% against soils of 14 to 15%; earlier models used 1.5.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 2.5,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "unresolved",
              "description": "Brightens each sample by the share of it covered by boulders too small to resolve, drawn about the expected share with the scatter of randomly placed rocks: bright speckle.",
              "unit": "",
              "schema": {
                "kind": "boolean"
              },
              "default": true
            }
          ],
          "default": {
            "type": "rocks",
            "boulder_layer": null,
            "seed": 0,
            "reflectance_ratio": 2.5,
            "unresolved": true
          }
        },
        {
          "type": "slopes",
          "description": "Steep ground kept immature and bright by regolith moving downslope, after Ikeda et al. (2022) and Lucey et al. (2014).",
          "fields": [
            {
              "name": "onset_degrees",
              "description": "Slope in degrees from which ground freshens; 20, where Lucey et al. (2014) and Ikeda et al. (2022) find brightening begin.",
              "unit": "deg",
              "schema": {
                "kind": "number"
              },
              "default": 20.0,
              "minimum": 0.0,
              "exclusive_minimum": false,
              "maximum": 90.0,
              "exclusive_maximum": true
            },
            {
              "name": "maturity_per_degree",
              "description": "Optical maturity (OMAT) gained per degree beyond the onset; about 0.0065 on the crater walls of Ikeda et al. (2022).",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.0065,
              "minimum": 0.0,
              "exclusive_minimum": false
            },
            {
              "name": "background_maturity",
              "description": "OMAT of gentler ground; about 0.10 at 20 degrees in Laue (Ikeda et al. 2022).",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.1,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "max_maturity",
              "description": "Cap on OMAT, at least the background's.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.42,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "baseline",
              "description": "Metres slopes are measured over, the spacing of the lattice they are read on; 10, the DTM Ikeda et al. (2022) measured slopes on.",
              "unit": "m",
              "schema": {
                "kind": "number"
              },
              "default": 10.0,
              "minimum": 0.0,
              "exclusive_minimum": true
            },
            {
              "name": "origin_reflectance",
              "description": "Reflectance of the optical maturity origin, from which reflectance scales with maturity at fixed iron content.",
              "unit": "",
              "schema": {
                "kind": "number"
              },
              "default": 0.08
            }
          ],
          "default": {
            "type": "slopes",
            "onset_degrees": 20.0,
            "maturity_per_degree": 0.0065,
            "background_maturity": 0.1,
            "max_maturity": 0.42,
            "baseline": 10.0,
            "origin_reflectance": 0.08
          }
        }
      ]
    },
    "d47": {
      "kind": "object",
      "fields": [
        {
          "name": "source",
          "description": "Base albedo of the terrain, before its layers: a synthetic colour or a raster map.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d48"
          },
          "default": {
            "type": "synthetic",
            "rgb": false,
            "hue": 0.0,
            "saturation": 0.0,
            "value": 0.11,
            "hue_noise": [],
            "saturation_noise": [],
            "value_noise": []
          }
        },
        {
          "name": "layers",
          "description": "Layers applied to the source's albedo in order, such as bright crater ejecta and rays.",
          "unit": "",
          "schema": {
            "kind": "array",
            "of": {
              "kind": "ref",
              "ref": "d50"
            },
            "default": {
              "type": "craters",
              "crater_layer": null,
              "seed": 0,
              "min_diameter": 0.0,
              "max_diameter": null,
              "min_age_gyr": 0.0,
              "max_age_gyr": null,
              "manual": true,
              "share": 1.0,
              "background_maturity": 0.202,
              "max_maturity": 0.42,
              "interior_excess": 0.132,
              "texture": {
                "streaks": 0.0,
                "streak_width_degrees": 3.0,
                "streak_length_radii": 1.5,
                "continuous_radii": 0.0,
                "lobes": 0.0,
                "lobe_count": 8,
                "floor_share": 1.0,
                "seed": 0
              },
              "zones": {
                "enabled": false,
                "max_diameter": 50.0,
                "mature_depth": 1.0,
                "excavation_ratio": 0.1,
                "proximal_high": {
                  "share": 1.0,
                  "change": {
                    "kind": "normal",
                    "a": 0.12,
                    "b": 0.09,
                    "min": 0.01,
                    "max": 0.5
                  },
                  "coefficient": 1.5,
                  "exponent": 1.0,
                  "scale": {
                    "kind": "log_normal",
                    "a": 1.0,
                    "b": 0.82,
                    "min": 0.4,
                    "max": 5.0
                  },
                  "raggedness": 0.3,
                  "finger_width_degrees": 25.0,
                  "feather": 0.3,
                  "retention_myr": null
                },
                "proximal_low": {
                  "share": 1.0,
                  "change": {
                    "kind": "normal",
                    "a": -0.09,
                    "b": 0.04,
                    "min": -0.2,
                    "max": -0.01
                  },
                  "coefficient": 2.9,
                  "exponent": 1.0,
                  "scale": {
                    "kind": "log_normal",
                    "a": 1.0,
                    "b": 0.44,
                    "min": 0.5,
                    "max": 3.0
                  },
                  "raggedness": 0.3,
                  "finger_width_degrees": 20.0,
                  "feather": 0.3,
                  "retention_myr": 0.081
                },
                "distal_high": {
                  "share": 0.24,
                  "change": {
                    "kind": "uniform",
                    "a": 0.01,
                    "b": 0.04,
                    "min": null,
                    "max": null
                  },
                  "coefficient": 0.52,
                  "exponent": 2.5,
                  "scale": {
                    "kind": "constant",
                    "a": 1.0,
                    "b": 0.0,
                    "min": null,
                    "max": null
                  },
                  "raggedness": 0.5,
                  "finger_width_degrees": 8.0,
                  "feather": 0.4,
                  "retention_myr": 0.081
                },
                "distal_low": {
                  "share": 0.84,
                  "change": {
                    "kind": "uniform",
                    "a": -0.06,
                    "b": -0.02,
                    "min": null,
                    "max": null
                  },
                  "coefficient": 5.03,
                  "exponent": 2.0,
                  "scale": {
                    "kind": "constant",
                    "a": 1.0,
                    "b": 0.0,
                    "min": null,
                    "max": null
                  },
                  "raggedness": 0.6,
                  "finger_width_degrees": 8.0,
                  "feather": 0.6,
                  "retention_myr": 0.081
                },
                "shadows": {
                  "enabled": false,
                  "jet_angle_degrees": 3.0,
                  "depth": 0.5,
                  "azimuths": 720,
                  "radial_samples": 400
                },
                "seed": 0
              },
              "ejecta_excess": 0.076,
              "ejecta_exponent": 3.0,
              "ejecta_reach_radii": 3.0,
              "rays": {
                "enabled": true,
                "count": {
                  "kind": "normal",
                  "a": 10.7,
                  "b": 3.1,
                  "min": 6.0,
                  "max": 20.0
                },
                "length_coefficient": 6.59,
                "length_exponent": 1.27,
                "length_spread": {
                  "kind": "uniform",
                  "a": -0.356,
                  "b": 0.468,
                  "min": null,
                  "max": null
                },
                "width_degrees": {
                  "kind": "normal",
                  "a": 22.0,
                  "b": 8.3,
                  "min": 5.4,
                  "max": 38.6
                },
                "excess": 0.048,
                "patchiness": 0.5,
                "patch_radii": 0.5,
                "oblique": {
                  "enabled": true,
                  "heading": null,
                  "asymmetric_degrees": 45.0,
                  "forbidden_degrees": 25.0,
                  "butterfly_degrees": 10.0,
                  "downrange_speed_ratio": {
                    "kind": "uniform",
                    "a": 1.2,
                    "b": 1.4,
                    "min": null,
                    "max": null
                  },
                  "zone_half_width_degrees": 45.0
                },
                "layout": null
              },
              "retention": {
                "small_diameter": 1000.0,
                "small_myr": 5.0,
                "mid_diameter": 5000.0,
                "mid_myr": 750.0,
                "large_diameter": 50000.0,
                "large_myr": 750.0,
                "scale": 1.0
              },
              "fade_exponent": 1.0,
              "origin_reflectance": 0.08,
              "fade": {
                "start_samples": 2.0,
                "end_samples": 4.0,
                "shape": "smoothstep"
              }
            }
          },
          "default": []
        }
      ]
    },
    "d62": {
      "kind": "object",
      "fields": [
        {
          "name": "albedo",
          "description": "Single-scattering albedo w, from 0 to 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "b",
          "description": "Asymmetry b of the two-term Henyey-Greenstein phase function, from 0 to 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "c",
          "description": "Backscatter fraction c of the two-term Henyey-Greenstein phase function, from 0 to 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": false
        },
        {
          "name": "roughness",
          "description": "Macroscopic roughness theta-bar, in degrees below 90.",
          "unit": "deg",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 90.0,
          "exclusive_maximum": true
        }
      ]
    },
    "d61": {
      "kind": "object",
      "fields": [
        {
          "name": "reference",
          "description": "Published Hapke parameters to start from; each class given below replaces its own.",
          "unit": "",
          "schema": {
            "kind": "enum",
            "choices": [
              "none",
              "mars_pancam"
            ],
            "descriptions": [
              "No parameters: each class present must be given.",
              "Pancam fits at 753 nm (Johnson et al. 2006a, b, tabulated by Fernando et al. 2013): soil, sand, dust, bedrock (Eagle crater outcrop, Johnson et al. 2006b) and rock."
            ]
          },
          "default": "none"
        },
        {
          "name": "soil",
          "description": "Hapke parameters of soil; unset keeps the reference's.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "ref",
              "ref": "d62"
            },
            "default": {
              "albedo": 0.0,
              "b": 0.0,
              "c": 0.0,
              "roughness": 0.0
            }
          },
          "default": null
        },
        {
          "name": "sand",
          "description": "Hapke parameters of sand; unset keeps the reference's.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "ref",
              "ref": "d62"
            },
            "default": {
              "albedo": 0.0,
              "b": 0.0,
              "c": 0.0,
              "roughness": 0.0
            }
          },
          "default": null
        },
        {
          "name": "dust",
          "description": "Hapke parameters of dust; unset keeps the reference's.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "ref",
              "ref": "d62"
            },
            "default": {
              "albedo": 0.0,
              "b": 0.0,
              "c": 0.0,
              "roughness": 0.0
            }
          },
          "default": null
        },
        {
          "name": "bedrock",
          "description": "Hapke parameters of bedrock; unset keeps the reference's.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "ref",
              "ref": "d62"
            },
            "default": {
              "albedo": 0.0,
              "b": 0.0,
              "c": 0.0,
              "roughness": 0.0
            }
          },
          "default": null
        },
        {
          "name": "rock",
          "description": "Hapke parameters of rocks and boulders; unset keeps the reference's.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "ref",
              "ref": "d62"
            },
            "default": {
              "albedo": 0.0,
              "b": 0.0,
              "c": 0.0,
              "roughness": 0.0
            }
          },
          "default": null
        }
      ]
    },
    "d60": {
      "kind": "object",
      "fields": [
        {
          "name": "exposure",
          "description": "Thresholds marking bare ground as bedrock, read on the ground beneath the first layer that lays a material; unset for no bedrock.",
          "unit": "",
          "schema": {
            "kind": "optional",
            "of": {
              "kind": "ref",
              "ref": "d29"
            },
            "default": {
              "reach": 12.0,
              "rise_soil": 0.01,
              "rise_boulder": 0.035,
              "slope_soil": 0.2,
              "slope_boulder": 0.4,
              "floor_cover": 0.0,
              "floor_patch": 60.0,
              "seed": 0
            }
          },
          "default": {
            "reach": 12.0,
            "rise_soil": 0.01,
            "rise_boulder": 0.035,
            "slope_soil": 0.2,
            "slope_boulder": 0.4,
            "floor_cover": 0.0,
            "floor_patch": 60.0,
            "seed": 0
          }
        },
        {
          "name": "dust_cover",
          "description": "About the share of the surface under bright dust patches, from 0 up to 1.",
          "unit": "",
          "schema": {
            "kind": "number"
          },
          "default": 0.0,
          "minimum": 0.0,
          "exclusive_minimum": false,
          "maximum": 1.0,
          "exclusive_maximum": true
        },
        {
          "name": "dust_patch",
          "description": "Typical width of a dust patch, in metres.",
          "unit": "m",
          "schema": {
            "kind": "number"
          },
          "default": 50.0,
          "minimum": 0.0,
          "exclusive_minimum": true
        },
        {
          "name": "seed",
          "description": "Seed of the dust patches.",
          "unit": "",
          "schema": {
            "kind": "integer",
            "minimum": 0
          },
          "default": 0
        },
        {
          "name": "photometry",
          "description": "Hapke parameters of each material class, which photometry outputs mix.",
          "unit": "",
          "schema": {
            "kind": "ref",
            "ref": "d61"
          },
          "default": {
            "reference": "none",
            "soil": null,
            "sand": null,
            "dust": null,
            "bedrock": null,
            "rock": null
          }
        }
      ]
    }
  }
}