text: import "../core/ns";
  import "selection";
  
  d3_selectionPrototype.attr = function(name, value) {
    if (arguments.length < 2) {
  
      // For attr(string), return the attribute value for the first node.
      if (typeof name === "string") {
        var node = this.node();
        name = d3.ns.qualify(name);
        return name.local
            ? node.getAttributeNS(name.space, name.local)
            : node.getAttribute(name);
      }
  
      // For attr(object), the object specifies the names and values of the
      // attributes to set or remove. The values may be functions that are
      // evaluated for each element.
      for (value in name) this.each(d3_selection_attr(value, name[value]));
      return this;
    }
  
    return this.each(d3_selection_attr(name, value));
  };
  
  function d3_selection_attr(name, value) {
    name = d3.ns.qualify(name);
  
    // For attr(string, null), remove the attribute with the specified name.
    function attrNull() {
      this.removeAttribute(name);
    }
    function attrNullNS() {
      this.removeAttributeNS(name.space, name.local);
    }
  
    // For attr(string, string), set the attribute with the specified name.
    function attrConstant() {
      this.setAttribute(name, value);
    }
    function attrConstantNS() {
      this.setAttributeNS(name.space, name.local, value);
    }
  
    // For attr(string, function), evaluate the function for each element, and set
    // or remove the attribute as appropriate.
    function attrFunction() {
      var x = value.apply(this, arguments);
      if (x == null) this.removeAttribute(name);
      else this.setAttribute(name, x);
    }
    function attrFunctionNS() {
      var x = value.apply(this, arguments);
      if (x == null) this.removeAttributeNS(name.space, name.local);
      else this.setAttributeNS(name.space, name.local, x);
    }
  
    return value == null
        ? (name.local ? attrNullNS : attrNull) : (typeof value === "function"
        ? (name.local ? attrFunctionNS : attrFunction)
        : (name.local ? attrConstantNS : attrConstant));
  }
  