///|
fn digest(text : String) -> UInt {
  let mut hash = 2166136261U
  for i in 0.. String {
  let digits = row.to_string()
  "k" + String::make(6 - digits.length(), '0') + digits
}

///|
fn main raise {
  let args = @env.args()
  // Node includes its own executable prefix; all modes use the final 4 args.
  guard args.length() >= 5 else {
    fail("ROWS COLUMNS CONFLICT_ROW_PERCENT merge|review|lineage|unique")
  }
  let args = args[args.length() - 4:].to_owned()
  let n = @string.parse_int(args[0])
  let width = @string.parse_int(args[1])
  let density = @string.parse_int(args[2])
  let mode = args[3]
  guard n > 0 &&
    n <= 100000 &&
    width >= 3 &&
    width <= 64 &&
    n * width <= 2000000 &&
    density >= 0 &&
    density <= 100 &&
    ["merge", "review", "lineage", "unique"].contains(mode) else {
    fail("invalid benchmark dimensions/mode")
  }
  let headers = ["id"]
  for c in 1.. {
    Array::makei(width, c => {
      if c == 0 {
        identity(r)
      } else if mode == "unique" {
        "\{r}:\{c}"
      } else {
        "base"
      }
    })
  })
  let local_rows = original.map(row => row.copy())
  let remote = original.map(row => row.copy())
  let mut count = 0
  for r in 0.. @merge.Decision::{
    target: c.target,
    choice: @merge.Value("reviewed"),
  })
  let resolved = @merge.resolve(plan, decisions)
  let report_hash = digest(resolved.report().stringify())
  let mut bundle_hash = 0U
  let table = if mode == "review" {
    let wire = @merge.ReviewBundle::from_plan(resolved).to_json().stringify()
    bundle_hash = digest(wire)
    @merge.ReviewBundle::from_json(wire)
    .replay(b, o, t, key=["id"])
    .finish()
    .table()
  } else {
    resolved.finish().table()
  }
  let rows = table.rows()
  assert_eq(rows.length(), n)
  assert_eq(table.headers(), headers)
  for r in 0..