<commit_before>/*
 *  Copyright 2011 Rackspace
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

var sprintf = require('./sprintf').sprintf;
var ElementPath = require('./elementpath');
var XMLParser = require('./parser').XMLParser;
var TreeBuilder = require('./parser').TreeBuilder;

function merge(a, b) {
  var c = {}, attrname;

  for (attrname in a) {
    if (a.hasOwnProperty(attrname)) {
      c[attrname] = a[attrname];
    }
  }
  for (attrname in b) {
    if (b.hasOwnProperty(attrname)) {
      c[attrname] = b[attrname];
    }
  }
  return c;
}

var element_ids = 0;

function Element(tag, attrib)
{
  this._id = element_ids++;
  this.tag = tag;
  this.attrib = {};
  this.text = null;
  this.tail = null;
  this._children = [];

  if (attrib) {
    this.attrib = merge(this.attrib, attrib);
  }
}

Element.prototype.toString = function()
{
  return sprintf("<Element %s at %s>", this.tag, this._id);
};

Element.prototype.makeelement = function(tag, attrib)
{
  return new Element(tag, attrib);
};

Element.prototype.len = function()
{
  return this._children.length;
};

Element.prototype.getItem = function(index)
{
  return this._children[index];
};

Element.prototype.setItem = function(index, element)
{
  this._children[index] = element;
};

Element.prototype.delItem = function(index)
{
  this._children.splice(index, 1);
};

Element.prototype.getSlice = function(start, stop)
{
  return this._children.slice(start, stop);
};

Element.prototype.setSlice = function(start, stop, elements)
{
  var i;
  var k = 0;
  for (i = start; i < stop; i++, k++) {
    this._children[i] = elements[k];
  }
};

Element.prototype.delSlice = function(start, stop)
{
  this._children.splice(start, stop - start);
};

Element.prototype.append = function(element)
{
  this._children.push(element);
};

Element.prototype.extend = function(elements)
{
  this._children.concat(elements);
};

Element.prototype.insert = function(index, element)
{
  this._children[index] = element;
};

Element.prototype.remove = function(index, element)
{
  this._children = this._children.filter(function(e) {
    /* TODO: is this the right way to do this? */
    if (e._id === element._id) {
      return false;
    }
    return true;
  });
};

Element.prototype.getchildren = function() {
  return this._children;
};

Element.prototype.find = function(path)
{
  return ElementPath.find(this, path);
};

Element.prototype.findtext = function(path, defvalue)
{
  return ElementPath.findtext(this, path, defvalue);
};

Element.prototype.findall = function(path, defvalue)
{
  return ElementPath.findall(this, path, defvalue);
};

Element.prototype.clear = function()
{
  this.attrib = {};
  this._children = [];
  this.text = null;
  this.tail = null;
};

Element.prototype.get = function(key, defvalue)
{
  if (this.attrib[key] !== undefined) {
    return this.attrib[key];
  }
  else {
    return defvalue;
  }
};

Element.prototype.set = function(key, value)
{
  this.attrib[key] = value;
};

Element.prototype.keys = function()
{
  return Object.keys(this.attrib);
};

Element.prototype.items = function()
{
  var rv = [];
  for (var k in this.attrib) {
    if (this.attrib.hasOwnProperty(k)) {
      rv.push([k, this.attrib[k]]);
    }
  }
  return rv;
};

/*
 * In python this uses a generator, but in v8 we don't have em,
 * so we use a callback instead.
 **/
Element.prototype.iter = function(tag, callback)
{
  var self = this;
  var i, child;

  if (tag === "*") {
    tag = null;
  }

  if (tag === null || this.tag === tag) {
    callback(self);
  }

  for (i = 0; i < this._children.length; i++) {
    child = this._children[i];
    child.iter(tag, function(e) {
      callback(e);
    });
  }
};

Element.prototype.itertext = function(callback)
{
  this.iter(null, function(e) {
    if (e.text) {
      callback(e.text);
    }

    if (e.tail) {
      callback(e.tail);
    }
  });
};

function SubElement(parent, tag, attrib) {
  var element = parent.makeelement(tag, attrib);
  parent.append(element);
  return element;
}

function Comment(text) {
  var element = new Element(Comment);
  if (text) {
    element.text = text;
  }
  return element;
}

function ProcessingInstruction(target, text)
{
  var element = new Element(ProcessingInstruction);
  element.text = target;
  if (text) {
    element.text = element.text + " " + text;
  }
  return element;
}

function QName(text_or_uri, tag)
{
  if (tag) {
    text_or_uri = sprintf("{%s}%s", text_or_uri, tag);
  }
  this.text = text_or_uri;
}

QName.prototype.toString = function() {
  return this.text;
};

function ElementTree(element)
{
  this._root = element;
}

ElementTree.prototype.getroot = function() {
  return this._root;
};

ElementTree.prototype._setroot = function(element) {
  this._root = element;
};

ElementTree.prototype.parse = function(source, parser) {
  if (!parser) {
    parser = new XMLParser(new TreeBuilder());
  }
  parser.feed(source);
  this._root = parser.close();
  return this._root;
};

ElementTree.prototype.iter = function(tag, callback) {
  this._root.iter(tag, callback);
};

ElementTree.prototype.find = function(path) {
  return this._root.find(path);
};

ElementTree.prototype.findtext = function(path, defvalue) {
  return this._root.findtext(path, defvalue);
};

ElementTree.prototype.findall = function(path) {
  return this._root.findall(path);
};

/**
 * Unlike ElementTree, we don't write to a file, we return you a string.
 */
ElementTree.prototype.write = function(options) {
  var sb = [];
  options = merge({
    encoding: 'utf-8',
    xml_declaration: null,
    default_namespace: null,
    method: 'xml'}, options);

  if (options.xml_declaration !== false) {
    sb.push("<?xml version='1.0' encoding='"+options.encoding +"'?>\n");
  }

  if (options.method === "text") {
    _serialize_text(sb, self._root, encoding);
  }
  else {
    var qnames, namespaces;
    var x = _namespaces(this._root, options.encoding, options.default_namespace);
    qnames = x[0];
    namespaces = x[1];

    if (options.method === "xml") {
      _serialize_xml(function(data) {
        sb.push(data);
      }, this._root, options.encoding, qnames, namespaces);
    }
    else {
      /* TODO: html */
      throw new Error("unknown serialization method "+ options.method);
    }
  }

  return sb.join("");
};

var _namespace_map = {
    /* "well-known" namespace prefixes */
    "http://www.w3.org/XML/1998/namespace": "xml",
    "http://www.w3.org/1999/xhtml": "html",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf",
    "http://schemas.xmlsoap.org/wsdl/": "wsdl",
    /* xml schema */
    "http://www.w3.org/2001/XMLSchema": "xs",
    "http://www.w3.org/2001/XMLSchema-instance": "xsi",
    /* dublic core */
    "http://purl.org/dc/elements/1.1/": "dc",
};

/* TODO: benchmark single regex */
// TODO replace without regex only replaces single instance
function _escape_attrib(text, encoding) {
  /* TODO: handle encoding */
  if (text.indexOf("&") !== -1) {
    text = text.replace("&", "&");
  }
  if (text.indexOf("<") !== -1) {
    text = text.replace("<", "<");
  }
  if (text.indexOf(">") !== -1) {
    text = text.replace(">", ">");
  }
  if (text.indexOf("\"") !== -1) {
    text = text.replace("\"", """);
  }
  if (text.indexOf("\n") !== -1) {
    text = text.replace("\n", "
");
  }

  return text;
}

function _escape_cdata(text, encoding) {
  /* TODO: handle encoding */
  if (text.indexOf("&") !== -1) {
    text = text.replace("&", "&");
  }
  if (text.indexOf("<") !== -1) {
    text = text.replace("<", "<");
  }
  if (text.indexOf(">") !== -1) {
    text = text.replace(">", ">");
  }

  return text;
}

function _namespaces(elem, encoding, default_namespace) {
  var qnames = {};
  var namespaces = {};

  if (default_namespace) {
    namespaces[default_namespace] = "";
  }

  function add_qname(qname) {
    /* TODO: qname support */
    if (qname[0] === "{") {
      var tmp = qname.substring(1).split("}", 2);
      var uri = tmp[0];
      var tag = tmp[1];
      var prefix = namespaces[uri];
      if (prefix === undefined) {
        prefix = _namespace_map[uri];
        if (prefix === undefined) {
          prefix = "ns" + namespaces.length;
        }
        if (prefix !== "xml") {
          namespaces[uri] = prefix;
        }
      }

      if (prefix) {
        qnames[qname] = sprintf("%s:%s", prefix, tag);
      }
      else {
        qnames[qname] = tag;
      }
    }
    else {
      /* TOOD: default namespaces (?) */
      qnames[qname] = qname;
    }
  }

  elem.iter(null, function(e) {
    var i;
    var tag = e.tag;
    var text = e.text;
    var items = e.items();

    if (tag instanceof QName && qnames[tag.text] === undefined) {
      add_qname(tag.text);
    }
    else if (typeof(tag) === "string") {
      add_qname(tag);
    }
    else if (tag !== null && tag !== Comment && tag !== ProcessingInstruction) {
      throw new Error('Invalid tag type for serialization: '+ tag);
    }

    if (text instanceof QName && qnames[text.text] === undefined) {
      add_qname(text.text);
    }

    items.forEach(function(item) {
      var key = item[0],
          value = item[1];
      if (key instanceof QName) {
        key = key.text;
      }

      if (qnames[key] === undefined) {
        add_qname(key);
      }

      if (value instanceof QName && qnames[value.text] === undefined) {
        add_qname(value.text);
      }
    });
  });
  return [qnames, namespaces];
}

function _serialize_xml(write, elem, encoding, qnames, namespaces) {
  var tag = elem.tag;
  var text = elem.text;
  var items;
  var i;

  if (tag === Comment) {
    write(sprintf("<!--%s-->", _escape_cdata(text, encoding)));
  }
  else if (tag === ProcessingInstruction) {
    write(sprintf("<?%s?>", _escape_cdata(text, encoding)));
  }
  else {
    tag = qnames[tag];
    if (tag === undefined) {
      if (text) {
        write(_escape_cdata(text, encoding));
      }
      elem.iter(function(e) {
        _serialize_xml(write, e, encoding, qnames, null);
      });
    }
    else {
      write("<" + tag);
      items = elem.items();
      items.sort();
      items.forEach(function(item) {
        var k = item[0],
            v = item[1];

          if (k instanceof QName) {
            k = k.text;
          }

          if (v instanceof QName) {
            v = qnames[v.text];
          }
          else {
            v = _escape_attrib(v, encoding);
          }
          write(sprintf(" %s=\"%s\"", qnames[k], v));
      });

      if (namespaces) {
        /* TODO: write xmlns */
      }

      if (text || elem.len()) {
        write(">");
        if (text) {
          write(_escape_cdata(text, encoding));
        }
        elem._children.forEach(function(e) {
          _serialize_xml(write, e, encoding, qnames, null);
        });

        write("</" + tag + ">");
      }
      else {
        write(" />");
      }
    }
  }
}

exports.PI = ProcessingInstruction;
exports.Comment = Comment;
exports.ProcessingInstruction = ProcessingInstruction;
exports.SubElement = SubElement;
exports.QName = QName;
exports.ElementTree = ElementTree;
exports.ElementPath = require('./elementpath');
exports.Element = function(tag, attrib) {
  return new Element(tag, attrib);
};

exports.XML = function(data) {
  var et = new ElementTree();
  return et.parse(data);
};
<commit_msg>Use items function from utils.<commit_after>/*
 *  Copyright 2011 Rackspace
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

var sprintf = require('./sprintf').sprintf;

var utils = require('./utils');
var ElementPath = require('./elementpath');
var XMLParser = require('./parser').XMLParser;
var TreeBuilder = require('./parser').TreeBuilder;

function merge(a, b) {
  var c = {}, attrname;

  for (attrname in a) {
    if (a.hasOwnProperty(attrname)) {
      c[attrname] = a[attrname];
    }
  }
  for (attrname in b) {
    if (b.hasOwnProperty(attrname)) {
      c[attrname] = b[attrname];
    }
  }
  return c;
}

var element_ids = 0;

function Element(tag, attrib)
{
  this._id = element_ids++;
  this.tag = tag;
  this.attrib = {};
  this.text = null;
  this.tail = null;
  this._children = [];

  if (attrib) {
    this.attrib = merge(this.attrib, attrib);
  }
}

Element.prototype.toString = function()
{
  return sprintf("<Element %s at %s>", this.tag, this._id);
};

Element.prototype.makeelement = function(tag, attrib)
{
  return new Element(tag, attrib);
};

Element.prototype.len = function()
{
  return this._children.length;
};

Element.prototype.getItem = function(index)
{
  return this._children[index];
};

Element.prototype.setItem = function(index, element)
{
  this._children[index] = element;
};

Element.prototype.delItem = function(index)
{
  this._children.splice(index, 1);
};

Element.prototype.getSlice = function(start, stop)
{
  return this._children.slice(start, stop);
};

Element.prototype.setSlice = function(start, stop, elements)
{
  var i;
  var k = 0;
  for (i = start; i < stop; i++, k++) {
    this._children[i] = elements[k];
  }
};

Element.prototype.delSlice = function(start, stop)
{
  this._children.splice(start, stop - start);
};

Element.prototype.append = function(element)
{
  this._children.push(element);
};

Element.prototype.extend = function(elements)
{
  this._children.concat(elements);
};

Element.prototype.insert = function(index, element)
{
  this._children[index] = element;
};

Element.prototype.remove = function(index, element)
{
  this._children = this._children.filter(function(e) {
    /* TODO: is this the right way to do this? */
    if (e._id === element._id) {
      return false;
    }
    return true;
  });
};

Element.prototype.getchildren = function() {
  return this._children;
};

Element.prototype.find = function(path)
{
  return ElementPath.find(this, path);
};

Element.prototype.findtext = function(path, defvalue)
{
  return ElementPath.findtext(this, path, defvalue);
};

Element.prototype.findall = function(path, defvalue)
{
  return ElementPath.findall(this, path, defvalue);
};

Element.prototype.clear = function()
{
  this.attrib = {};
  this._children = [];
  this.text = null;
  this.tail = null;
};

Element.prototype.get = function(key, defvalue)
{
  if (this.attrib[key] !== undefined) {
    return this.attrib[key];
  }
  else {
    return defvalue;
  }
};

Element.prototype.set = function(key, value)
{
  this.attrib[key] = value;
};

Element.prototype.keys = function()
{
  return Object.keys(this.attrib);
};

Element.prototype.items = function()
{
  return utils.items(this.attrib);
};

/*
 * In python this uses a generator, but in v8 we don't have em,
 * so we use a callback instead.
 **/
Element.prototype.iter = function(tag, callback)
{
  var self = this;
  var i, child;

  if (tag === "*") {
    tag = null;
  }

  if (tag === null || this.tag === tag) {
    callback(self);
  }

  for (i = 0; i < this._children.length; i++) {
    child = this._children[i];
    child.iter(tag, function(e) {
      callback(e);
    });
  }
};

Element.prototype.itertext = function(callback)
{
  this.iter(null, function(e) {
    if (e.text) {
      callback(e.text);
    }

    if (e.tail) {
      callback(e.tail);
    }
  });
};

function SubElement(parent, tag, attrib) {
  var element = parent.makeelement(tag, attrib);
  parent.append(element);
  return element;
}

function Comment(text) {
  var element = new Element(Comment);
  if (text) {
    element.text = text;
  }
  return element;
}

function ProcessingInstruction(target, text)
{
  var element = new Element(ProcessingInstruction);
  element.text = target;
  if (text) {
    element.text = element.text + " " + text;
  }
  return element;
}

function QName(text_or_uri, tag)
{
  if (tag) {
    text_or_uri = sprintf("{%s}%s", text_or_uri, tag);
  }
  this.text = text_or_uri;
}

QName.prototype.toString = function() {
  return this.text;
};

function ElementTree(element)
{
  this._root = element;
}

ElementTree.prototype.getroot = function() {
  return this._root;
};

ElementTree.prototype._setroot = function(element) {
  this._root = element;
};

ElementTree.prototype.parse = function(source, parser) {
  if (!parser) {
    parser = new XMLParser(new TreeBuilder());
  }
  parser.feed(source);
  this._root = parser.close();
  return this._root;
};

ElementTree.prototype.iter = function(tag, callback) {
  this._root.iter(tag, callback);
};

ElementTree.prototype.find = function(path) {
  return this._root.find(path);
};

ElementTree.prototype.findtext = function(path, defvalue) {
  return this._root.findtext(path, defvalue);
};

ElementTree.prototype.findall = function(path) {
  return this._root.findall(path);
};

/**
 * Unlike ElementTree, we don't write to a file, we return you a string.
 */
ElementTree.prototype.write = function(options) {
  var sb = [];
  options = merge({
    encoding: 'utf-8',
    xml_declaration: null,
    default_namespace: null,
    method: 'xml'}, options);

  if (options.xml_declaration !== false) {
    sb.push("<?xml version='1.0' encoding='"+options.encoding +"'?>\n");
  }

  if (options.method === "text") {
    _serialize_text(sb, self._root, encoding);
  }
  else {
    var qnames, namespaces;
    var x = _namespaces(this._root, options.encoding, options.default_namespace);
    qnames = x[0];
    namespaces = x[1];

    if (options.method === "xml") {
      _serialize_xml(function(data) {
        sb.push(data);
      }, this._root, options.encoding, qnames, namespaces);
    }
    else {
      /* TODO: html */
      throw new Error("unknown serialization method "+ options.method);
    }
  }

  return sb.join("");
};

var _namespace_map = {
    /* "well-known" namespace prefixes */
    "http://www.w3.org/XML/1998/namespace": "xml",
    "http://www.w3.org/1999/xhtml": "html",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf",
    "http://schemas.xmlsoap.org/wsdl/": "wsdl",
    /* xml schema */
    "http://www.w3.org/2001/XMLSchema": "xs",
    "http://www.w3.org/2001/XMLSchema-instance": "xsi",
    /* dublic core */
    "http://purl.org/dc/elements/1.1/": "dc",
};

/* TODO: benchmark single regex */
// TODO replace without regex only replaces single instance
function _escape_attrib(text, encoding) {
  /* TODO: handle encoding */
  if (text.indexOf("&") !== -1) {
    text = text.replace("&", "&");
  }
  if (text.indexOf("<") !== -1) {
    text = text.replace("<", "<");
  }
  if (text.indexOf(">") !== -1) {
    text = text.replace(">", ">");
  }
  if (text.indexOf("\"") !== -1) {
    text = text.replace("\"", """);
  }
  if (text.indexOf("\n") !== -1) {
    text = text.replace("\n", "
");
  }

  return text;
}

function _escape_cdata(text, encoding) {
  /* TODO: handle encoding */
  if (text.indexOf("&") !== -1) {
    text = text.replace("&", "&");
  }
  if (text.indexOf("<") !== -1) {
    text = text.replace("<", "<");
  }
  if (text.indexOf(">") !== -1) {
    text = text.replace(">", ">");
  }

  return text;
}

function _namespaces(elem, encoding, default_namespace) {
  var qnames = {};
  var namespaces = {};

  if (default_namespace) {
    namespaces[default_namespace] = "";
  }

  function add_qname(qname) {
    /* TODO: qname support */
    if (qname[0] === "{") {
      var tmp = qname.substring(1).split("}", 2);
      var uri = tmp[0];
      var tag = tmp[1];
      var prefix = namespaces[uri];
      if (prefix === undefined) {
        prefix = _namespace_map[uri];
        if (prefix === undefined) {
          prefix = "ns" + namespaces.length;
        }
        if (prefix !== "xml") {
          namespaces[uri] = prefix;
        }
      }

      if (prefix) {
        qnames[qname] = sprintf("%s:%s", prefix, tag);
      }
      else {
        qnames[qname] = tag;
      }
    }
    else {
      /* TOOD: default namespaces (?) */
      qnames[qname] = qname;
    }
  }

  elem.iter(null, function(e) {
    var i;
    var tag = e.tag;
    var text = e.text;
    var items = e.items();

    if (tag instanceof QName && qnames[tag.text] === undefined) {
      add_qname(tag.text);
    }
    else if (typeof(tag) === "string") {
      add_qname(tag);
    }
    else if (tag !== null && tag !== Comment && tag !== ProcessingInstruction) {
      throw new Error('Invalid tag type for serialization: '+ tag);
    }

    if (text instanceof QName && qnames[text.text] === undefined) {
      add_qname(text.text);
    }

    items.forEach(function(item) {
      var key = item[0],
          value = item[1];
      if (key instanceof QName) {
        key = key.text;
      }

      if (qnames[key] === undefined) {
        add_qname(key);
      }

      if (value instanceof QName && qnames[value.text] === undefined) {
        add_qname(value.text);
      }
    });
  });
  return [qnames, namespaces];
}

function _serialize_xml(write, elem, encoding, qnames, namespaces) {
  var tag = elem.tag;
  var text = elem.text;
  var items;
  var i;

  if (tag === Comment) {
    write(sprintf("<!--%s-->", _escape_cdata(text, encoding)));
  }
  else if (tag === ProcessingInstruction) {
    write(sprintf("<?%s?>", _escape_cdata(text, encoding)));
  }
  else {
    tag = qnames[tag];
    if (tag === undefined) {
      if (text) {
        write(_escape_cdata(text, encoding));
      }
      elem.iter(function(e) {
        _serialize_xml(write, e, encoding, qnames, null);
      });
    }
    else {
      write("<" + tag);
      items = elem.items();
      items.sort();
      items.forEach(function(item) {
        var k = item[0],
            v = item[1];

          if (k instanceof QName) {
            k = k.text;
          }

          if (v instanceof QName) {
            v = qnames[v.text];
          }
          else {
            v = _escape_attrib(v, encoding);
          }
          write(sprintf(" %s=\"%s\"", qnames[k], v));
      });

      if (namespaces) {
        /* TODO: write xmlns */
      }

      if (text || elem.len()) {
        write(">");
        if (text) {
          write(_escape_cdata(text, encoding));
        }
        elem._children.forEach(function(e) {
          _serialize_xml(write, e, encoding, qnames, null);
        });

        write("</" + tag + ">");
      }
      else {
        write(" />");
      }
    }
  }
}

exports.PI = ProcessingInstruction;
exports.Comment = Comment;
exports.ProcessingInstruction = ProcessingInstruction;
exports.SubElement = SubElement;
exports.QName = QName;
exports.ElementTree = ElementTree;
exports.ElementPath = require('./elementpath');
exports.Element = function(tag, attrib) {
  return new Element(tag, attrib);
};

exports.XML = function(data) {
  var et = new ElementTree();
  return et.parse(data);
};
<|endoftext|>


<commit_before>/**
 *  Copyright 2011 Rackspace
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

var sprintf = require('./sprintf').sprintf;

var utils = require('./utils');
var ElementPath = require('./elementpath');
var TreeBuilder = require('./treebuilder').TreeBuilder;
var get_parser = require('./parser').get_parser;
var constants = require('./constants');

var element_ids = 0;

function Element(tag, attrib)
{
  this._id = element_ids++;
  this.tag = tag;
  this.attrib = {};
  this.text = null;
  this.tail = null;
  this._children = [];

  if (attrib) {
    this.attrib = utils.merge(this.attrib, attrib);
  }
}

Element.prototype.toString = function()
{
  return sprintf("<Element %s at %s>", this.tag, this._id);
};

Element.prototype.makeelement = function(tag, attrib)
{
  return new Element(tag, attrib);
};

Element.prototype.len = function()
{
  return this._children.length;
};

Element.prototype.getItem = function(index)
{
  return this._children[index];
};

Element.prototype.setItem = function(index, element)
{
  this._children[index] = element;
};

Element.prototype.delItem = function(index)
{
  this._children.splice(index, 1);
};

Element.prototype.getSlice = function(start, stop)
{
  return this._children.slice(start, stop);
};

Element.prototype.setSlice = function(start, stop, elements)
{
  var i;
  var k = 0;
  for (i = start; i < stop; i++, k++) {
    this._children[i] = elements[k];
  }
};

Element.prototype.delSlice = function(start, stop)
{
  this._children.splice(start, stop - start);
};

Element.prototype.append = function(element)
{
  this._children.push(element);
};

Element.prototype.extend = function(elements)
{
  this._children.concat(elements);
};

Element.prototype.insert = function(index, element)
{
  this._children[index] = element;
};

Element.prototype.remove = function(index, element)
{
  this._children = this._children.filter(function(e) {
    /* TODO: is this the right way to do this? */
    if (e._id === element._id) {
      return false;
    }
    return true;
  });
};

Element.prototype.getchildren = function() {
  return this._children;
};

Element.prototype.find = function(path)
{
  return ElementPath.find(this, path);
};

Element.prototype.findtext = function(path, defvalue)
{
  return ElementPath.findtext(this, path, defvalue);
};

Element.prototype.findall = function(path, defvalue)
{
  return ElementPath.findall(this, path, defvalue);
};

Element.prototype.clear = function()
{
  this.attrib = {};
  this._children = [];
  this.text = null;
  this.tail = null;
};

Element.prototype.get = function(key, defvalue)
{
  if (this.attrib[key] !== undefined) {
    return this.attrib[key];
  }
  else {
    return defvalue;
  }
};

Element.prototype.set = function(key, value)
{
  this.attrib[key] = value;
};

Element.prototype.keys = function()
{
  return Object.keys(this.attrib);
};

Element.prototype.items = function()
{
  return utils.items(this.attrib);
};

/*
 * In python this uses a generator, but in v8 we don't have em,
 * so we use a callback instead.
 **/
Element.prototype.iter = function(tag, callback)
{
  var self = this;
  var i, child;

  if (tag === "*") {
    tag = null;
  }

  if (tag === null || this.tag === tag) {
    callback(self);
  }

  for (i = 0; i < this._children.length; i++) {
    child = this._children[i];
    child.iter(tag, function(e) {
      callback(e);
    });
  }
};

Element.prototype.itertext = function(callback)
{
  this.iter(null, function(e) {
    if (e.text) {
      callback(e.text);
    }

    if (e.tail) {
      callback(e.tail);
    }
  });
};

function SubElement(parent, tag, attrib) {
  var element = parent.makeelement(tag, attrib);
  parent.append(element);
  return element;
}

function Comment(text) {
  var element = new Element(Comment);
  if (text) {
    element.text = text;
  }
  return element;
}

function ProcessingInstruction(target, text)
{
  var element = new Element(ProcessingInstruction);
  element.text = target;
  if (text) {
    element.text = element.text + " " + text;
  }
  return element;
}

function QName(text_or_uri, tag)
{
  if (tag) {
    text_or_uri = sprintf("{%s}%s", text_or_uri, tag);
  }
  this.text = text_or_uri;
}

QName.prototype.toString = function() {
  return this.text;
};

function ElementTree(element)
{
  this._root = element;
}

ElementTree.prototype.getroot = function() {
  return this._root;
};

ElementTree.prototype._setroot = function(element) {
  this._root = element;
};

ElementTree.prototype.parse = function(source, parser) {
  if (!parser) {
    parser = get_parser(constants.DEFAULT_PARSER);
    parser = new parser.XMLParser(new TreeBuilder());
  }

  parser.feed(source);
  this._root = parser.close();
  return this._root;
};

ElementTree.prototype.iter = function(tag, callback) {
  this._root.iter(tag, callback);
};

ElementTree.prototype.find = function(path) {
  return this._root.find(path);
};

ElementTree.prototype.findtext = function(path, defvalue) {
  return this._root.findtext(path, defvalue);
};

ElementTree.prototype.findall = function(path) {
  return this._root.findall(path);
};

/**
 * Unlike ElementTree, we don't write to a file, we return you a string.
 */
ElementTree.prototype.write = function(options) {
  var sb = [];
  options = utils.merge({
    encoding: 'utf-8',
    xml_declaration: null,
    default_namespace: null,
    method: 'xml'}, options);

  if (options.xml_declaration !== false) {
    sb.push("<?xml version='1.0' encoding='"+options.encoding +"'?>\n");
  }

  if (options.method === "text") {
    _serialize_text(sb, self._root, encoding);
  }
  else {
    var qnames, namespaces;
    var x = _namespaces(this._root, options.encoding, options.default_namespace);
    qnames = x[0];
    namespaces = x[1];

    if (options.method === "xml") {
      _serialize_xml(function(data) {
        sb.push(data);
      }, this._root, options.encoding, qnames, namespaces);
    }
    else {
      /* TODO: html */
      throw new Error("unknown serialization method "+ options.method);
    }
  }

  return sb.join("");
};

var _namespace_map = {
    /* "well-known" namespace prefixes */
    "http://www.w3.org/XML/1998/namespace": "xml",
    "http://www.w3.org/1999/xhtml": "html",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf",
    "http://schemas.xmlsoap.org/wsdl/": "wsdl",
    /* xml schema */
    "http://www.w3.org/2001/XMLSchema": "xs",
    "http://www.w3.org/2001/XMLSchema-instance": "xsi",
    /* dublic core */
    "http://purl.org/dc/elements/1.1/": "dc",
};

function register_namespace(prefix, uri) {
  if (/ns\d+$/.test(prefix)) {
    throw new Error('Prefix format reserved for internal use');
  }

  if (_namespace_map.hasOwnProperty(uri) && _namespace_map[uri] === prefix) {
    delete _namespace_map[uri];
  }

  _namespace_map[uri] = prefix;
}

/* TODO: benchmark single regex */
// TODO replace without regex only replaces single instance
function _escape_attrib(text, encoding) {
  if (text) {
    text = text.toString();
  }

  if (text.indexOf("&") !== -1) {
    text = text.replace("&", "&");
  }
  if (text.indexOf("<") !== -1) {
    text = text.replace("<", "<");
  }
  if (text.indexOf(">") !== -1) {
    text = text.replace(">", ">");
  }
  if (text.indexOf("\"") !== -1) {
    text = text.replace("\"", """);
  }
  if (text.indexOf("\n") !== -1) {
    text = text.replace("\n", "
");
  }

  return text;
}

function _escape_cdata(text, encoding) {
  if (text) {
    text = text.toString();
  }

  if (text.indexOf("&") !== -1) {
    text = text.replace("&", "&");
  }
  if (text.indexOf("<") !== -1) {
    text = text.replace("<", "<");
  }
  if (text.indexOf(">") !== -1) {
    text = text.replace(">", ">");
  }

  return text;
}

function _namespaces(elem, encoding, default_namespace) {
  var qnames = {};
  var namespaces = {};

  if (default_namespace) {
    namespaces[default_namespace] = "";
  }

  function encode(text) {
    return text;
  }

  function add_qname(qname) {
    if (qname[0] === "{") {
      var tmp = qname.substring(1).split("}", 2);
      var uri = tmp[0];
      var tag = tmp[1];
      var prefix = namespaces[uri];

      if (prefix === undefined) {
        prefix = _namespace_map[uri];
        if (prefix === undefined) {
          prefix = "ns" + Object.keys(namespaces).length;
        }
        if (prefix !== "xml") {
          namespaces[uri] = prefix;
        }
      }

      if (prefix) {
        qnames[qname] = sprintf("%s:%s", prefix, tag);
      }
      else {
        qnames[qname] = tag;
      }
    }
    else {
      if (default_namespace) {
        throw new Error('cannot use non-qualified names with default_namespace option');
      }

      qnames[qname] = qname;
    }
  }

  elem.iter(null, function(e) {
    var i;
    var tag = e.tag;
    var text = e.text;
    var items = e.items();

    if (tag instanceof QName && qnames[tag.text] === undefined) {
      add_qname(tag.text);
    }
    else if (typeof(tag) === "string") {
      add_qname(tag);
    }
    else if (tag !== null && tag !== Comment && tag !== ProcessingInstruction) {
      throw new Error('Invalid tag type for serialization: '+ tag);
    }

    if (text instanceof QName && qnames[text.text] === undefined) {
      add_qname(text.text);
    }

    items.forEach(function(item) {
      var key = item[0],
          value = item[1];
      if (key instanceof QName) {
        key = key.text;
      }

      if (qnames[key] === undefined) {
        add_qname(key);
      }

      if (value instanceof QName && qnames[value.text] === undefined) {
        add_qname(value.text);
      }
    });
  });
  return [qnames, namespaces];
}

function _serialize_xml(write, elem, encoding, qnames, namespaces) {
  var tag = elem.tag;
  var text = elem.text;
  var items;
  var i;

  if (tag === Comment) {
    write(sprintf("<!--%s-->", _escape_cdata(text, encoding)));
  }
  else if (tag === ProcessingInstruction) {
    write(sprintf("<?%s?>", _escape_cdata(text, encoding)));
  }
  else {
    tag = qnames[tag];
    if (tag === undefined) {
      if (text) {
        write(_escape_cdata(text, encoding));
      }
      elem.iter(function(e) {
        _serialize_xml(write, e, encoding, qnames, null);
      });
    }
    else {
      write("<" + tag);
      items = elem.items();

      if (items || namespaces) {
        items.sort(); // lexical order

        items.forEach(function(item) {
          var k = item[0],
              v = item[1];

            if (k instanceof QName) {
              k = k.text;
            }

            if (v instanceof QName) {
              v = qnames[v.text];
            }
            else {
              v = _escape_attrib(v, encoding);
            }
            write(sprintf(" %s=\"%s\"", qnames[k], v));
        });

        if (namespaces) {
          items = utils.items(namespaces);
          items.sort(function(a, b) { return a[1] < b[1]; });

          items.forEach(function(item) {
            var k = item[1],
                v = item[0];

            if (k) {
              k = ':' + k;
            }

            write(sprintf(" xmlns%s=\"%s\"", k, _escape_attrib(v, encoding)));
          });
        }
      }

      if (text || elem.len()) {
        write(">");
        if (text) {
          write(_escape_cdata(text, encoding));
        }
        elem._children.forEach(function(e) {
          _serialize_xml(write, e, encoding, qnames, null);
        });

        write("</" + tag + ">");
      }
      else {
        write(" />");
      }
    }
  }
}

function parse(source, parser) {
  var tree = new ElementTree();
  tree.parse(source, parser);
  return tree;
}

function tostring(element, options) {
  return new ElementTree(element).write(options);
}

exports.PI = ProcessingInstruction;
exports.Comment = Comment;
exports.ProcessingInstruction = ProcessingInstruction;
exports.SubElement = SubElement;
exports.QName = QName;
exports.ElementTree = ElementTree;
exports.ElementPath = ElementPath;
exports.Element = function(tag, attrib) {
  return new Element(tag, attrib);
};

exports.XML = function(data) {
  var et = new ElementTree();
  return et.parse(data);
};

exports.parse = parse;
exports.register_namespace = register_namespace;
exports.tostring = tostring;
<commit_msg>Fix cr lf characters<commit_after>/**
 *  Copyright 2011 Rackspace
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

var sprintf = require('./sprintf').sprintf;

var utils = require('./utils');
var ElementPath = require('./elementpath');
var TreeBuilder = require('./treebuilder').TreeBuilder;
var get_parser = require('./parser').get_parser;
var constants = require('./constants');

var element_ids = 0;

function Element(tag, attrib)
{
  this._id = element_ids++;
  this.tag = tag;
  this.attrib = {};
  this.text = null;
  this.tail = null;
  this._children = [];

  if (attrib) {
    this.attrib = utils.merge(this.attrib, attrib);
  }
}

Element.prototype.toString = function()
{
  return sprintf("<Element %s at %s>", this.tag, this._id);
};

Element.prototype.makeelement = function(tag, attrib)
{
  return new Element(tag, attrib);
};

Element.prototype.len = function()
{
  return this._children.length;
};

Element.prototype.getItem = function(index)
{
  return this._children[index];
};

Element.prototype.setItem = function(index, element)
{
  this._children[index] = element;
};

Element.prototype.delItem = function(index)
{
  this._children.splice(index, 1);
};

Element.prototype.getSlice = function(start, stop)
{
  return this._children.slice(start, stop);
};

Element.prototype.setSlice = function(start, stop, elements)
{
  var i;
  var k = 0;
  for (i = start; i < stop; i++, k++) {
    this._children[i] = elements[k];
  }
};

Element.prototype.delSlice = function(start, stop)
{
  this._children.splice(start, stop - start);
};

Element.prototype.append = function(element)
{
  this._children.push(element);
};

Element.prototype.extend = function(elements)
{
  this._children.concat(elements);
};

Element.prototype.insert = function(index, element)
{
  this._children[index] = element;
};

Element.prototype.remove = function(index, element)
{
  this._children = this._children.filter(function(e) {
    /* TODO: is this the right way to do this? */
    if (e._id === element._id) {
      return false;
    }
    return true;
  });
};

Element.prototype.getchildren = function() {
  return this._children;
};

Element.prototype.find = function(path)
{
  return ElementPath.find(this, path);
};

Element.prototype.findtext = function(path, defvalue)
{
  return ElementPath.findtext(this, path, defvalue);
};

Element.prototype.findall = function(path, defvalue)
{
  return ElementPath.findall(this, path, defvalue);
};

Element.prototype.clear = function()
{
  this.attrib = {};
  this._children = [];
  this.text = null;
  this.tail = null;
};

Element.prototype.get = function(key, defvalue)
{
  if (this.attrib[key] !== undefined) {
    return this.attrib[key];
  }
  else {
    return defvalue;
  }
};

Element.prototype.set = function(key, value)
{
  this.attrib[key] = value;
};

Element.prototype.keys = function()
{
  return Object.keys(this.attrib);
};

Element.prototype.items = function()
{
  return utils.items(this.attrib);
};

/*
 * In python this uses a generator, but in v8 we don't have em,
 * so we use a callback instead.
 **/
Element.prototype.iter = function(tag, callback)
{
  var self = this;
  var i, child;

  if (tag === "*") {
    tag = null;
  }

  if (tag === null || this.tag === tag) {
    callback(self);
  }

  for (i = 0; i < this._children.length; i++) {
    child = this._children[i];
    child.iter(tag, function(e) {
      callback(e);
    });
  }
};

Element.prototype.itertext = function(callback)
{
  this.iter(null, function(e) {
    if (e.text) {
      callback(e.text);
    }

    if (e.tail) {
      callback(e.tail);
    }
  });
};

function SubElement(parent, tag, attrib) {
  var element = parent.makeelement(tag, attrib);
  parent.append(element);
  return element;
}

function Comment(text) {
  var element = new Element(Comment);
  if (text) {
    element.text = text;
  }
  return element;
}

function ProcessingInstruction(target, text)
{
  var element = new Element(ProcessingInstruction);
  element.text = target;
  if (text) {
    element.text = element.text + " " + text;
  }
  return element;
}

function QName(text_or_uri, tag)
{
  if (tag) {
    text_or_uri = sprintf("{%s}%s", text_or_uri, tag);
  }
  this.text = text_or_uri;
}

QName.prototype.toString = function() {
  return this.text;
};

function ElementTree(element)
{
  this._root = element;
}

ElementTree.prototype.getroot = function() {
  return this._root;
};

ElementTree.prototype._setroot = function(element) {
  this._root = element;
};

ElementTree.prototype.parse = function(source, parser) {
  if (!parser) {
    parser = get_parser(constants.DEFAULT_PARSER);
    parser = new parser.XMLParser(new TreeBuilder());
  }

  parser.feed(source);
  this._root = parser.close();
  return this._root;
};

ElementTree.prototype.iter = function(tag, callback) {
  this._root.iter(tag, callback);
};

ElementTree.prototype.find = function(path) {
  return this._root.find(path);
};

ElementTree.prototype.findtext = function(path, defvalue) {
  return this._root.findtext(path, defvalue);
};

ElementTree.prototype.findall = function(path) {
  return this._root.findall(path);
};

/**
 * Unlike ElementTree, we don't write to a file, we return you a string.
 */
ElementTree.prototype.write = function(options) {
  var sb = [];
  options = utils.merge({
    encoding: 'utf-8',
    xml_declaration: null,
    default_namespace: null,
    method: 'xml'}, options);

  if (options.xml_declaration !== false) {
    sb.push("<?xml version='1.0' encoding='"+options.encoding +"'?>\n");
  }

  if (options.method === "text") {
    _serialize_text(sb, self._root, encoding);
  }
  else {
    var qnames, namespaces;
    var x = _namespaces(this._root, options.encoding, options.default_namespace);
    qnames = x[0];
    namespaces = x[1];

    if (options.method === "xml") {
      _serialize_xml(function(data) {
        sb.push(data);
      }, this._root, options.encoding, qnames, namespaces);
    }
    else {
      /* TODO: html */
      throw new Error("unknown serialization method "+ options.method);
    }
  }

  return sb.join("");
};

var _namespace_map = {
    /* "well-known" namespace prefixes */
    "http://www.w3.org/XML/1998/namespace": "xml",
    "http://www.w3.org/1999/xhtml": "html",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf",
    "http://schemas.xmlsoap.org/wsdl/": "wsdl",
    /* xml schema */
    "http://www.w3.org/2001/XMLSchema": "xs",
    "http://www.w3.org/2001/XMLSchema-instance": "xsi",
    /* dublic core */
    "http://purl.org/dc/elements/1.1/": "dc",
};

function register_namespace(prefix, uri) {
  if (/ns\d+$/.test(prefix)) {
    throw new Error('Prefix format reserved for internal use');
  }

  if (_namespace_map.hasOwnProperty(uri) && _namespace_map[uri] === prefix) {
    delete _namespace_map[uri];
  }

  _namespace_map[uri] = prefix;
}

/* TODO: benchmark single regex */
// TODO replace without regex only replaces single instance
function _escape_attrib(text, encoding) {
  if (text) {
    text = text.toString();
  }

  if (text.indexOf("&") !== -1) {
    text = text.replace("&", "&");
  }
  if (text.indexOf("<") !== -1) {
    text = text.replace("<", "<");
  }
  if (text.indexOf(">") !== -1) {
    text = text.replace(">", ">");
  }
  if (text.indexOf("\"") !== -1) {
    text = text.replace("\"", """);
  }
  if (text.indexOf("\n") !== -1) {
    text = text.replace("\n", "
");
  }
  if (text.indexOf("\r") !== -1) {
    text = text.replace("\r", "
");
  }

  return text;
}

function _escape_cdata(text, encoding) {
  if (text) {
    text = text.toString();
  }

  if (text.indexOf("&") !== -1) {
    text = text.replace("&", "&");
  }
  if (text.indexOf("<") !== -1) {
    text = text.replace("<", "<");
  }
  if (text.indexOf(">") !== -1) {
    text = text.replace(">", ">");
  }

  return text;
}

function _namespaces(elem, encoding, default_namespace) {
  var qnames = {};
  var namespaces = {};

  if (default_namespace) {
    namespaces[default_namespace] = "";
  }

  function encode(text) {
    return text;
  }

  function add_qname(qname) {
    if (qname[0] === "{") {
      var tmp = qname.substring(1).split("}", 2);
      var uri = tmp[0];
      var tag = tmp[1];
      var prefix = namespaces[uri];

      if (prefix === undefined) {
        prefix = _namespace_map[uri];
        if (prefix === undefined) {
          prefix = "ns" + Object.keys(namespaces).length;
        }
        if (prefix !== "xml") {
          namespaces[uri] = prefix;
        }
      }

      if (prefix) {
        qnames[qname] = sprintf("%s:%s", prefix, tag);
      }
      else {
        qnames[qname] = tag;
      }
    }
    else {
      if (default_namespace) {
        throw new Error('cannot use non-qualified names with default_namespace option');
      }

      qnames[qname] = qname;
    }
  }

  elem.iter(null, function(e) {
    var i;
    var tag = e.tag;
    var text = e.text;
    var items = e.items();

    if (tag instanceof QName && qnames[tag.text] === undefined) {
      add_qname(tag.text);
    }
    else if (typeof(tag) === "string") {
      add_qname(tag);
    }
    else if (tag !== null && tag !== Comment && tag !== ProcessingInstruction) {
      throw new Error('Invalid tag type for serialization: '+ tag);
    }

    if (text instanceof QName && qnames[text.text] === undefined) {
      add_qname(text.text);
    }

    items.forEach(function(item) {
      var key = item[0],
          value = item[1];
      if (key instanceof QName) {
        key = key.text;
      }

      if (qnames[key] === undefined) {
        add_qname(key);
      }

      if (value instanceof QName && qnames[value.text] === undefined) {
        add_qname(value.text);
      }
    });
  });
  return [qnames, namespaces];
}

function _serialize_xml(write, elem, encoding, qnames, namespaces) {
  var tag = elem.tag;
  var text = elem.text;
  var items;
  var i;

  if (tag === Comment) {
    write(sprintf("<!--%s-->", _escape_cdata(text, encoding)));
  }
  else if (tag === ProcessingInstruction) {
    write(sprintf("<?%s?>", _escape_cdata(text, encoding)));
  }
  else {
    tag = qnames[tag];
    if (tag === undefined) {
      if (text) {
        write(_escape_cdata(text, encoding));
      }
      elem.iter(function(e) {
        _serialize_xml(write, e, encoding, qnames, null);
      });
    }
    else {
      write("<" + tag);
      items = elem.items();

      if (items || namespaces) {
        items.sort(); // lexical order

        items.forEach(function(item) {
          var k = item[0],
              v = item[1];

            if (k instanceof QName) {
              k = k.text;
            }

            if (v instanceof QName) {
              v = qnames[v.text];
            }
            else {
              v = _escape_attrib(v, encoding);
            }
            write(sprintf(" %s=\"%s\"", qnames[k], v));
        });

        if (namespaces) {
          items = utils.items(namespaces);
          items.sort(function(a, b) { return a[1] < b[1]; });

          items.forEach(function(item) {
            var k = item[1],
                v = item[0];

            if (k) {
              k = ':' + k;
            }

            write(sprintf(" xmlns%s=\"%s\"", k, _escape_attrib(v, encoding)));
          });
        }
      }

      if (text || elem.len()) {
        write(">");
        if (text) {
          write(_escape_cdata(text, encoding));
        }
        elem._children.forEach(function(e) {
          _serialize_xml(write, e, encoding, qnames, null);
        });

        write("</" + tag + ">");
      }
      else {
        write(" />");
      }
    }
  }
}

function parse(source, parser) {
  var tree = new ElementTree();
  tree.parse(source, parser);
  return tree;
}

function tostring(element, options) {
  return new ElementTree(element).write(options);
}

exports.PI = ProcessingInstruction;
exports.Comment = Comment;
exports.ProcessingInstruction = ProcessingInstruction;
exports.SubElement = SubElement;
exports.QName = QName;
exports.ElementTree = ElementTree;
exports.ElementPath = ElementPath;
exports.Element = function(tag, attrib) {
  return new Element(tag, attrib);
};

exports.XML = function(data) {
  var et = new ElementTree();
  return et.parse(data);
};

exports.parse = parse;
exports.register_namespace = register_namespace;
exports.tostring = tostring;
<|endoftext|>


<commit_before>// ============================================================================
// File:    endpointMap.js
// Author:  Jarle Elshaug
// Purpose: Maps enpoint attributes to SCIM/CustomSCIM attributes
//          Used by method scimgateway.endpointMapper
//
// Plugin examples:
//   let parsedAttr = scimgateway.endpointMapper('outbound', attributes, scimgateway.endpointMap.microsoftGraphUser)
//   let parsedAttr = scimgateway.endpointMapper('inbound', attributes, scimgateway.endpointMap.microsoftGraphUser)
// ============================================================================

//
// User mapping - used by plugin-azure-aad.js
//
module.exports.microsoftGraphUser = {
  'id': {
    'mapTo': 'id', // mandatory
    'type': 'string'
  },
  'userPrincipalName': {
    'mapTo': 'userName', // mandatory - changed
    'type': 'string'
  },
  'accountEnabled': {
    'mapTo': 'active', // changed
    'type': 'boolean'
  },
  'assignedLicenses': {
    'mapTo': 'assignedLicenses',
    'type': 'array'
  },
  'assignedPlans': {
    'mapTo': 'assignedPlans',
    'type': 'array'
  },
  'businessPhones': { // singleton value
    'mapTo': 'businessPhones',
    'type': 'array' // changed
  },
  'city': {
    'mapTo': 'city',
    'type': 'string'
  },
  'companyName': {
    'mapTo': 'companyName',
    'type': 'string'
  },
  'country': {
    'mapTo': 'country',
    'type': 'string'
  },
  'department': {
    'mapTo': 'department',
    'type': 'string'
  },
  'displayName': {
    'mapTo': 'displayName',
    'type': 'string'
  },
  'givenName': {
    'mapTo': 'name.givenName', // changed
    'type': 'string'
  },
  'imAddresses': {
    'mapTo': 'imAddresses',
    'type': 'array'
  },
  'jobTitle': {
    'mapTo': 'jobTitle',
    'type': 'string'
  },
  'mail': {
    'mapTo': 'mail',
    'type': 'string'
  },
  'mailNickname': {
    'mapTo': 'mailNickname',
    'type': 'string'
  },
  'manager': {
    'mapTo': 'manager.managerId', // changed
    'type': 'string'
  },
  'mobilePhone': {
    'mapTo': 'mobilePhone',
    'type': 'string'
  },
  'onPremisesImmutableId': {
    'mapTo': 'onPremisesImmutableId',
    'type': 'string'
  },
  'onPremisesLastSyncDateTime': {
    'mapTo': 'onPremisesLastSyncDateTime',
    'type': 'string'
  },
  'onPremisesSecurityIdentifier': {
    'mapTo': 'onPremisesSecurityIdentifier',
    'type': 'string'
  },
  'onPremisesSyncEnabled': {
    'mapTo': 'onPremisesSyncEnabled',
    'type': 'boolean'
  },
  'passwordPolicies': {
    'mapTo': 'passwordPolicies',
    'type': 'string'
  },
  'passwordProfile.forceChangePasswordNextSignIn': { // changed
    'mapTo': 'passwordProfile.forceChangePasswordNextSignIn',
    'type': 'string'
  },
  'passwordProfile.password': { // changed
    'mapTo': 'passwordProfile.password',
    'type': 'string'
  },
  'officeLocation': {
    'mapTo': 'officeLocation',
    'type': 'string'
  },
  'postalCode': {
    'mapTo': 'postalCode',
    'type': 'string'
  },
  'preferredLanguage': {
    'mapTo': 'preferredLanguage',
    'type': 'string'
  },
  'provisionedPlans': {
    'mapTo': 'provisionedPlans',
    'type': 'array'
  },
  'proxyAddresses': {
    'mapTo': 'proxyAddresses.value', // changed
    'type': 'array',
    'items': {
      'type': 'string'
    }
  },
  'servicePlan': { // added
    'mapTo': 'servicePlan.value',
    'type': 'array'
  },
  'state': {
    'mapTo': 'state',
    'type': 'string'
  },
  'streetAddress': {
    'mapTo': 'streetAddress',
    'type': 'string'
  },
  'surname': {
    'mapTo': 'name.familyName', // changed
    'type': 'string'
  },
  'usageLocation': {
    'mapTo': 'usageLocation',
    'type': 'string'
  },
  'userType': {
    'mapTo': 'userType',
    'type': 'string'
  },
  'mailboxSettings': {
    'mapTo': 'mailboxSettings',
    'type': 'string'
  },
  'aboutMe': {
    'mapTo': 'aboutMe',
    'type': 'string'
  },
  'birthday': {
    'mapTo': 'birthday',
    'type': 'string'
  },
  'hireDate': {
    'mapTo': 'hireDate',
    'type': 'string'
  },
  'interests': {
    'mapTo': 'interests',
    'type': 'array'
  },
  'mySite': {
    'mapTo': 'mySite',
    'type': 'string'
  },
  'pastProjects': {
    'mapTo': 'pastProjects',
    'type': 'array'
  },
  'preferredName': {
    'mapTo': 'preferredName',
    'type': 'string'
  },
  'responsibilities': {
    'mapTo': 'responsibilities',
    'type': 'array'
  },
  'schools': {
    'mapTo': 'schools',
    'type': 'array'
  },
  'skills': {
    'mapTo': 'skills',
    'type': 'array'
  }
}

//
// Group mapping - used by plugin-azure-aad.js
//
module.exports.microsoftGraphGroup = {
  'id': { // mandatory
    'mapTo': 'id',
    'type': 'string'
  },
  'displayName': { // mandatory
    'mapTo': 'displayName',
    'type': 'string'
  },
  'members.value': { // new - no mapping changes - plugin could exclude on outbound but needs to be included on inbound
    'mapTo': 'members.value',
    'type': 'string'
  },
  'classification': {
    'mapTo': 'classification',
    'type': 'string'
  },
  'description': {
    'mapTo': 'description',
    'type': 'string'
  },
  'groupTypes': {
    'mapTo': 'groupTypes',
    'type': 'array',
    'items': {
      'type': 'string'
    }
  },
  'mail': {
    'mapTo': 'mail',
    'type': 'string'
  },
  'mailEnabled': {
    'mapTo': 'mailEnabled',
    'type': 'boolean'
  },
  'mailNickname': {
    'mapTo': 'mailNickname',
    'type': 'string'
  },
  'onPremisesLastSyncDateTime': {
    'mapTo': 'onPremisesLastSyncDateTime',
    'type': 'string',
    'format': 'date-time'
  },
  'onPremisesSecurityIdentifier': {
    'mapTo': 'onPremisesSecurityIdentifier',
    'type': 'string'
  },
  'onPremisesSyncEnabled': {
    'mapTo': 'onPremisesSyncEnabled',
    'type': 'boolean'
  },
  'proxyAddresses': {
    'mapTo': 'proxyAddresses.value', // changed
    'type': 'array',
    'items': {
      'type': 'string'
    }
  },
  'securityEnabled': {
    'mapTo': 'securityEnabled',
    'type': 'boolean'
  },
  'visibility': {
    'mapTo': 'visibility',
    'type': 'string'
  },
  'allowExternalSenders': {
    'mapTo': 'allowExternalSenders',
    'type': 'boolean'
  },
  'autoSubscribeNewMembers': {
    'mapTo': 'autoSubscribeNewMembers',
    'type': 'boolean'
  },
  'isSubscribedByMail': {
    'mapTo': 'isSubscribedByMail',
    'type': 'boolean'
  },
  'unseenCount': {
    'mapTo': 'unseenCount',
    'type': 'integer'
  }
}

module.exports.microsoftGraphLicenseDetails = { // also includes servicePlanInfo
  /*
  'id': {
    'mapTo': 'id',
    'type': 'string'
  }, */
  'servicePlans': {
    'mapTo': 'servicePlans',
    'type': 'array'
  },
  'skuId': {
    'mapTo': 'skuId',
    'type': 'string'
  },
  'skuPartNumber': {
    'mapTo': 'skuPartNumber',
    'type': 'string'
  },
  'servicePlanId': {
    'mapTo': 'id', // changed
    'type': 'string'
  },
  'servicePlanName': { // (skuPartNumber::servicePlanName)
    'mapTo': 'servicePlanName',
    'type': 'string'
  },
  'provisioningStatus': {
    'mapTo': 'provisioningStatus',
    'type': 'string'
  },
  'appliesTo': {
    'mapTo': 'appliesTo',
    'type': 'string'
  }
}
<commit_msg>typeInbound<commit_after>// ============================================================================
// File:    endpointMap.js
// Author:  Jarle Elshaug
// Purpose: Maps enpoint attributes to SCIM/CustomSCIM attributes
//          Used by method scimgateway.endpointMapper
//
// Plugin examples:
//   let parsedAttr = scimgateway.endpointMapper('outbound', attributes, scimgateway.endpointMap.microsoftGraphUser)
//   let parsedAttr = scimgateway.endpointMapper('inbound', attributes, scimgateway.endpointMap.microsoftGraphUser)
// ============================================================================

//
// User mapping - used by plugin-azure-aad.js
//
module.exports.microsoftGraphUser = {
  'id': {
    'mapTo': 'id', // mandatory
    'type': 'string'
  },
  'userPrincipalName': {
    'mapTo': 'userName', // mandatory - changed
    'type': 'string'
  },
  'accountEnabled': {
    'mapTo': 'active', // changed
    'type': 'boolean'
  },
  'assignedLicenses': {
    'mapTo': 'assignedLicenses',
    'type': 'array'
  },
  'assignedPlans': {
    'mapTo': 'assignedPlans',
    'type': 'array'
  },
  'businessPhones': { // singleton value
    'mapTo': 'businessPhones',
    'type': 'array', // changed
    'typeInbound': 'string' // changed
  },
  'city': {
    'mapTo': 'city',
    'type': 'string'
  },
  'companyName': {
    'mapTo': 'companyName',
    'type': 'string'
  },
  'country': {
    'mapTo': 'country',
    'type': 'string'
  },
  'department': {
    'mapTo': 'department',
    'type': 'string'
  },
  'displayName': {
    'mapTo': 'displayName',
    'type': 'string'
  },
  'givenName': {
    'mapTo': 'name.givenName', // changed
    'type': 'string'
  },
  'imAddresses': {
    'mapTo': 'imAddresses',
    'type': 'array'
  },
  'jobTitle': {
    'mapTo': 'jobTitle',
    'type': 'string'
  },
  'mail': {
    'mapTo': 'mail',
    'type': 'string'
  },
  'mailNickname': {
    'mapTo': 'mailNickname',
    'type': 'string'
  },
  'manager': {
    'mapTo': 'manager.managerId', // changed
    'type': 'string'
  },
  'mobilePhone': {
    'mapTo': 'mobilePhone',
    'type': 'string'
  },
  'onPremisesImmutableId': {
    'mapTo': 'onPremisesImmutableId',
    'type': 'string'
  },
  'onPremisesLastSyncDateTime': {
    'mapTo': 'onPremisesLastSyncDateTime',
    'type': 'string'
  },
  'onPremisesSecurityIdentifier': {
    'mapTo': 'onPremisesSecurityIdentifier',
    'type': 'string'
  },
  'onPremisesSyncEnabled': {
    'mapTo': 'onPremisesSyncEnabled',
    'type': 'boolean'
  },
  'passwordPolicies': {
    'mapTo': 'passwordPolicies',
    'type': 'string'
  },
  'passwordProfile.forceChangePasswordNextSignIn': { // changed
    'mapTo': 'passwordProfile.forceChangePasswordNextSignIn',
    'type': 'string'
  },
  'passwordProfile.password': { // changed
    'mapTo': 'passwordProfile.password',
    'type': 'string'
  },
  'officeLocation': {
    'mapTo': 'officeLocation',
    'type': 'string'
  },
  'postalCode': {
    'mapTo': 'postalCode',
    'type': 'string'
  },
  'preferredLanguage': {
    'mapTo': 'preferredLanguage',
    'type': 'string'
  },
  'provisionedPlans': {
    'mapTo': 'provisionedPlans',
    'type': 'array'
  },
  'proxyAddresses': {
    'mapTo': 'proxyAddresses.value', // changed
    'type': 'array',
    'items': {
      'type': 'string'
    }
  },
  'servicePlan': { // added
    'mapTo': 'servicePlan.value',
    'type': 'array'
  },
  'state': {
    'mapTo': 'state',
    'type': 'string'
  },
  'streetAddress': {
    'mapTo': 'streetAddress',
    'type': 'string'
  },
  'surname': {
    'mapTo': 'name.familyName', // changed
    'type': 'string'
  },
  'usageLocation': {
    'mapTo': 'usageLocation',
    'type': 'string'
  },
  'userType': {
    'mapTo': 'userType',
    'type': 'string'
  },
  'mailboxSettings': {
    'mapTo': 'mailboxSettings',
    'type': 'string'
  },
  'aboutMe': {
    'mapTo': 'aboutMe',
    'type': 'string'
  },
  'birthday': {
    'mapTo': 'birthday',
    'type': 'string'
  },
  'hireDate': {
    'mapTo': 'hireDate',
    'type': 'string'
  },
  'interests': {
    'mapTo': 'interests',
    'type': 'array'
  },
  'mySite': {
    'mapTo': 'mySite',
    'type': 'string'
  },
  'pastProjects': {
    'mapTo': 'pastProjects',
    'type': 'array'
  },
  'preferredName': {
    'mapTo': 'preferredName',
    'type': 'string'
  },
  'responsibilities': {
    'mapTo': 'responsibilities',
    'type': 'array'
  },
  'schools': {
    'mapTo': 'schools',
    'type': 'array'
  },
  'skills': {
    'mapTo': 'skills',
    'type': 'array'
  }
}

//
// Group mapping - used by plugin-azure-aad.js
//
module.exports.microsoftGraphGroup = {
  'id': { // mandatory
    'mapTo': 'id',
    'type': 'string'
  },
  'displayName': { // mandatory
    'mapTo': 'displayName',
    'type': 'string'
  },
  'members.value': { // new - no mapping changes - plugin could exclude on outbound but needs to be included on inbound
    'mapTo': 'members.value',
    'type': 'string'
  },
  'classification': {
    'mapTo': 'classification',
    'type': 'string'
  },
  'description': {
    'mapTo': 'description',
    'type': 'string'
  },
  'groupTypes': {
    'mapTo': 'groupTypes',
    'type': 'array',
    'items': {
      'type': 'string'
    }
  },
  'mail': {
    'mapTo': 'mail',
    'type': 'string'
  },
  'mailEnabled': {
    'mapTo': 'mailEnabled',
    'type': 'boolean'
  },
  'mailNickname': {
    'mapTo': 'mailNickname',
    'type': 'string'
  },
  'onPremisesLastSyncDateTime': {
    'mapTo': 'onPremisesLastSyncDateTime',
    'type': 'string',
    'format': 'date-time'
  },
  'onPremisesSecurityIdentifier': {
    'mapTo': 'onPremisesSecurityIdentifier',
    'type': 'string'
  },
  'onPremisesSyncEnabled': {
    'mapTo': 'onPremisesSyncEnabled',
    'type': 'boolean'
  },
  'proxyAddresses': {
    'mapTo': 'proxyAddresses.value', // changed
    'type': 'array',
    'items': {
      'type': 'string'
    }
  },
  'securityEnabled': {
    'mapTo': 'securityEnabled',
    'type': 'boolean'
  },
  'visibility': {
    'mapTo': 'visibility',
    'type': 'string'
  },
  'allowExternalSenders': {
    'mapTo': 'allowExternalSenders',
    'type': 'boolean'
  },
  'autoSubscribeNewMembers': {
    'mapTo': 'autoSubscribeNewMembers',
    'type': 'boolean'
  },
  'isSubscribedByMail': {
    'mapTo': 'isSubscribedByMail',
    'type': 'boolean'
  },
  'unseenCount': {
    'mapTo': 'unseenCount',
    'type': 'integer'
  }
}

module.exports.microsoftGraphLicenseDetails = { // also includes servicePlanInfo
  /*
  'id': {
    'mapTo': 'id',
    'type': 'string'
  }, */
  'servicePlans': {
    'mapTo': 'servicePlans',
    'type': 'array'
  },
  'skuId': {
    'mapTo': 'skuId',
    'type': 'string'
  },
  'skuPartNumber': {
    'mapTo': 'skuPartNumber',
    'type': 'string'
  },
  'servicePlanId': {
    'mapTo': 'id', // changed
    'type': 'string'
  },
  'servicePlanName': { // (skuPartNumber::servicePlanName)
    'mapTo': 'servicePlanName',
    'type': 'string'
  },
  'provisioningStatus': {
    'mapTo': 'provisioningStatus',
    'type': 'string'
  },
  'appliesTo': {
    'mapTo': 'appliesTo',
    'type': 'string'
  }
}
<|endoftext|>


<commit_before>mini.Module(
	"engine/loop"
)
.requires(

)
.defines(function() {
	var _Loop = function(callback, desiredTime) {
		var that = this;
		// -----------------------------------------------------------------------------

		// use requestAnimationFrame if available or setInterval otherwise

		// Find vendor prefix, if any
		var vendors = ['ms', 'moz', 'webkit', 'o'];
		for( var i = 0; i < vendors.length && !window.requestAnimationFrame; i++ ) {
			window.requestAnimationFrame = window[vendors[i]+'RequestAnimationFrame'];
		}

		// Use requestAnimationFrame if available
		if( window.requestAnimationFrame ) {
			var next = 1,
				anims = {},
				lastFrame = {};

			that.start = function( callback, element ) {
				var current = next++;
				anims[current] = true;
				lastFrame[current] = new Date().getTime();

				var animate = function() {
					if( !anims[current] ) { return; } // deleted?
					window.requestAnimationFrame( animate, element );

					// setup time since last call
					var tm = new Date().getTime();
					var dt = (tm - lastFrame[current]) / 1000;
					lastFrame[current] = tm;

					callback(dt);
				};
				window.requestAnimationFrame( animate, element );
				return current;
			};

			that.stop = function( id ) {
				delete anims[id];
			};
		}

		// [set/clear]Interval fallback
		else {
			that.start = function( callback, element ) {
				return window.setInterval( callback, 1000/60 );
			};
			that.stop = function( id ) {
				window.clearInterval( id );
			};
		}
	};

	var Loop = function() {
		this.loop = new _Loop();
		this.callbacks = [];
		this.removals = {};
	};

	Loop.prototype.start = function(fn) {
		var fn = Bloob.Utils.bind(this.update, this);
		this.__loopId__ = this.loop.start(fn);
		return this;
	};

	Loop.prototype.stop = function() {
		this.loop.stop(this.__loopId__);
		return this;
	};

	Loop.prototype.update = function(timePassed) {
		timePassed = 1/60;
		for(var index in this.callbacks)
			this.callbacks[index](timePassed);
	};

	Loop.prototype.add = function(context, func, keyForRemoval) {
		var bindFunction = Bloob.Utils.bind(func, context);

		if(typeof keyForRemoval !== "undefined") {
			this.removals[keyForRemoval] = bindFunction;
		}
		this.callbacks.push(bindFunction);
		return this;
	};

	Loop.prototype.remove = function(keyForRemoval) {
		var functionToRemove = this.removals[keyForRemoval];
		var index = this.callbacks.indexOf(functionToRemove);
		if (index !== - 1) {
			this.callbacks.splice( index, 1 );
		}
		return this;
	};

	Loop.prototype.clear = function() {
		this.callbacks.length = 0;
		return this;
	};

	Bloob.Loop = Loop;

	return Loop;
});
<commit_msg>removed Bloob in Loop<commit_after>mini.Module(
	"engine/loop"
)
.requires(
	"basic/utils"
)
.defines(function(Utils) {
	var _Loop = function(callback, desiredTime) {
		var that = this;
		// -----------------------------------------------------------------------------

		// use requestAnimationFrame if available or setInterval otherwise

		// Find vendor prefix, if any
		var vendors = ['ms', 'moz', 'webkit', 'o'];
		for( var i = 0; i < vendors.length && !window.requestAnimationFrame; i++ ) {
			window.requestAnimationFrame = window[vendors[i]+'RequestAnimationFrame'];
		}

		// Use requestAnimationFrame if available
		if( window.requestAnimationFrame ) {
			var next = 1,
				anims = {},
				lastFrame = {};

			that.start = function( callback, element ) {
				var current = next++;
				anims[current] = true;
				lastFrame[current] = new Date().getTime();

				var animate = function() {
					if( !anims[current] ) { return; } // deleted?
					window.requestAnimationFrame( animate, element );

					// setup time since last call
					var tm = new Date().getTime();
					var dt = (tm - lastFrame[current]) / 1000;
					lastFrame[current] = tm;

					callback(dt);
				};
				window.requestAnimationFrame( animate, element );
				return current;
			};

			that.stop = function( id ) {
				delete anims[id];
			};
		}

		// [set/clear]Interval fallback
		else {
			that.start = function( callback, element ) {
				return window.setInterval( callback, 1000/60 );
			};
			that.stop = function( id ) {
				window.clearInterval( id );
			};
		}
	};

	var Loop = function() {
		this.loop = new _Loop();
		this.callbacks = [];
		this.removals = {};
	};

	Loop.prototype.start = function(fn) {
		var fn = Utils.bind(this.update, this);
		this.__loopId__ = this.loop.start(fn);
		return this;
	};

	Loop.prototype.stop = function() {
		this.loop.stop(this.__loopId__);
		return this;
	};

	Loop.prototype.update = function(timePassed) {
		timePassed = 1/60;
		for(var index in this.callbacks)
			this.callbacks[index](timePassed);
	};

	Loop.prototype.add = function(context, func, keyForRemoval) {
		var bindFunction = Utils.bind(func, context);

		if(typeof keyForRemoval !== "undefined") {
			this.removals[keyForRemoval] = bindFunction;
		}
		this.callbacks.push(bindFunction);
		return this;
	};

	Loop.prototype.remove = function(keyForRemoval) {
		var functionToRemove = this.removals[keyForRemoval];
		var index = this.callbacks.indexOf(functionToRemove);
		if (index !== - 1) {
			this.callbacks.splice( index, 1 );
		}
		return this;
	};

	Loop.prototype.clear = function() {
		this.callbacks.length = 0;
		return this;
	};

	return Loop;
});
<|endoftext|>


<commit_before>$(document).ready(function() {
  $('button[name="schedule-button"]').each(function(i, obj) {
    var button = $(this);
    var term = button.data('term-id');
    var course = button.data('course-crn');
    var params = {
      'username': api_username,
      'api_key': api_key,
      'term__value': term,
      'course_crn': course,
      'format': 'json',
    }
    $.get('/api/v1/schedule/', params, function(data) {
      state = data.meta.total_count;
      update_schedule_button(button, state);
    });
  });
  $('button[name="follow-button"]').each(function(i, obj) {
    var button = $(this);
    var term = button.attr('data-term-id');
    var course = button.attr('data-course-crn');
    var params = {
      'username': api_username,
      'api_key': api_key,
      'term__value': term,
      'course_crn': course,
      'format': 'json',
    }
    $.get('/api/v1/follow/', params, function(data) {
      state = data.meta.total_count;
      update_follow_button(button, state);
    });
  });

  $('button[name="schedule-button"]').click(function() {
    var button = $(this);
    var term = button.attr('data-term-id');
    var course = button.attr('data-course-crn');
    var state = button.attr('data-schedule-state');
    if (state == '0') {
      var headers = {
        'Authorization': 'ApiKey ' + api_username + ':' + api_key,
      }
      var data = {
        'term': '/api/v1/term/' + term + '/',
        'course_crn': course,
      }
      $.ajax({
        url: '/api/v1/schedule/',
        type: 'POST',
        data: JSON.stringify(data),
        headers: headers,
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        processData: false,
        success: function (data, status, jqXHR) {
          update_schedule_button(button, 1);
        },
        error: function (jqXHR, status, error) {
          update_schedule_button(button, 1);
        }
      });
    } else {
      var params = {
        'username': api_username,
        'api_key': api_key,
        'term__value': term,
        'course_crn': course,
        'format': 'json',
      }
      $.get('/api/v1/schedule/', params, function(data) {
        uri = data.objects[0].resource_uri;
        headers = {
          'Authorization': 'ApiKey ' + api_username + ':' + api_key,
        }
        $.ajax({
          url: uri,
          type: 'DELETE',
          headers: headers,
          success: function(data) {
            update_schedule_button(button, 0);
          }
        });
      });
    }
  });

  $('button[name="follow-button"]').click(function() {
    var button = $(this);
    var term = button.attr('data-term-id');
    var course = button.attr('data-course-crn');
    var state = button.attr('data-follow-state');
    if (state == '0') {
      var headers = {
        'Authorization': 'ApiKey ' + api_username + ':' + api_key,
      }
      var data = {
        'term': '/api/v1/term/' + term + '/',
        'course_crn': course,
      }
      $.ajax({
        url: '/api/v1/follow/',
        type: 'POST',
        data: JSON.stringify(data),
        headers: headers,
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        processData: false,
        success: function (data, status, jqXHR) {
          update_follow_button(button, 1);
        },
        error: function (jqXHR, status, error) {
          update_follow_button(button, 1);
        }
      });
    } else {
      var params = {
        'username': api_username,
        'api_key': api_key,
        'term__value': term,
        'course_crn': course,
        'format': 'json',
      }
      $.get('/api/v1/follow/', params, function(data) {
        uri = data.objects[0].resource_uri;
        headers = {
          'Authorization': 'ApiKey ' + api_username + ':' + api_key,
        }
        $.ajax({
          url: uri,
          type: 'DELETE',
          headers: headers,
          success: function(data) {
            update_follow_button(button, 0);
          }
        });
      });
    }
  });
});

function update_schedule_button(button, state) {
  button.attr('data-schedule-state', state)
  button.removeClass("btn-default");
  if (state == 0) {
    button.html(' Add to Schedule');
    button.removeClass("btn-danger");
    button.addClass("btn-success");
  } else {
    button.html(' Remove from Schedule');
    button.removeClass("btn-success");
    button.addClass("btn-danger");
  }
}

function update_follow_button(button, state) {
  button.attr('data-follow-state', state)
  button.removeClass("btn-default");
  if (state == 0) {
    button.html(' Get Updates');
    button.removeClass("btn-danger");
    button.addClass("btn-success");
  } else {
    button.html(' Stop Updates');
    button.removeClass("btn-success");
    button.addClass("btn-danger");
  }
}
<commit_msg>Use api parameters directly in button posts<commit_after>$(document).ready(function() {
  var API_PARAM = '?username=' + api_username + '&api_key=' + api_key;
  $('button[name="schedule-button"]').each(function(i, obj) {
    var button = $(this);
    var term = button.data('term-id');
    var course = button.data('course-crn');
    var params = {
      'username': api_username,
      'api_key': api_key,
      'term__value': term,
      'course_crn': course,
      'format': 'json',
    }
    $.get('/api/v1/schedule/', params, function(data) {
      state = data.meta.total_count;
      update_schedule_button(button, state);
    });
  });
  $('button[name="follow-button"]').each(function(i, obj) {
    var button = $(this);
    var term = button.attr('data-term-id');
    var course = button.attr('data-course-crn');
    var params = {
      'username': api_username,
      'api_key': api_key,
      'term__value': term,
      'course_crn': course,
      'format': 'json',
    }
    $.get('/api/v1/follow/', params, function(data) {
      state = data.meta.total_count;
      update_follow_button(button, state);
    });
  });

  $('button[name="schedule-button"]').click(function() {
    var button = $(this);
    var term = button.attr('data-term-id');
    var course = button.attr('data-course-crn');
    var state = button.attr('data-schedule-state');
    if (state == '0') {
      var headers = {
        'Authorization': 'ApiKey ' + api_username + ':' + api_key,
      }
      var data = {
        'term': '/api/v1/term/' + term + '/',
        'course_crn': course,
      }
      $.ajax({
        url: '/api/v1/schedule/' + API_PARAM,
        type: 'POST',
        data: JSON.stringify(data),
        headers: headers,
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        processData: false,
        success: function (data, status, jqXHR) {
          update_schedule_button(button, 1);
        },
        error: function (jqXHR, status, error) {
          update_schedule_button(button, 1);
        }
      });
    } else {
      var params = {
        'username': api_username,
        'api_key': api_key,
        'term__value': term,
        'course_crn': course,
        'format': 'json',
      }
      $.get('/api/v1/schedule/', params, function(data) {
        uri = data.objects[0].resource_uri + API_PARAM;
        headers = {
          'Authorization': 'ApiKey ' + api_username + ':' + api_key,
        }
        $.ajax({
          url: uri,
          type: 'DELETE',
          headers: headers,
          success: function(data) {
            update_schedule_button(button, 0);
          }
        });
      });
    }
  });

  $('button[name="follow-button"]').click(function() {
    var button = $(this);
    var term = button.attr('data-term-id');
    var course = button.attr('data-course-crn');
    var state = button.attr('data-follow-state');
    if (state == '0') {
      var headers = {
        'Authorization': 'ApiKey ' + api_username + ':' + api_key,
      }
      var data = {
        'term': '/api/v1/term/' + term + '/',
        'course_crn': course,
      }
      $.ajax({
        url: '/api/v1/follow/' + API_PARAM,
        type: 'POST',
        data: JSON.stringify(data),
        headers: headers,
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        processData: false,
        success: function (data, status, jqXHR) {
          update_follow_button(button, 1);
        },
        error: function (jqXHR, status, error) {
          update_follow_button(button, 1);
        }
      });
    } else {
      var params = {
        'username': api_username,
        'api_key': api_key,
        'term__value': term,
        'course_crn': course,
        'format': 'json',
      }
      $.get('/api/v1/follow/', params, function(data) {
        uri = data.objects[0].resource_uri + API_PARAM;
        headers = {
          'Authorization': 'ApiKey ' + api_username + ':' + api_key,
        }
        $.ajax({
          url: uri,
          type: 'DELETE',
          headers: headers,
          success: function(data) {
            update_follow_button(button, 0);
          }
        });
      });
    }
  });
});

function update_schedule_button(button, state) {
  button.attr('data-schedule-state', state)
  button.removeClass("btn-default");
  if (state == 0) {
    button.html(' Add to Schedule');
    button.removeClass("btn-danger");
    button.addClass("btn-success");
  } else {
    button.html(' Remove from Schedule');
    button.removeClass("btn-success");
    button.addClass("btn-danger");
  }
}

function update_follow_button(button, state) {
  button.attr('data-follow-state', state)
  button.removeClass("btn-default");
  if (state == 0) {
    button.html(' Get Updates');
    button.removeClass("btn-danger");
    button.addClass("btn-success");
  } else {
    button.html(' Stop Updates');
    button.removeClass("btn-success");
    button.addClass("btn-danger");
  }
}
<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');

class AftershipError {
	/**
	 * Static Method for getting REQUEST error
	 *
	 * @param error_enum {object}
	 * @param error_data {object} - The object trigger the error
	 * @param retry_count {number}
	 * @constructor
	 */
	static getRequestError(error, error_data, retry_count) {
		error.data = error_data;
		error.type = error.code;

		if (retry_count) {
			error.retry_count = retry_count;
		}

		return error;
	}

	/**
	 * Static Method for getting SDK error
	 *
	 * @param error_enum {object}
	 * @param error_data {object} - The object trigger the error
	 * @param retry_count {number}
	 * @constructor
	 */
	static getSdkError(error_enum, error_data) {
		let error = new Error();
		error.type = error_enum.type;
		error.message = error_enum.message;
		error.data = error_data;
		Error.captureStackTrace(error);

		return error;
	}

	/**
	 * Static Method for getting API error
	 *
	 * @param response_body {object}
	 * @param retry_count {number}
	 * @constructor
	 */
	static getApiError(response_body, retry_count) {
		let error = new Error();
		error.type = _.get(response_body, 'meta.type');
		error.message = _.get(response_body, 'meta.message');
		error.code = _.get(response_body, 'meta.code');
		error.data = _.get(response_body, 'data');;
		error.response_body = JSON.stringify(response_body);

		if (retry_count) {
			error.retry_count = retry_count;
		}

		return error;
	}
}

module.exports = AftershipError;
<commit_msg>linting fix<commit_after>'use strict';

const _ = require('lodash');

class AftershipError {
	/**
	 * Static Method for getting REQUEST error
	 *
	 * @param error_enum {object}
	 * @param error_data {object} - The object trigger the error
	 * @param retry_count {number}
	 * @constructor
	 */
	static getRequestError(error, error_data, retry_count) {
		error.data = error_data;
		error.type = error.code;

		if (retry_count) {
			error.retry_count = retry_count;
		}

		return error;
	}

	/**
	 * Static Method for getting SDK error
	 *
	 * @param error_enum {object}
	 * @param error_data {object} - The object trigger the error
	 * @param retry_count {number}
	 * @constructor
	 */
	static getSdkError(error_enum, error_data) {
		let error = new Error();
		error.type = error_enum.type;
		error.message = error_enum.message;
		error.data = error_data;
		Error.captureStackTrace(error);

		return error;
	}

	/**
	 * Static Method for getting API error
	 *
	 * @param response_body {object}
	 * @param retry_count {number}
	 * @constructor
	 */
	static getApiError(response_body, retry_count) {
		let error = new Error();
		error.type = _.get(response_body, 'meta.type');
		error.message = _.get(response_body, 'meta.message');
		error.code = _.get(response_body, 'meta.code');
		error.data = _.get(response_body, 'data');
		error.response_body = JSON.stringify(response_body);

		if (retry_count) {
			error.retry_count = retry_count;
		}

		return error;
	}
}

module.exports = AftershipError;
<|endoftext|>


<commit_before>// Copyright (c) Visual Data Solutions, Inc. All rights reserved. This source code is distributed under the terms of the MIT license. See LICENSE file in the project root for complete license information.

var CoreObject = require('./coreobject.js');

module.exports = {

    mixinName: 'EventSource',

    init: function(host) {
        "use strict";

        this.host = host;
        this.eventHandlers = {};
    },

    on: function(eventName, eventHandler, handlerContext) {
        "use strict";

        if (!this.eventHandlers[eventName]) {
            this.eventHandlers[eventName] = [];
        }

        var handlerSet = this.eventHandlers[eventName];
        var exists = false;
        handlerSet.forEach(function (item) {
            if (item.context === handlerContext &&
                item.handler === eventHandler) {

                exists = true;
            }
        }, this);

        if (!exists) {
            handlerSet.push({
                context: handlerContext,
                handler: eventHandler
            });
        }
    },

    removeAllWithContext: function(context) {

        for(var p in this.eventHandlers) {
            if (this.eventHandlers.hasOwnProperty(p)) {

                var handlerSet = this.eventHandlers[p];

                //remove any with context match
                var i = handlerSet.length;
                while (i--) {
                    var handler = handlerSet[i];
                    if (handler.context == context) {
                        this.splice(i, 1);
                    }
                }
            }
        }
    },

    emit: function(eventName, data) {
        "use strict";

        var handlerSet = this.eventHandlers[eventName];
        if (!handlerSet) {
            return;
        }

        handlerSet.forEach( function(handler) {
            handler.handler.call(handler.context, data);
        });
    }
};

<commit_msg>publish<commit_after>// Copyright (c) Visual Data Solutions, Inc. All rights reserved. This source code is distributed under the terms of the MIT license. See LICENSE file in the project root for complete license information.

var CoreObject = require('./coreobject.js');

module.exports = {

    mixinName: 'EventSource',

    init: function(host) {
        "use strict";

        this.host = host;
        this.eventHandlers = {};
    },

    on: function(eventName, eventHandler, handlerContext) {
        "use strict";

        if (!this.eventHandlers[eventName]) {
            this.eventHandlers[eventName] = [];
        }

        var handlerSet = this.eventHandlers[eventName];
        var exists = false;
        handlerSet.forEach(function (item) {
            if (item.context === handlerContext &&
                item.handler === eventHandler) {

                exists = true;
            }
        }, this);

        if (!exists) {
            handlerSet.push({
                context: handlerContext,
                handler: eventHandler
            });
        }
    },

    removeAllWithContext: function(context) {

        for(var p in this.eventHandlers) {
            if (this.eventHandlers.hasOwnProperty(p)) {

                var handlerSet = this.eventHandlers[p];

                //remove any with context match
                var i = handlerSet.length;
                while (i--) {
                    var handler = handlerSet[i];
                    if (handler.context == context) {
                        handlerSet.splice(i, 1);
                    }
                }
            }
        }
    },

    emit: function(eventName, data) {
        "use strict";

        var handlerSet = this.eventHandlers[eventName];
        if (!handlerSet) {
            return;
        }

        handlerSet.forEach( function(handler) {
            handler.handler.call(handler.context, data);
        });
    }
};

<|endoftext|>


<commit_before>define([
    'src/util/api',
    'src/util/ui',
    './libs'
    ], function (API, UI, libs) {
    var OCLE = libs.OCLE;
    var CCE = libs.CCE;

    class MF {
        constructor(sample) {
            this.sample = sample;

            // if no mf we calculate from molfile
            console.log(API.getData('mf')+'');
            if (! (API.getData('mf')+'')) {
                console.log("No MF ?!",API.getData('mf'))
                this.fromMolfile();
            }
        }

        fromMolfile() {
            var chemcalc=this._chemcalcFromMolfile();
            if (chemcalc && this.previousEM !== chemcalc.em) {
                this.previousEM = chemcalc.em;

                var general=API.getData('general');
                general.mf=chemcalc.mf;
                general.em=chemcalc.em;
                general.mw=chemcalc.mw;
                general.triggerChange();
            }
            API.createData('mfBGColor','white');
        }

        _chemcalcFromMolfile() {
            var molfile=API.getData('molfile')+'';
            if (molfile) {
                var molecule=OCLE.Molecule.fromMolfile(molfile);
                var mf=molecule.getMolecularFormula().formula;
                try {
                    return CCE.analyseMF(mf);
                } catch (e) {
                    UI.showNotification('Could not calculate molecular formula: '+e);
                }
            }
            return undefined;
        }

        fromMF() {

            var chemcalc=CCE.analyseMF(API.getData('mf')+'');
            console.log('new MF', chemcalc);
            if (chemcalc && this.previousEM !== chemcalc.em) {
                this.previousEM = chemcalc.em;
                var general=API.getData('general');
                general.mw=chemcalc.mw;
                general.em=chemcalc.em;
                general.triggerChange();
            }
        }

        _mfColor() {
            var existingMF=API.getData('mf')+"";
            if (molfile) {
                var molecule=OCLE.Molecule.fromMolfile(molfile);
                var mf=molecule.getMolecularFormula().formula;
                var existingMW=existingMF ? CCE.analyseMF(existingMF).mw : 0;
                var newMW=mf ? CCE.analyseMF(mf).mw : 0;
                if (newMW!=existingMW) {
                    API.createData('mfBGColor','pink');
                } else {
                    API.createData('mfBGColor','white');
                }
            } else {
                API.createData('mfBGColor','white');
            }
        }

        handleAction(action) {
            if (!action) return;
            switch (action.name) {

                default:
                    return false;
            }
            return true;
        }
    }

    return MF;
});<commit_msg>Fix bug<commit_after>define([
    'src/util/api',
    'src/util/ui',
    './libs'
    ], function (API, UI, libs) {
    var OCLE = libs.OCLE;
    var CCE = libs.CCE;

    class MF {
        constructor(sample) {
            this.sample = sample;

            // if no mf we calculate from molfile
            console.log(API.getData('mf')+'');
            if (! (API.getData('mf')+'')) {
                console.log("No MF ?!",API.getData('mf'))
                this.fromMolfile();
            }
        }

        fromMolfile() {
            var chemcalc=this._chemcalcFromMolfile();
            console.log('fromMolfile', chemcalc);
            if (chemcalc && this.previousEM !== chemcalc.em) {
                this.previousEM = chemcalc.em;

                var general=API.getData('general');
                general.mf=chemcalc.mf;
                general.em=chemcalc.em;
                general.mw=chemcalc.mw;
                general.triggerChange();
            }
            API.createData('mfBGColor','white');
        }

        _chemcalcFromMolfile() {
            var molfile=API.getData('molfile')+'';
            if (molfile) {
                var molecule=OCLE.Molecule.fromMolfile(molfile);
                var mf=molecule.getMolecularFormula().formula;
                try {
                    return CCE.analyseMF(mf);
                } catch (e) {
                    UI.showNotification('Could not calculate molecular formula: '+e);
                }
            }
            return undefined;
        }

        fromMF() {

            var chemcalc=CCE.analyseMF(API.getData('mf')+'');
            console.log('new MF', chemcalc);
            if (chemcalc && this.previousEM !== chemcalc.em) {
                this.previousEM = chemcalc.em;
                var general=API.getData('general');
                general.mw=chemcalc.mw;
                general.em=chemcalc.em;
                general.triggerChange();
            }
        }

        _mfColor() {
            var existingMF=API.getData('mf')+"";
            if (molfile) {
                var molecule=OCLE.Molecule.fromMolfile(molfile);
                var mf=molecule.getMolecularFormula().formula;
                var existingMW=existingMF ? CCE.analyseMF(existingMF).mw : 0;
                var newMW=mf ? CCE.analyseMF(mf).mw : 0;
                if (newMW!=existingMW) {
                    API.createData('mfBGColor','pink');
                } else {
                    API.createData('mfBGColor','white');
                }
            } else {
                API.createData('mfBGColor','white');
            }
        }

        handleAction(action) {
            if (!action) return;
            switch (action.name) {

                default:
                    return false;
            }
            return true;
        }
    }

    return MF;
});<|endoftext|>