Prompt:
# need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

Response:
# check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if @options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject


Response:
@saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    @saxParser.write str.toString()


Prompt:
Convert this CoffeeScript to JavaScript.
```coffeescript
@saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    @saxParser.write str.toString()
```

Response:
this.saxParser.ontext = this.saxParser.oncdata = (text) => {
  var s;
  s = stack[stack.length - 1];
  if (s) {
    return s[charkey] += text;
  }
};

({
  parseString: (str, cb) => {
    if ((cb != null) && typeof cb === "function") {
      this.on("end", function(result) {
        this.reset();
        return cb(null, result);
      });
      this.on("error", function(err) {
        this.reset();
        return cb(err);
      });
    }
    if (str.toString().trim() === '') {
      this.emit("end", null);
      return true;
    }
    return this.saxParser.write(str.toString());
  }
});


Prompt:
Convert this JavaScript to CoffeeScript.
```javascript
this.saxParser.ontext = this.saxParser.oncdata = (text) => {
  var s;
  s = stack[stack.length - 1];
  if (s) {
    return s[charkey] += text;
  }
};

({
  parseString: (str, cb) => {
    if ((cb != null) && typeof cb === "function") {
      this.on("end", function(result) {
        this.reset();
        return cb(null, result);
      });
      this.on("error", function(err) {
        this.reset();
        return cb(err);
      });
    }
    if (str.toString().trim() === '') {
      this.emit("end", null);
      return true;
    }
    return this.saxParser.write(str.toString());
  }
});
```

Response:
@saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    @saxParser.write str.toString()


Prompt:
@saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()

Response:
cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    @saxParser.write str.toString()


Response:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->
    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    @options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
      # always put child nodes in an array
      explicitArray: false
      # ignore all attributes regardless
      ignoreAttrs: false
      # merge attributes and child elements onto parent object.  this may
      # cause collisions.
      mergeAttrs: false
    # overwrite them with the specified options, if any
    @options[key] = value for own key, value of opts

    @reset()

  reset: =>
    # remove all previous listeners for events, to prevent event listener
    # accumulation
    @removeAllListeners()
    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

    # emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = @options.explicitCharkey
    @resultObject = null
    stack = []


Prompt:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->
    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    @options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
      # always put child nodes in an array
      explicitArray: false
      # ignore all attributes regardless
      ignoreAttrs: false
      # merge attributes and child elements onto parent object.  this may
      # cause collisions.
      mergeAttrs: false
    # overwrite them with the specified options, if any
    @options[key] = value for own key, value of opts

    @reset()

Response:
reset: =>
    # remove all previous listeners for events, to prevent event listener
    # accumulation
    @removeAllListeners()
    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

    # emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = @options.explicitCharkey
    @resultObject = null
    stack = []


Response:
# aliases, so we don't have to type so much
    attrkey = @options.attrkey
    charkey = @options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj and not @options.mergeAttrs
            obj[attrkey] = {}
          if @options.mergeAttrs
            obj[key] = node.attributes[key]
          else
            obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]


Prompt:
Convert this CoffeeScript to JavaScript.
```coffeescript
# aliases, so we don't have to type so much
    attrkey = @options.attrkey
    charkey = @options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj and not @options.mergeAttrs
            obj[attrkey] = {}
          if @options.mergeAttrs
            obj[key] = node.attributes[key]
          else
            obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
```

Response:
// aliases, so we don't have to type so much
var attrkey, charkey,
  hasProp = {}.hasOwnProperty;

attrkey = this.options.attrkey;

charkey = this.options.charkey;

this.saxParser.onopentag = (node) => {
  var key, obj, ref;
  obj = {};
  obj[charkey] = "";
  if (!this.options.ignoreAttrs) {
    ref = node.attributes;
    for (key in ref) {
      if (!hasProp.call(ref, key)) continue;
      if (!(attrkey in obj) && !this.options.mergeAttrs) {
        obj[attrkey] = {};
      }
      if (this.options.mergeAttrs) {
        obj[key] = node.attributes[key];
      } else {
        obj[attrkey][key] = node.attributes[key];
      }
    }
  }
  // need a place to store the node name
  obj["#name"] = node.name;
  return stack.push(obj);
};

this.saxParser.onclosetag = () => {
  var nodeName, obj, old, s;
  obj = stack.pop();
  nodeName = obj["#name"];
  delete obj["#name"];
  s = stack[stack.length - 1];
  // remove the '#' key altogether if it's blank
  if (obj[charkey].match(/^\s*$/)) {
    delete obj[charkey];
  } else {
    if (this.options.trim) {
      obj[charkey] = obj[charkey].trim();
    }
    if (this.options.normalize) {
      obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim();
    }
    // also do away with '#' key altogether, if there's no subkeys
    // unless EXPLICIT_CHARKEY is set
    if (Object.keys(obj).length === 1 && charkey in obj && !this.EXPLICIT_CHARKEY) {
      obj = obj[charkey];
    }
  }
  if (this.options.emptyTag !== void 0 && isEmpty(obj)) {
    obj = this.options.emptyTag;
  }
  // check whether we closed all the open tags
  if (stack.length > 0) {
    if (!this.options.explicitArray) {
      if (!(nodeName in s)) {
        return s[nodeName] = obj;
      } else if (s[nodeName] instanceof Array) {
        return s[nodeName].push(obj);
      } else {
        old = s[nodeName];
        return s[nodeName] = [old];
      }
    }
  }
};


Prompt:
Convert this JavaScript to CoffeeScript.
```javascript
// aliases, so we don't have to type so much
var attrkey, charkey,
  hasProp = {}.hasOwnProperty;

attrkey = this.options.attrkey;

charkey = this.options.charkey;

this.saxParser.onopentag = (node) => {
  var key, obj, ref;
  obj = {};
  obj[charkey] = "";
  if (!this.options.ignoreAttrs) {
    ref = node.attributes;
    for (key in ref) {
      if (!hasProp.call(ref, key)) continue;
      if (!(attrkey in obj) && !this.options.mergeAttrs) {
        obj[attrkey] = {};
      }
      if (this.options.mergeAttrs) {
        obj[key] = node.attributes[key];
      } else {
        obj[attrkey][key] = node.attributes[key];
      }
    }
  }
  // need a place to store the node name
  obj["#name"] = node.name;
  return stack.push(obj);
};

this.saxParser.onclosetag = () => {
  var nodeName, obj, old, s;
  obj = stack.pop();
  nodeName = obj["#name"];
  delete obj["#name"];
  s = stack[stack.length - 1];
  // remove the '#' key altogether if it's blank
  if (obj[charkey].match(/^\s*$/)) {
    delete obj[charkey];
  } else {
    if (this.options.trim) {
      obj[charkey] = obj[charkey].trim();
    }
    if (this.options.normalize) {
      obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim();
    }
    // also do away with '#' key altogether, if there's no subkeys
    // unless EXPLICIT_CHARKEY is set
    if (Object.keys(obj).length === 1 && charkey in obj && !this.EXPLICIT_CHARKEY) {
      obj = obj[charkey];
    }
  }
  if (this.options.emptyTag !== void 0 && isEmpty(obj)) {
    obj = this.options.emptyTag;
  }
  // check whether we closed all the open tags
  if (stack.length > 0) {
    if (!this.options.explicitArray) {
      if (!(nodeName in s)) {
        return s[nodeName] = obj;
      } else if (s[nodeName] instanceof Array) {
        return s[nodeName].push(obj);
      } else {
        old = s[nodeName];
        return s[nodeName] = [old];
      }
    }
  }
};
```

Response:
# aliases, so we don't have to type so much
    attrkey = @options.attrkey
    charkey = @options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj and not @options.mergeAttrs
            obj[attrkey] = {}
          if @options.mergeAttrs
            obj[key] = node.attributes[key]
          else
            obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]


Prompt:
# aliases, so we don't have to type so much
    attrkey = @options.attrkey
    charkey = @options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj and not @options.mergeAttrs
            obj[attrkey] = {}
          if @options.mergeAttrs
            obj[key] = node.attributes[key]
          else
            obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

Response:
s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]


Response:
s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if @options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    @saxParser.write str.toString()


Prompt:
s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if @options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>

Response:
s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    @saxParser.write str.toString()


Response:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->
    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    @options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
      # always put child nodes in an array
      explicitArray: false
      # ignore all attributes regardless
      ignoreAttrs: false
      # merge attributes and child elements onto parent object.  this may
      # cause collisions.
      mergeAttrs: false
      # optional validator for schema-driven generawtion
      validator: null
    # overwrite them with the specified options, if any
    @options[key] = value for own key, value of opts

    @reset()

  reset: =>
    # remove all previous listeners for events, to prevent event listener
    # accumulation
    @removeAllListeners()
    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

    # emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = @options.explicitCharkey


Prompt:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->
    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    @options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
      # always put child nodes in an array
      explicitArray: false
      # ignore all attributes regardless
      ignoreAttrs: false
      # merge attributes and child elements onto parent object.  this may
      # cause collisions.
      mergeAttrs: false
      # optional validator for schema-driven generawtion
      validator: null
    # overwrite them with the specified options, if any
    @options[key] = value for own key, value of opts

Response:
@reset()

  reset: =>
    # remove all previous listeners for events, to prevent event listener
    # accumulation
    @removeAllListeners()
    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

    # emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = @options.explicitCharkey


Response:
@resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = @options.attrkey
    charkey = @options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj and not @options.mergeAttrs
            obj[attrkey] = {}
          if @options.mergeAttrs
            obj[key] = node.attributes[key]
          else
            obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      if @options.validator?
        xpath = "/" + (node["#name"] for node in stack).concat(nodeName).join("/")
        obj = @options.validator(xpath, s and s[nodeName], obj)

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s


Prompt:
@resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = @options.attrkey
    charkey = @options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj and not @options.mergeAttrs
            obj[attrkey] = {}
          if @options.mergeAttrs
            obj[key] = node.attributes[key]
          else
            obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]

Response:
delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      if @options.validator?
        xpath = "/" + (node["#name"] for node in stack).concat(nodeName).join("/")
        obj = @options.validator(xpath, s and s[nodeName], obj)

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s


Response:
s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if @options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    try
      @saxParser.write str.toString()
    catch ex
      if ex instanceof exports.ValidationError
        @emit("error", ex.message)
      else
        throw ex


Prompt:
s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if @options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>

Response:
s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    try
      @saxParser.write str.toString()
    catch ex
      if ex instanceof exports.ValidationError
        @emit("error", ex.message)
      else
        throw ex


Response:
@resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = @options.attrkey
    charkey = @options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj and not @options.mergeAttrs
            obj[attrkey] = {}
          if @options.mergeAttrs
            obj[key] = node.attributes[key]
          else
            obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      if @options.validator?
        obj = @options.validator(obj, stack, nodeName)

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj


Prompt:
@resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = @options.attrkey
    charkey = @options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj and not @options.mergeAttrs
            obj[attrkey] = {}
          if @options.mergeAttrs
            obj[key] = node.attributes[key]
          else
            obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]

Response:
delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      if @options.validator?
        obj = @options.validator(obj, stack, nodeName)

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj


Response:
else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if @options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    try
      @saxParser.write str.toString()
    catch ex
      if ex instanceof exports.ValidationError
        @emit("error", ex.message)
      else
        throw ex


Prompt:
else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if @options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]

Response:
if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    try
      @saxParser.write str.toString()
    catch ex
      if ex instanceof exports.ValidationError
        @emit("error", ex.message)
      else
        throw ex


Response:
@resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = @options.attrkey
    charkey = @options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj and not @options.mergeAttrs
            obj[attrkey] = {}
          if @options.mergeAttrs
            obj[key] = node.attributes[key]
          else
            obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      if @options.validator?
        obj = @options.validator.validate(obj, stack, nodeName)

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj


Prompt:
@resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = @options.attrkey
    charkey = @options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj and not @options.mergeAttrs
            obj[attrkey] = {}
          if @options.mergeAttrs
            obj[key] = node.attributes[key]
          else
            obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]

Response:
delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      if @options.validator?
        obj = @options.validator.validate(obj, stack, nodeName)

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj


Response:
else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if @options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    try
      @saxParser.write str.toString()
    catch ex
      @emit("error", ex.message)
      return @saxParser


Prompt:
else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if @options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>

Response:
s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    try
      @saxParser.write str.toString()
    catch ex
      @emit("error", ex.message)
      return @saxParser


Response:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->
    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    @options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
      # always put child nodes in an array
      explicitArray: false
      # ignore all attributes regardless
      ignoreAttrs: false
    # overwrite them with the specified options, if any
    @options[key] = value for own key, value of opts

    @reset()

  reset: =>
    # remove all previous listeners for events, to prevent event listener
    # accumulation
    @removeAllListeners()
    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

    # emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = @options.explicitCharkey
    @resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = @options.attrkey
    charkey = @options.charkey


Prompt:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->
    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    @options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
      # always put child nodes in an array
      explicitArray: false
      # ignore all attributes regardless
      ignoreAttrs: false
    # overwrite them with the specified options, if any
    @options[key] = value for own key, value of opts

    @reset()

  reset: =>
    # remove all previous listeners for events, to prevent event listener
    # accumulation

Response:
@removeAllListeners()
    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

    # emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = @options.explicitCharkey
    @resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = @options.attrkey
    charkey = @options.charkey


Response:
@saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj
            obj[attrkey] = {}
          obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else


Prompt:
Convert this CoffeeScript to JavaScript.
```coffeescript
@saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj
            obj[attrkey] = {}
          obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
```

Response:
var hasProp = {}.hasOwnProperty;

this.saxParser.onopentag = (node) => {
  var key, obj, ref;
  obj = {};
  obj[charkey] = "";
  if (!this.options.ignoreAttrs) {
    ref = node.attributes;
    for (key in ref) {
      if (!hasProp.call(ref, key)) continue;
      if (!(attrkey in obj)) {
        obj[attrkey] = {};
      }
      obj[attrkey][key] = node.attributes[key];
    }
  }
  // need a place to store the node name
  obj["#name"] = node.name;
  return stack.push(obj);
};

this.saxParser.onclosetag = () => {
  var nodeName, obj, old, s;
  obj = stack.pop();
  nodeName = obj["#name"];
  delete obj["#name"];
  s = stack[stack.length - 1];
  // remove the '#' key altogether if it's blank
  if (obj[charkey].match(/^\s*$/)) {
    delete obj[charkey];
  } else {
    if (this.options.trim) {
      obj[charkey] = obj[charkey].trim();
    }
    if (this.options.normalize) {
      obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim();
    }
    // also do away with '#' key altogether, if there's no subkeys
    // unless EXPLICIT_CHARKEY is set
    if (Object.keys(obj).length === 1 && charkey in obj && !this.EXPLICIT_CHARKEY) {
      obj = obj[charkey];
    }
  }
  if (this.options.emptyTag !== void 0 && isEmpty(obj)) {
    obj = this.options.emptyTag;
  }
  // check whether we closed all the open tags
  if (stack.length > 0) {
    if (!this.options.explicitArray) {
      if (!(nodeName in s)) {
        return s[nodeName] = obj;
      } else if (s[nodeName] instanceof Array) {
        return s[nodeName].push(obj);
      } else {
        old = s[nodeName];
        s[nodeName] = [old];
        return s[nodeName].push(obj);
      }
    } else {
      if (!(s[nodeName] instanceof Array)) {
        s[nodeName] = [];
      }
      return s[nodeName].push(obj);
    }
  } else {

  }
};


Prompt:
Convert this JavaScript to CoffeeScript.
```javascript
var hasProp = {}.hasOwnProperty;

this.saxParser.onopentag = (node) => {
  var key, obj, ref;
  obj = {};
  obj[charkey] = "";
  if (!this.options.ignoreAttrs) {
    ref = node.attributes;
    for (key in ref) {
      if (!hasProp.call(ref, key)) continue;
      if (!(attrkey in obj)) {
        obj[attrkey] = {};
      }
      obj[attrkey][key] = node.attributes[key];
    }
  }
  // need a place to store the node name
  obj["#name"] = node.name;
  return stack.push(obj);
};

this.saxParser.onclosetag = () => {
  var nodeName, obj, old, s;
  obj = stack.pop();
  nodeName = obj["#name"];
  delete obj["#name"];
  s = stack[stack.length - 1];
  // remove the '#' key altogether if it's blank
  if (obj[charkey].match(/^\s*$/)) {
    delete obj[charkey];
  } else {
    if (this.options.trim) {
      obj[charkey] = obj[charkey].trim();
    }
    if (this.options.normalize) {
      obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim();
    }
    // also do away with '#' key altogether, if there's no subkeys
    // unless EXPLICIT_CHARKEY is set
    if (Object.keys(obj).length === 1 && charkey in obj && !this.EXPLICIT_CHARKEY) {
      obj = obj[charkey];
    }
  }
  if (this.options.emptyTag !== void 0 && isEmpty(obj)) {
    obj = this.options.emptyTag;
  }
  // check whether we closed all the open tags
  if (stack.length > 0) {
    if (!this.options.explicitArray) {
      if (!(nodeName in s)) {
        return s[nodeName] = obj;
      } else if (s[nodeName] instanceof Array) {
        return s[nodeName].push(obj);
      } else {
        old = s[nodeName];
        s[nodeName] = [old];
        return s[nodeName].push(obj);
      }
    } else {
      if (!(s[nodeName] instanceof Array)) {
        s[nodeName] = [];
      }
      return s[nodeName].push(obj);
    }
  } else {

  }
};
```

Response:
@saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj
            obj[attrkey] = {}
          obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else


Prompt:
@saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj
            obj[attrkey] = {}
          obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim

Response:
obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else


Response:
# if explicitRoot was specified, wrap stuff in the root tag name
        if @options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    @saxParser.write str.toString()


Prompt:
# if explicitRoot was specified, wrap stuff in the root tag name
        if @options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

Response:
parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    @saxParser.write str.toString()


Response:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->
    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    @options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
      # always put child nodes in an array
      explicitArray: false
      # ignore all attributes regardless
      ignoreAttrs: false
    # overwrite them with the specified options, if any
    @options[key] = value for own key, value of opts

    @reset()

  reset: =>
    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

    # emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = @options.explicitCharkey
    @resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = @options.attrkey
    charkey = @options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}


Prompt:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->
    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    @options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
      # always put child nodes in an array
      explicitArray: false
      # ignore all attributes regardless
      ignoreAttrs: false
    # overwrite them with the specified options, if any
    @options[key] = value for own key, value of opts

    @reset()

  reset: =>
    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful

Response:
@saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

    # emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = @options.explicitCharkey
    @resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = @options.attrkey
    charkey = @options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}


Response:
obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj
            obj[attrkey] = {}
          obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if @options.explicitRoot
          # avoid circular references


Prompt:
obj[charkey] = ""
      unless @options.ignoreAttrs
        for own key of node.attributes
          if attrkey not of obj
            obj[attrkey] = {}
          obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if @options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set

Response:
if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if @options.emptyTag != undefined && isEmpty obj
        obj = @options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not @options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if @options.explicitRoot
          # avoid circular references


Response:
old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    @saxParser.write str.toString()


Prompt:
old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>

Response:
if cb? and typeof cb is "function"
      @on "end", (result) ->
        @reset()
        cb null, result
      @on "error", (err) ->
        @reset()
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    @saxParser.write str.toString()


Response:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->

    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
      # always put child nodes in an array
      explicitArray: false
      # ignore all attributes regardless
      ignoreAttrs: false
    # overwrite them with the specified options, if any
    options[key] = value for own key, value of opts

    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

    # emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = options.explicitCharkey
    @resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = options.attrkey
    charkey = options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless options.ignoreAttrs


Prompt:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->

    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
      # always put child nodes in an array
      explicitArray: false
      # ignore all attributes regardless
      ignoreAttrs: false
    # overwrite them with the specified options, if any
    options[key] = value for own key, value of opts

    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,

Response:
normalize: false
    }

    # emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = options.explicitCharkey
    @resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = options.attrkey
    charkey = options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      unless options.ignoreAttrs


Response:
for own key of node.attributes
          if attrkey not of obj
            obj[attrkey] = {}
          obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if options.emptyTag != undefined && isEmpty obj
        obj = options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}


Prompt:
Convert this CoffeeScript to JavaScript.
```coffeescript
for own key of node.attributes
          if attrkey not of obj
            obj[attrkey] = {}
          obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if options.emptyTag != undefined && isEmpty obj
        obj = options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
```

Response:
var key, ref,
  hasProp = {}.hasOwnProperty;

ref = node.attributes;
for (key in ref) {
  if (!hasProp.call(ref, key)) continue;
  if (!(attrkey in obj)) {
    obj[attrkey] = {};
  }
  obj[attrkey][key] = node.attributes[key];
}

// need a place to store the node name
obj["#name"] = node.name;

stack.push(obj);

this.saxParser.onclosetag = () => {
  var nodeName, obj, old, s;
  obj = stack.pop();
  nodeName = obj["#name"];
  delete obj["#name"];
  s = stack[stack.length - 1];
  // remove the '#' key altogether if it's blank
  if (obj[charkey].match(/^\s*$/)) {
    delete obj[charkey];
  } else {
    if (options.trim) {
      obj[charkey] = obj[charkey].trim();
    }
    if (options.normalize) {
      obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim();
    }
    // also do away with '#' key altogether, if there's no subkeys
    // unless EXPLICIT_CHARKEY is set
    if (Object.keys(obj).length === 1 && charkey in obj && !this.EXPLICIT_CHARKEY) {
      obj = obj[charkey];
    }
  }
  if (options.emptyTag !== void 0 && isEmpty(obj)) {
    obj = options.emptyTag;
  }
  // check whether we closed all the open tags
  if (stack.length > 0) {
    if (!options.explicitArray) {
      if (!(nodeName in s)) {
        return s[nodeName] = obj;
      } else if (s[nodeName] instanceof Array) {
        return s[nodeName].push(obj);
      } else {
        old = s[nodeName];
        s[nodeName] = [old];
        return s[nodeName].push(obj);
      }
    } else {
      if (!(s[nodeName] instanceof Array)) {
        s[nodeName] = [];
      }
      return s[nodeName].push(obj);
    }
  } else {
    // if explicitRoot was specified, wrap stuff in the root tag name
    if (options.explicitRoot) {
      // avoid circular references
      old = obj;
      return obj = {};
    }
  }
};


Prompt:
Convert this JavaScript to CoffeeScript.
```javascript
var key, ref,
  hasProp = {}.hasOwnProperty;

ref = node.attributes;
for (key in ref) {
  if (!hasProp.call(ref, key)) continue;
  if (!(attrkey in obj)) {
    obj[attrkey] = {};
  }
  obj[attrkey][key] = node.attributes[key];
}

// need a place to store the node name
obj["#name"] = node.name;

stack.push(obj);

this.saxParser.onclosetag = () => {
  var nodeName, obj, old, s;
  obj = stack.pop();
  nodeName = obj["#name"];
  delete obj["#name"];
  s = stack[stack.length - 1];
  // remove the '#' key altogether if it's blank
  if (obj[charkey].match(/^\s*$/)) {
    delete obj[charkey];
  } else {
    if (options.trim) {
      obj[charkey] = obj[charkey].trim();
    }
    if (options.normalize) {
      obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim();
    }
    // also do away with '#' key altogether, if there's no subkeys
    // unless EXPLICIT_CHARKEY is set
    if (Object.keys(obj).length === 1 && charkey in obj && !this.EXPLICIT_CHARKEY) {
      obj = obj[charkey];
    }
  }
  if (options.emptyTag !== void 0 && isEmpty(obj)) {
    obj = options.emptyTag;
  }
  // check whether we closed all the open tags
  if (stack.length > 0) {
    if (!options.explicitArray) {
      if (!(nodeName in s)) {
        return s[nodeName] = obj;
      } else if (s[nodeName] instanceof Array) {
        return s[nodeName].push(obj);
      } else {
        old = s[nodeName];
        s[nodeName] = [old];
        return s[nodeName].push(obj);
      }
    } else {
      if (!(s[nodeName] instanceof Array)) {
        s[nodeName] = [];
      }
      return s[nodeName].push(obj);
    }
  } else {
    // if explicitRoot was specified, wrap stuff in the root tag name
    if (options.explicitRoot) {
      // avoid circular references
      old = obj;
      return obj = {};
    }
  }
};
```

Response:
for own key of node.attributes
          if attrkey not of obj
            obj[attrkey] = {}
          obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if options.emptyTag != undefined && isEmpty obj
        obj = options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}


Prompt:
for own key of node.attributes
          if attrkey not of obj
            obj[attrkey] = {}
          obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

Response:
if options.emptyTag != undefined && isEmpty obj
        obj = options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}


Response:
obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        cb null, result
      @on "error", (err) ->
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    @saxParser.write str.toString()


Prompt:
obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>

Response:
if cb? and typeof cb is "function"
      @on "end", (result) ->
        cb null, result
      @on "error", (err) ->
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    @saxParser.write str.toString()


Response:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->

    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
      # always put child nodes in an array
      explicitArray: false
    # overwrite them with the specified options, if any
    options[key] = value for own key, value of opts

    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

    # emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = options.explicitCharkey
    @resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = options.attrkey
    charkey = options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      for own key of node.attributes
        if attrkey not of obj
          obj[attrkey] = {}


Prompt:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->

    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
      # always put child nodes in an array
      explicitArray: false
    # overwrite them with the specified options, if any
    options[key] = value for own key, value of opts

    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

Response:
# emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = options.explicitCharkey
    @resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = options.attrkey
    charkey = options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      for own key of node.attributes
        if attrkey not of obj
          obj[attrkey] = {}


Response:
obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if options.emptyTag != undefined && isEmpty obj
        obj = options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if not options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj


Prompt:
obj[attrkey][key] = node.attributes[key]

      # need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if options.emptyTag != undefined && isEmpty obj
        obj = options.emptyTag

Response:
# check whether we closed all the open tags
      if stack.length > 0
        if not options.explicitArray
          if nodeName not of s
            s[nodeName] = obj
          else if s[nodeName] instanceof Array
            s[nodeName].push obj
          else
            old = s[nodeName]
            s[nodeName] = [old]
            s[nodeName].push obj
        else
          if not (s[nodeName] instanceof Array)
            s[nodeName] = []
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj


Response:
@emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        cb null, result
      @on "error", (err) ->
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    @saxParser.write str.toString()


Prompt:
@emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"

Response:
@on "end", (result) ->
        cb null, result
      @on "error", (err) ->
        cb err

    if str.toString().trim() is ''
      @emit "end", null
      return true

    @saxParser.write str.toString()


Response:
@emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        cb null, result
      @on "error", (err) ->
        cb err

    @saxParser.write str.toString()


Prompt:
@emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

Response:
parseString: (str, cb) =>
    if cb? and typeof cb is "function"
      @on "end", (result) ->
        cb null, result
      @on "error", (err) ->
        cb err

    @saxParser.write str.toString()


Response:
@emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str, cb) =>
    if cb? and typeof cb is 'function'
      @on 'end', (result) ->
        cb null, result
      @on 'error', (err) ->
        cb err

    @saxParser.write str.toString()


Prompt:
@emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

Response:
parseString: (str, cb) =>
    if cb? and typeof cb is 'function'
      @on 'end', (result) ->
        cb null, result
      @on 'error', (err) ->
        cb err

    @saxParser.write str.toString()


Response:
@emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text

  parseString: (str) =>
    @saxParser.write str.toString()


Prompt:
@emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]

Response:
if s
        s[charkey] += text

  parseString: (str) =>
    @saxParser.write str.toString()


Response:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->

    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
    # overwrite them with the specified options, if any
    options[key] = value for own key, value of opts

    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

    # emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = options.explicitCharkey
    @resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = options.attrkey
    charkey = options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      for own key of node.attributes
        if attrkey not of obj
          obj[attrkey] = {}
        obj[attrkey][key] = node.attributes[key]


Prompt:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->

    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
    # overwrite them with the specified options, if any
    options[key] = value for own key, value of opts

    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

Response:
# emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = options.explicitCharkey
    @resultObject = null
    stack = []
    # aliases, so we don't have to type so much
    attrkey = options.attrkey
    charkey = options.charkey

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[charkey] = ""
      for own key of node.attributes
        if attrkey not of obj
          obj[attrkey] = {}
        obj[attrkey][key] = node.attributes[key]


Response:
# need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if options.emptyTag != undefined && isEmpty obj
        obj = options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if nodeName not of s
          s[nodeName] = obj
        else if s[nodeName] instanceof Array
          s[nodeName].push obj
        else
          old = s[nodeName]
          s[nodeName] = [old]
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text


Prompt:
# need a place to store the node name
      obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[charkey].match(/^\s*$/)
        delete obj[charkey]
      else
        obj[charkey] = obj[charkey].trim() if options.trim
        obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
          obj = obj[charkey]

      if options.emptyTag != undefined && isEmpty obj
        obj = options.emptyTag

Response:
# check whether we closed all the open tags
      if stack.length > 0
        if nodeName not of s
          s[nodeName] = obj
        else if s[nodeName] instanceof Array
          s[nodeName].push obj
        else
          old = s[nodeName]
          s[nodeName] = [old]
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[charkey] += text


Response:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->

    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
    # overwrite them with the specified options, if any
    options[key] = value for own key, value of opts

    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

    # emit one error event if the sax parser fails. this is mostly a hack, but
    # the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = options.explicitCharkey
    @ATTRKEY = options.attrkey
    @CHARKEY = options.charkey
    @resultObject = null
    stack = []

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[@CHARKEY] = ""
      for own key of node.attributes
        if @ATTRKEY not of obj
          obj[@ATTRKEY] = {}
        obj[@ATTRKEY][key] = node.attributes[key]

      # need a place to store the node name


Prompt:
class exports.Parser extends events.EventEmitter
  constructor: (opts) ->

    # default options. for compatibility's sake set to some
    # sub-optimal settings. might change in the future.
    options =
      explicitCharkey: false
      trim: true
      # normalize implicates trimming, just so you know
      normalize: true
      # set default attribute object key
      attrkey: "@"
      # set default char object key
      charkey: "#"
    # overwrite them with the specified options, if any
    options[key] = value for own key, value of opts

    # make the SAX parser. tried trim and normalize, but they are not
    # very helpful
    @saxParser = sax.parser true, {
      trim: false,
      normalize: false
    }

    # emit one error event if the sax parser fails. this is mostly a hack, but

Response:
# the sax parser isn't state of the art either.
    err = false
    @saxParser.onerror = (error) =>
      if ! err
        err = true
        @emit "error", error

    # always use the '#' key, even if there are no subkeys
    # setting this property by and is deprecated, yet still supported.
    # better pass it as explicitCharkey option to the constructor
    @EXPLICIT_CHARKEY = options.explicitCharkey
    @ATTRKEY = options.attrkey
    @CHARKEY = options.charkey
    @resultObject = null
    stack = []

    @saxParser.onopentag = (node) =>
      obj = {}
      obj[@CHARKEY] = ""
      for own key of node.attributes
        if @ATTRKEY not of obj
          obj[@ATTRKEY] = {}
        obj[@ATTRKEY][key] = node.attributes[key]

      # need a place to store the node name


Response:
obj["#name"] = node.name
      stack.push obj

    @saxParser.onclosetag = =>
      obj = stack.pop()
      nodeName = obj["#name"]
      delete obj["#name"]

      s = stack[stack.length - 1]
      # remove the '#' key altogether if it's blank
      if obj[@CHARKEY].match(/^\s*$/)
        delete obj[@CHARKEY]
      else
        obj[@CHARKEY] = obj[@CHARKEY].trim() if options.trim
        obj[@CHARKEY] = obj[@CHARKEY].replace(/\s{2,}/g, " ").trim() if options.normalize
        # also do away with '#' key altogether, if there's no subkeys
        # unless EXPLICIT_CHARKEY is set
        if Object.keys(obj).length == 1 and @CHARKEY of obj and not @EXPLICIT_CHARKEY
          obj = obj[@CHARKEY]

      if options.emptyTag != undefined && isEmpty obj
        obj = options.emptyTag

      # check whether we closed all the open tags
      if stack.length > 0
        if nodeName not of s
          s[nodeName] = obj
        else if s[nodeName] instanceof Array
          s[nodeName].push obj
        else
          old = s[nodeName]
          s[nodeName] = [old]
          s[nodeName].push obj
      else
        # if explicitRoot was specified, wrap stuff in the root tag name
        if options.explicitRoot
          # avoid circular references
          old = obj
          obj = {}
          obj[nodeName] = old

        @resultObject = obj
        @emit "end", @resultObject

    @saxParser.ontext = @saxParser.oncdata = (text) =>
      s = stack[stack.length - 1]
      if s
        s[@CHARKEY] += text

  parseString: (str) =>