<commit_before>class Thing
  constructor: (@name, @attributes, existingGid) ->
    @attributes ||= {}
    @gid = existingGid || gid += 1
    registry.register this

    @children = {}
    @parent = null
    @listeners = {}

    @name = "#{this.constructor.name}" unless @name

  # subclass children to provide custom description formats
  detailed: ->
    "#{this}#{utils.eol}#{this.description()}"

  inspection: ->
    "#{this} - #{this.description()}" + \
    utils.eol + \
    "Attributes:" + \
    utils.eol + \
    ("  #{k} = #{v}" for k, v of @attributes when k isnt "description").join(utils.eol) + \
    utils.eol + \
    "Children:" + \
    utils.eol + \
    ("  #{c}" for gid, c of @children).join(utils.eol) + \
    utils.eol + \
    "Actions:" + \
    utils.eol + \
    ("  #{k}" for k, v of @interface).join(utils.eol)

  description: -> @attr("description") || ""

  setName: (name) ->
    @name = name
    @broadcast new Event "change", this, "attribute": "name"

  # return quoted name
  qname: () -> "\"#{this.name}\""

  # maybe return a quoted name (if a space exists in the name)
  mqname: () ->
    if this.name.search(" ") != -1
      this.qname()
    else
      this.name

  # build an object representation of this Thing
  rep: ->
    type: @constructor.name
    gid: @gid
    name: @name
    attributes: @attributes
    parent: @parent?.gid

  # generic child search
  search: (selector, args) =>
    args ||= {}
    searchThing this, selector, args

  # can an attribute be set to a value? redefine in subclasses to provide access control
  canSetAttr: (k, v) ->
    true

  # set and / or return attribute
  attr: (k, v = undefined) ->
    @attributes[k] = v if v?
    @attributes[k]

  # push a value onto an array attribute
  attrPush: (k, v) ->
    @attributes[k]?.push v
    @attributes[k]

  # does any array attribute have a specific value
  attrAny: (k, v) ->
    lst = @attributes[k]
    if lst?
      v in lst
    else
      debug "array attribute not found with key #{k}, keys = " + (k for k, v of @attributes)

  # array of attribute names
  attrNames: () ->
    (k for k, v of @attributes)

  # default string representation
  toString: () ->
    "#{this.name}[#{this.constructor.name}]#{this.gid}"

  listenTo: (thing) ->
#    debug "#{this} starts listening to #{thing}"
    @listeners[thing.gid] = thing

  ignore: (thing) ->
#    debug "#{this} stops listening to #{thing}"
    delete @listeners[thing.gid]

  broadcast: (evt) ->
    for gid, thing of @listeners
#      debug "#{this} routes an event of type #{evt.type} to #{thing}"
      thing.hear evt

  # subclass to implement behaviour
  hear: (evt) ->
#    debug "#{this} hears event of type #{evt.type} from #{evt.source}"

  #
  # Hierarchy methods
  #
  children: () ->
    @children

  siblings: () ->
    if @parent?
      (thing for gid, thing of @parent.children when thing isnt this)
    else
      return []

  siblingsOfType: (type) ->
    (thing for thing in @siblings() when thing.isa(type))

  # subclass this method to determine if thing should be
  # able to contain another thing
  canAdd: (thing) ->
    true

  add: () -><commit_msg>thing documentation<commit_after>class Thing
  constructor: (@name, @attributes, existingGid) ->
    # key / value pairs of attributes
    @attributes ||= {}

    # global Thing id
    @gid = existingGid || gid += 1
    registry.register this

    # object (k/v) of children {Thing}
    @children = {}

    # parent container {Thing}
    @parent = null

    # other Things listening to me
    @listeners = {}

    # use the class name for the object name if non given
    @name = "#{this.constructor.name}" unless @name

  # subclass children to provide custom description formats
  detailed: ->
    "#{this}#{utils.eol}#{this.description()}"

  inspection: ->
    "#{this} - #{this.description()}" + \
    utils.eol + \
    "Attributes:" + \
    utils.eol + \
    ("  #{k} = #{v}" for k, v of @attributes when k isnt "description").join(utils.eol) + \
    utils.eol + \
    "Children:" + \
    utils.eol + \
    ("  #{c}" for gid, c of @children).join(utils.eol) + \
    utils.eol + \
    "Actions:" + \
    utils.eol + \
    ("  #{k}" for k, v of @interface).join(utils.eol)

  description: -> @attr("description") || ""

  setName: (name) ->
    @name = name
    @broadcast new Event "change", this, "attribute": "name"

  # return quoted name
  qname: () -> "\"#{this.name}\""

  # maybe return a quoted name (if a space exists in the name)
  mqname: () ->
    if this.name.search(" ") != -1
      this.qname()
    else
      this.name

  # build an object representation of this Thing
  rep: ->
    type: @constructor.name
    gid: @gid
    name: @name
    attributes: @attributes
    parent: @parent?.gid

  # generic child search
  search: (selector, args) =>
    assert selector?, "selector required"

    args ||= {}
    searchThing this, selector, args

  # can an attribute be set to a value? redefine in subclasses to provide access control
  canSetAttr: (k, v) ->
    true

  # set and / or return attribute
  attr: (k, v = undefined) ->
    @attributes[k] = v if v?
    @attributes[k]

  # push a value onto an array attribute
  attrPush: (k, v) ->
    @attributes[k]?.push v
    @attributes[k]

  # does any array attribute have a specific value
  attrAny: (k, v) ->
    lst = @attributes[k]
    if lst?
      v in lst
    else
      debug "array attribute not found with key #{k}, keys = " + (k for k, v of @attributes)

  # array of attribute names
  attrNames: () ->
    (k for k, v of @attributes)

  # default string representation
  toString: () ->
    "#{this.name}[#{this.constructor.name}]#{this.gid}"

  listenTo: (thing) ->
    @listeners[thing.gid] = thing

  ignore: (thing) ->
    delete @listeners[thing.gid]

  broadcast: (evt) ->
    for gid, thing of @listeners
      thing.hear evt

  # subclass to implement behaviour
  hear: (evt) ->
#    debug "#{this} hears event of type #{evt.type} from #{evt.source}"

  #
  # Hierarchy methods
  #
  children: () ->
    @children

  siblings: () ->
    if @parent?
      (thing for gid, thing of @parent.children when thing isnt this)
    else
      return []

  siblingsOfType: (type) ->
    (thing for thing in @siblings() when thing.isa(type))

  # subclass this method to determine if thing should be
  # able to contain another thing
  canAdd: (thing) ->
    true

  add: () ->
{'fraction_non_alphanumeric': 0.1486971446403495, 'fraction_numerical': 0.0006241223279762834, 'mean_word_length': 2.565072302558398, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6564513', 'n_tokens_mistral': 2139, 'n_tokens_neox': 2100, 'n_words': 669}