     return unless interval_class_between(root_note_number, pitch_number_for_position(finger_position)) == semitones
     positions.push finger_position
   return positions
-
-fingerings_for = (chord, root_note) ->
-  positions = do (positions=[]) ->
-    finger_positions_each (pos) ->
-      interval_class = interval_class_between(root_note, pitch_number_for_position(pos))
-      degree_index = chord.pitch_classes.indexOf(interval_class)
-      positions.push {string: pos.string, fret: pos.fret, degree_index} if degree_index >= 0
-    positions
-
-  frets_per_string = do (strings=([] for __ in OpenStringNoteNumbers)) ->
-    strings[position.string].push position for position in positions
-    strings
-
-  compute_choices = (by_string) ->
-    return [[]] unless by_string.length
-    frets = by_string[0]
-    remaining = compute_choices(by_string[1..])
-    return remaining.concat(([n].concat(right) \
-      for n in frets for right in remaining)...)
-
-  count_distinct_notes = (fs) ->
-    _.chain(fs).pluck('degree_index').uniq().value().length
-
-  chord_note_count = count_distinct_notes(positions)
-
-  has_all_notes = (fs) ->
-    return count_distinct_notes(fs) == chord_note_count
-
-  closed_medial_strings = (fs) ->
-    string_frets = (-1 for s in StringNumbers)
-    string_frets[pos.string] = pos.fret for pos in fs
-    p = ((if x >= 0 then x else 'x') for x in string_frets).join('')
-    return p.match(/\dx+\d/)
-
-  closed_treble_strings = (fs) ->
-    string_frets = (-1 for s in StringNumbers)
-    string_frets[pos.string] = pos.fret for pos in fs
-    p = ((if x >= 0 then x else 'x') for x in string_frets).join('')
-    return p.match(/x$/)
-
-  finger_count = (fs) ->
-    (f for f in fs when f.fret).length
-
-  high_note_count = (fs) -> -fs.length
-
-  is_first_position = (fs) ->
-    _(fs).sortBy((f) -> f.string)[0].degree_index == 0
-
-  cmp = (fn) -> (x...) -> !fn(x...)
-
-  filters = [
-    {name: 'has all chord notes', filter: has_all_notes},
-    {name: 'no muted medial strings', filter: cmp(closed_medial_strings)},
-    {name: 'no muted treble strings', filter: cmp(closed_treble_strings)}
-  ]
-
-  sorts = [
-    finger_count,
-    high_note_count,
-    cmp(is_first_position)
-  ]
-
-  chord_name = "#{NoteNames[root_note % 12]}#{chord.abbr}"
-  choices = compute_choices(frets_per_string)
-  for {name, filter} in filters
-    filtered = (choice for choice in choices when filter(choice))
-    unless filtered.length
-      console.error "#{chord_name}: no fingerings pass filter \"#{name}\""
-      filtered = choices
-    choices = filtered
-  for sort in sorts
-    choices = _(choices).sortBy(sort)
-  # for choice in choices
-  #   console.info finger_count(choice)
-  return choices
-
-best_fingering_for = (chord, root_note) ->
-  return fingerings_for(chord, root_note)[0]
-
-
-#
-# Drawing and Layout
-#
-
-BuildDirectory = __dirname + '/build/'
-DefaultFilename = null
-canvas = null
-ctx = null
-
-erase_background = ->
-  ctx.fillStyle = 'white'
-  ctx.fillRect 0, 0, canvas.width, canvas.height
-
-filename = (name) -> DefaultFilename = name
-
-save_canvas_to_png = (canvas, fname) ->
-  out = fs.createWriteStream(BuildDirectory + fname)
-  stream = canvas.pngStream()
-  stream.on 'data', (chunk) -> out.write(chunk)
-  stream.on 'end', () -> console.log "Saved #{fname}"
-
-mode = null
-pdf = false
-page = (width, height, draw_page) ->
-  return [width, height] if mode == 'measure'
-  canvas ||= new Canvas(width, height, pdf and 'pdf')
-  ctx = canvas.getContext('2d')
-  ctx.textDrawingMode = 'glyph' if pdf
-  erase_background()
-  draw_page ctx
-  unless pdf
-    filename = "#{DefaultFilename or 'test'}.png"
-    fs.writeFile BuildDirectory + filename, canvas.toBuffer()
-
-grid = ({cols, rows, cell_width, cell_height, header_height}, draw_page) ->
-  header_height ||= 0
-  page cols * cell_width, header_height + rows * cell_height, (ctx) ->
-    i = 0
-    draw_page (draw_cell) ->
-      return if i >= cols * rows
-      ctx.save()
-      ctx.translate (i % cols) * cell_width, header_height + Math.floor(i / cols) * cell_height
-      draw_cell()
-      ctx.restore()
-      i += 1
-
-book = (filename, options, draw_book) ->
-  draw_book = options if typeof options == 'function'
-  pdf = true
-  mode = 'draw'
-  page_limit = options.pages
-  page_count = 0
-  draw_book (draw_page) ->
-    return if page_limit and page_limit <= page_count
-    page_count += 1
-    draw_page()
-    ctx.addPage()
-  fs.writeFile BuildDirectory + filename + ".pdf", canvas.toBuffer()
-
-
-#
-# Layout Options
-#
-
-h_gutter = 10
-v_gutter = 10
-string_spacing = 20
-fret_width = 45
-fret_overhang = .3 * fret_width
-padded_fretboard_width = 2 * v_gutter + fret_width * FretCount + fret_overhang
-padded_fretboard_height = 2 * h_gutter + (StringCount - 1) * string_spacing
-
-
-#
-# Drawing Fretboard and Diagrams
-#
-
-draw_diagrams = true
-if draw_diagrams
-  string_spacing = 6
-  fret_height = 8
-  fret_overhang = 0
-  h_gutter = 5
-  v_gutter = 5
-  note_radius = 1
-  closed_string_fontsize = 4
-  padded_fretboard_width = 2 * h_gutter + (StringCount - 1) * string_spacing
-  padded_fretboard_height = 2 * v_gutter + fret_height * FretCount + fret_overhang
-  above_fretboard = fret_height
-
-if true
-  string_spacing = 12
-  fret_height = 16
-  note_radius = 3
-  closed_string_fontsize = 8
-  padded_fretboard_width = 2 * h_gutter + (StringCount - 1) * string_spacing
-  padded_fretboard_height = 2 * v_gutter + (fret_height + 2) * FretCount + fret_overhang
-
-draw_strings = ->
-  for i in StringNumbers
-    y = i * string_spacing + h_gutter
-    ctx.beginPath()
-    ctx.moveTo h_gutter, y
-    ctx.lineTo h_gutter + FretCount * fret_width + fret_overhang, y
-    ctx.lineWidth = 1
-    ctx.stroke()
-
-draw_frets = ->
-  for fret_number in FretNumbers
-    x = fret_number * fret_width + h_gutter
-    ctx.beginPath()
-    ctx.moveTo x, h_gutter
-    ctx.lineTo x, h_gutter + (StringCount - 1) * string_spacing
-    ctx.lineWidth = 3 if fret_number == 0
-    ctx.stroke()
-    ctx.lineWidth = 1
-
-draw_finger_position = ({string, fret}, options) ->
-  {is_root, color} = options || {}
-  x = h_gutter + (fret - 1) * fret_width + fret_width / 2
-  x = h_gutter if fret == 0
-  ctx.beginPath()
-  ctx.arc x, v_gutter + (6 - string) * string_spacing, 7, 0, 2 * Math.PI, false
-  ctx.fillStyle = 'red'
-  ctx.fillStyle = color or 'white' unless is_root
-  ctx.lineWidth = 2 unless is_root
-  ctx.fill()
-  ctx.stroke()
-  ctx.strokeStyle = 'black'
-  ctx.lineWidth = 1
-
-if draw_diagrams
-  draw_strings = ->
-    for i in StringNumbers
-      x = i * string_spacing + h_gutter
-      ctx.beginPath()
-      ctx.moveTo x, v_gutter + above_fretboard
-      ctx.lineTo x, v_gutter + above_fretboard + FretCount * fret_height + fret_overhang
-      ctx.stroke()
-
-  draw_frets = ->
-    for fret in FretNumbers
-      y = v_gutter + above_fretboard + fret * fret_height
-      ctx.beginPath()
-      ctx.moveTo v_gutter - 0.5, y
-      ctx.lineTo v_gutter + 0.5 + (StringCount - 1) * string_spacing, y
-      ctx.lineWidth = 3 if fret == 0
-      ctx.stroke()
-      ctx.lineWidth = 1
-
-  draw_finger_position = ({string, fret}, options={}) ->
-    {is_root, color} = options
-    y = v_gutter + above_fretboard + (fret - 1) * fret_height + fret_height / 2
-    ctx.fillStyle = color or (if is_root then 'red' else 'white')
-    ctx.strokeStyle = color or (if is_root then 'red' else 'black')
-    ctx.lineWidth = 1
-    ctx.beginPath()
-    ctx.arc h_gutter + string * string_spacing, y, note_radius, 0, 2 * Math.PI, false
-    ctx.fill() if fret or is_root
-    ctx.stroke()
-    ctx.strokeStyle = 'black'
 
 find_barres = (positions) ->
   fret_rows = for fn in FretNumbers

        , Math.PI*3/2, Math.PI/2, false
      ctx.fillStyle = 'rgba(0,0,0, 0.5)'
      ctx.fill()
  if positions
    fretted_strings = []
    for position in positions

    pitches = ((i * 5 + 3) % 12 for i in [0...12])
    for pitch in pitches
      root_fingering = pitch_fingers[pitch]
      chord_name = compute_chord_name pitch, chord
      continue if options.only unless chord_name == options.only
      cell ->
        ctx.font = '7pt Times'
