   #.........................................................................................................
   ### Finishing ###
   yield from @_walk_closing_events                      me
+  yield from @_walk_fail_events                         me
   #.........................................................................................................
   # ### dump description for debugging ###
   # ### TAINT make dump configurable ###

  yield return

#-----------------------------------------------------------------------------------------------------------
@_walk_field_designations_from_hints = ( me, fieldhints ) ->
  ### TAINT this will have to be changed to allow for named fields ###
  count           = 0
  fieldhints_set  = new Set ( _.trim() for _ in fieldhints.split ',' )
  if fieldhints_set.has '*'
    keys    = Object.keys me.fieldcells
    count  += keys.length
    yield key for key in keys
  else
    seen_field_designations = new Set()
    for fieldhint from fieldhints_set

#===========================================================================================================
# PUBLIC API
#-----------------------------------------------------------------------------------------------------------
@_set_gridsize = ( me, direction, text ) ->
  unless direction in [ 'width', 'height', ]
    throw _stackerr me, 'µ9061', "expected 'width' or 'height', got #{rpr direction}"
  p = "grid#{direction}"
  #.........................................................................................................
  ### Apply default unless text matches integer pattern: ###
  unless ( match = text.match /^\s*(\d+)\s*$/ )?
    me[ p ] = me.default[ p ]
    return _record_fail  me, 'µ4833', "need a text like '3' or similar for mkts-table/#{p}, got #{rpr text}"
  #.......................................................................................................
  ### Do nothing if dimension already defined: ###
  if me[ p ]?
    return _record_fail me, 'µ5689', "unable to re-define #{p}"
  #.........................................................................................................
  me[ p ] = parseInt match[ 1 ], 10
  return null

#-----------------------------------------------------------------------------------------------------------
@_set_unitsize = ( me, direction, text ) ->
  unless direction in [ 'width', 'height', ]
    throw _stackerr me, 'µ4613', "expected 'width' or 'height', got #{rpr direction}"
  p = "unit#{direction}"
  #.........................................................................................................
  ### Do nothing if dimension already defined: ###
  if me[ p ]?
    return _record_fail me, 'µ5661', "unable to re-define #{p}"
  #.........................................................................................................
  me[ p ] = text
  return null

#-----------------------------------------------------------------------------------------------------------
@_set_cellsizes = ( me, direction, text ) ->
  unless direction in [ 'width', 'height', ]
    throw _stackerr me, 'µ2352', "expected 'width' or 'height', got #{rpr direction}"
  p = "cell#{direction}s"
  #.........................................................................................................
  ### Do nothing if dimension already defined: ###
  if me[ p ].length > 1
    return _record_fail me, 'µ8613', "unable to re-define #{p}"
  #.........................................................................................................
  if direction is 'width'
    @_ensure_gridwidth me
    lane_count = me.gridwidth
  else
    @_ensure_gridheight me
    lane_count = me.gridheight
  #.........................................................................................................
  ### Apply default unless text matches (simplified) float pattern: ###
  unless ( match = text.match /^([+\d.]+)$/ )?
    _record_fail me, 'µ6377', "need a text like '2.7' or similar for mkts-table/#{p}, got #{rpr text}"
    value = me.default[ p ]
  else
    value = parseFloat text
  me[ p ][  0 ] = value ### set default ###
  me[ p ][ nr ] = value for nr in [ 1 .. lane_count ]
  #.........................................................................................................
  return null

#-----------------------------------------------------------------------------------------------------------
@gridwidth    = ( me, text ) -> @_set_gridsize  me, 'width',    text
@gridheight   = ( me, text ) -> @_set_gridsize  me, 'height',   text
@unitwidth    = ( me, text ) -> @_set_unitsize  me, 'width',    text
@unitheight   = ( me, text ) -> @_set_unitsize  me, 'height',   text
@cellwidths   = ( me, text ) -> @_set_cellsizes me, 'width',    text
@cellheights  = ( me, text ) -> @_set_cellsizes me, 'height',   text

#-----------------------------------------------------------------------------------------------------------
@fieldcells = ( me, text ) ->
  unless ( type = CND.type_of text ) is 'text'
    throw new Error "(MKTS/TABLE µ1064) need a text for mkts-table/fieldcells, got a #{type}"
  #.........................................................................................................
  @_ensure_gridwidth  me
  @_ensure_gridheight me
