<commit_before>/*!
    Copyright (C) 2013 Google Inc., authors, and contributors <see AUTHORS file>
    Licensed under http://www.apache.org/licenses/LICENSE-2.0 <see LICENSE file>
    Created By: brad@reciprocitylabs.com
    Maintained By: brad@reciprocitylabs.com
*/

//require can.jquery-all

(function(can) {

can.Model.Cacheable("CMS.Models.Context", {
    root_object : "context"
  , root_collection : "contexts"
  , category : "contexts"
  , findAll : "/api/contexts"
  , findOne : "/api/contexts/{id}"
  , create : "POST /api/contexts"
  , update : "PUT /api/contexts/{id}"
  , destroy : "DELETE /api/contexts/{id}"
  , attributes : {
      context : "CMS.Models.Context.stub"
    , related_object: "CMS.Models.get_stub"
    , user_roles: "CMS.Models.UserRole.stubs"
    }
}, {
});

can.Model.Cacheable("CMS.Models.Program", {
  root_object : "program"
  , root_collection : "programs"
  , category : "programs"
  , findAll : "/api/programs"
  , findOne : "/api/programs/{id}"
  , create : "POST /api/programs"
  , update : "PUT /api/programs/{id}"
  , destroy : "DELETE /api/programs/{id}"
  , mixins : ["contactable", "unique_title"]
  , is_custom_attributable: true
  , attributes : {
      context : "CMS.Models.Context.stub"
    , owners : "CMS.Models.Person.stubs"
    , modified_by : "CMS.Models.Person.stub"
    , object_people : "CMS.Models.ObjectPerson.stubs"
    , people : "CMS.Models.Person.stubs"
    , object_documents : "CMS.Models.ObjectDocument.stubs"
    , documents : "CMS.Models.Document.stubs"
    , related_sources : "CMS.Models.Relationship.stubs"
    , related_destinations : "CMS.Models.Relationship.stubs"
    , objectives : "CMS.Models.Objective.stubs"
    , sections : "CMS.Models.get_stubs"
    , directives : "CMS.Models.Directive.stubs"
    , controls : "CMS.Models.Control.stubs"
    , audits : "CMS.Models.Audit.stubs"
    , custom_attribute_values : "CMS.Models.CustomAttributeValue.stubs"
  }
  , tree_view_options : {
      show_view : GGRC.mustache_path + "/programs/tree.mustache"
    , footer_view : GGRC.mustache_path + "/base_objects/tree_footer.mustache"
    , attr_list : [
      {attr_title: 'Manager', attr_name: 'owner', attr_sort_field: 'authorizations.0.person.name|email'}
    ].concat(can.Model.Cacheable.attr_list.filter(function (d) {
      return d.attr_name != 'owner';
    })).concat([
      {attr_title: 'URL', attr_name: 'url'},
      {attr_title: 'Reference URL', attr_name: 'reference_url'},
      {attr_title: 'Effective Date', attr_name: 'start_date'},
      {attr_title: 'Stop Date', attr_name: 'end_date'}
    ])
    , child_tree_display_list : ['Standard', 'Regulation', 'Policy', 'Contract']
    , add_item_view : GGRC.mustache_path + "/base_objects/tree_add_item.mustache"
    }
  , links_to : {
    "System" : {}
    , "Process" : {}
    , "Product" : {}
    , "Facility" : {}
    , "OrgGroup" : {}
    , "Vendor" : {}
    , "Project" : {}
    , "DataAsset" : {}
    , "AccessGroup" : {}
    , "Product" : {}
    , "Market" : {}
  }
  , init : function() {
    var that = this;
    this.validateNonBlank("title");
    this._super.apply(this, arguments);
  }
}, {
});

can.Model.Cacheable("CMS.Models.Option", {
  root_object : "option"
  , root_collection : "options"
  , cache_by_role: {}
  , for_role: function(role) {
      var self = this;

      if (!this.cache_by_role[role])
        this.cache_by_role[role] =
          this.findAll({ role: role }).then(function(options) {
            self.cache_by_role[role] = options;
            return options;
          });
      return $.when(this.cache_by_role[role]);
    }
}, {});

can.Model.Cacheable("CMS.Models.Objective", {
  root_object : "objective"
  , root_collection : "objectives"
  , category : "objectives"
  , title_singular : "Objective"
  , title_plural : "Objectives"
  , findAll : "GET /api/objectives"
  , findOne : "GET /api/objectives/{id}"
  , create : "POST /api/objectives"
  , update : "PUT /api/objectives/{id}"
  , destroy : "DELETE /api/objectives/{id}"
  , mixins : ["ownable", "contactable", "unique_title"]
  , is_custom_attributable: true
  , attributes : {
      context : "CMS.Models.Context.stub"
    , owners : "CMS.Models.Person.stubs"
    , modified_by : "CMS.Models.Person.stub"
    , sections : "CMS.Models.get_stubs"
    , controls : "CMS.Models.Control.stubs"
    //, people : "CMS.Models.Person.stubs"
    //, documents : "CMS.Models.Document.stubs"
    , object_people : "CMS.Models.ObjectPerson.stubs"
    , object_documents : "CMS.Models.ObjectDocument.stubs"
    , related_sources : "CMS.Models.Relationship.stubs"
    , related_destinations : "CMS.Models.Relationship.stubs"
    , objective_objects : "CMS.Models.ObjectObjective.stubs"
    , custom_attribute_values : "CMS.Models.CustomAttributeValue.stubs"
  }

  , defaults : {
  }

  , tree_view_options : {
      show_view : GGRC.mustache_path + "/objectives/tree.mustache"
    , footer_view : GGRC.mustache_path + "/objectives/tree_footer.mustache"
    , attr_list : can.Model.Cacheable.attr_list.concat([
      {attr_title: 'URL', attr_name: 'url'},
      {attr_title: 'Reference URL', attr_name: 'reference_url'}
    ])
    , child_tree_display_list : ['Control']
    , add_item_view : GGRC.mustache_path + "/objectives/tree_add_item.mustache"
    , create_link : true
    //, draw_children : true
    , start_expanded : false
    , child_options : [{
        model : can.Model.Cacheable
      , mapping : "related_objects" //"related_and_able_objects"
      , footer_view : GGRC.mustache_path + "/base_objects/tree_footer.mustache"
      , add_item_view : GGRC.mustache_path + "/base_objects/tree_add_item.mustache"
      , title_plural : "Business Objects"
      , draw_children : false
    }]
  }

  , init : function() {
    this.validateNonBlank("title");
    this._super.apply(this, arguments);
  }
}, {
});

can.Model.Cacheable("CMS.Models.Help", {
  root_object : "help"
  , root_collection : "helps"
  , findAll : "GET /api/help"
  , findOne : "GET /api/help/{id}"
  , update : "PUT /api/help/{id}"
  , destroy : "DELETE /api/help/{id}"
  , create : "POST /api/help"
}, {});

can.Model.Cacheable("CMS.Models.Event", {
  root_object : "event"
  , root_collection : "events"
  , findAll : "GET /api/events"
  , list_view_options : { find_params: { __include: "revisions" } }
  , attributes : {
      modified_by : "CMS.Models.Person.stub"
    }
}, {});

can.Model.Cacheable("CMS.Models.Role", {
  root_object : "role"
  , root_collection : "roles"
  , findAll : "GET /api/roles"
  , findOne : "GET /api/roles/{id}"
  , update : "PUT /api/roles/{id}"
  , destroy : "DELETE /api/roles/{id}"
  , create : "POST /api/roles"
  , scopes : [
        "Private Program",
        "Workflow",
        "System"
    ]
  , defaults : {
      permissions: {
          read: []
        , update: []
        , create: []
        , "delete": []
      }
    }
}, {

  allowed : function(operation, object_or_class) {
    var cls = typeof object_or_class === "function" ? object_or_class : object_or_class.constructor;
    return !!~can.inArray(cls.model_singular, this.permissions[operation]);
  }

  , not_system_role : function() {
    return this.attr('scope') !== "System";
  }

  , permission_summary : function() {
    if (this.name == "ProgramOwner") return "Owner";
    if (this.name == "ProgramEditor") return "Can Edit";
    if (this.name == "ProgramReader") return "View Only";
    return this.name;
  }

});

can.Model.Cacheable("CMS.Models.MultitypeSearch", {}, {});

can.Model.Cacheable("CMS.Models.BackgroundTask", {
  root_object : "background_task"
  , root_collection : "background_tasks"
  , findAll : "GET /api/background_tasks"
  , findOne : "GET /api/background_tasks/{id}"
  , update : "PUT /api/background_tasks/{id}"
  , destroy : "DELETE /api/background_tasks/{id}"
  , create : "POST /api/background_tasks"
  , scopes : []
  , defaults : {}
}, {
  poll: function() {
    var dfd = new $.Deferred(),
        self = this,
        wait = 2000,
        interval;

    function _poll(){
      self.refresh().then(function(task) {
        // Poll until we either get a success or a failure:
        if (['Success', 'Failure'].indexOf(task.status) < 0) {
          setTimeout(_poll, wait);
        } else {
          dfd.resolve(task);
        }
      });
    }
    _poll();
    return dfd;
  }
});

CMS.Models.get_instance = function(object_type, object_id, params_or_object) {
  var model, params = {}, instance = null, href;

  if(typeof object_type === "object" || object_type instanceof can.Stub) {
    //assume we only passed in params_or_object
    params_or_object = object_type;
    if (!params_or_object)
      return null;
    if (params_or_object instanceof can.Model)
      object_type = params_or_object.constructor.shortName;
    else if (params_or_object instanceof can.Stub)
      object_type = params_or_object.type;
    else if (!params_or_object.selfLink && params_or_object.type)
      object_type = params_or_object.type;
    else {
      href = params_or_object.selfLink || params_or_object.href;
      object_type = can.map(
          window.cms_singularize(/^\/api\/(\w+)\//.exec(href)[1]).split("_"),
          can.capitalize
        ).join("");
    }
    object_id = params_or_object.id;
  }

  model = CMS.Models[object_type];

  if (!model)
    return null;

  if (!object_id)
    return null;

  if (!!params_or_object) {
    if ($.isFunction(params_or_object.serialize))
      $.extend(params, params_or_object.serialize());
    else
      $.extend(params, params_or_object || {});
  }

  instance = model.findInCacheById(object_id);
  if (!instance) {
    if (params.selfLink) {
      params.id = object_id;
      instance = new model(params);
    } else
      instance = new model({
          id: object_id
        , href: (params_or_object || {}).href
        });
  }
  return instance;
};

CMS.Models.get_stub = function (object) {
  var instance = CMS.Models.get_instance(object);
  if (!instance) {
    return;
  }
  return instance.stub();
};

CMS.Models.get_stubs = function (objects) {
  return new can.Stub.List(can.map(CMS.Models.get_instances(objects), function (o) {
    if (!o || !o.stub) {
      console.warn("`Models.get_stubs` instance has no stubs ", arguments);
      return;
    }
    return o.stub();
  }));
};

CMS.Models.get_instances = function (objects) {
  var i, instances = [];
  if (!objects)
    return [];
  for (i=0; i<objects.length; i++) {
    instances[i] = CMS.Models.get_instance(objects[i]);
  }
  return instances;
};

CMS.Models.get_link_type = function(instance, attr) {
  var type
    , model
    ;

  type = instance[attr + "_type"];
  if (!type) {
    model = instance[attr] && instance[attr].constructor;
    if (model)
      type = model.shortName;
    else if (instance[attr])
      type = instance[attr].type;
  }
  return type;
};

})(this.can);
<commit_msg>Add missing REST attributes to Option<commit_after>/*!
    Copyright (C) 2013 Google Inc., authors, and contributors <see AUTHORS file>
    Licensed under http://www.apache.org/licenses/LICENSE-2.0 <see LICENSE file>
    Created By: brad@reciprocitylabs.com
    Maintained By: brad@reciprocitylabs.com
*/

//require can.jquery-all

(function(can) {

can.Model.Cacheable("CMS.Models.Context", {
    root_object : "context"
  , root_collection : "contexts"
  , category : "contexts"
  , findAll : "/api/contexts"
  , findOne : "/api/contexts/{id}"
  , create : "POST /api/contexts"
  , update : "PUT /api/contexts/{id}"
  , destroy : "DELETE /api/contexts/{id}"
  , attributes : {
      context : "CMS.Models.Context.stub"
    , related_object: "CMS.Models.get_stub"
    , user_roles: "CMS.Models.UserRole.stubs"
    }
}, {
});

can.Model.Cacheable("CMS.Models.Program", {
  root_object : "program"
  , root_collection : "programs"
  , category : "programs"
  , findAll : "/api/programs"
  , findOne : "/api/programs/{id}"
  , create : "POST /api/programs"
  , update : "PUT /api/programs/{id}"
  , destroy : "DELETE /api/programs/{id}"
  , mixins : ["contactable", "unique_title"]
  , is_custom_attributable: true
  , attributes : {
      context : "CMS.Models.Context.stub"
    , owners : "CMS.Models.Person.stubs"
    , modified_by : "CMS.Models.Person.stub"
    , object_people : "CMS.Models.ObjectPerson.stubs"
    , people : "CMS.Models.Person.stubs"
    , object_documents : "CMS.Models.ObjectDocument.stubs"
    , documents : "CMS.Models.Document.stubs"
    , related_sources : "CMS.Models.Relationship.stubs"
    , related_destinations : "CMS.Models.Relationship.stubs"
    , objectives : "CMS.Models.Objective.stubs"
    , sections : "CMS.Models.get_stubs"
    , directives : "CMS.Models.Directive.stubs"
    , controls : "CMS.Models.Control.stubs"
    , audits : "CMS.Models.Audit.stubs"
    , custom_attribute_values : "CMS.Models.CustomAttributeValue.stubs"
  }
  , tree_view_options : {
      show_view : GGRC.mustache_path + "/programs/tree.mustache"
    , footer_view : GGRC.mustache_path + "/base_objects/tree_footer.mustache"
    , attr_list : [
      {attr_title: 'Manager', attr_name: 'owner', attr_sort_field: 'authorizations.0.person.name|email'}
    ].concat(can.Model.Cacheable.attr_list.filter(function (d) {
      return d.attr_name != 'owner';
    })).concat([
      {attr_title: 'URL', attr_name: 'url'},
      {attr_title: 'Reference URL', attr_name: 'reference_url'},
      {attr_title: 'Effective Date', attr_name: 'start_date'},
      {attr_title: 'Stop Date', attr_name: 'end_date'}
    ])
    , child_tree_display_list : ['Standard', 'Regulation', 'Policy', 'Contract']
    , add_item_view : GGRC.mustache_path + "/base_objects/tree_add_item.mustache"
    }
  , links_to : {
    "System" : {}
    , "Process" : {}
    , "Product" : {}
    , "Facility" : {}
    , "OrgGroup" : {}
    , "Vendor" : {}
    , "Project" : {}
    , "DataAsset" : {}
    , "AccessGroup" : {}
    , "Product" : {}
    , "Market" : {}
  }
  , init : function() {
    var that = this;
    this.validateNonBlank("title");
    this._super.apply(this, arguments);
  }
}, {
});

can.Model.Cacheable("CMS.Models.Option", {
  root_object : "option"
  , findAll : "GET /api/options"
  , findOne : "GET /api/options/{id}"
  , create : "POST /api/options"
  , update : "PUT /api/options/{id}"
  , destroy : "DELETE /api/options/{id}"
  , root_collection : "options"
  , cache_by_role: {}
  , for_role: function(role) {
      var self = this;

      if (!this.cache_by_role[role])
        this.cache_by_role[role] =
          this.findAll({ role: role }).then(function(options) {
            self.cache_by_role[role] = options;
            return options;
          });
      return $.when(this.cache_by_role[role]);
    }
}, {});

can.Model.Cacheable("CMS.Models.Objective", {
  root_object : "objective"
  , root_collection : "objectives"
  , category : "objectives"
  , title_singular : "Objective"
  , title_plural : "Objectives"
  , findAll : "GET /api/objectives"
  , findOne : "GET /api/objectives/{id}"
  , create : "POST /api/objectives"
  , update : "PUT /api/objectives/{id}"
  , destroy : "DELETE /api/objectives/{id}"
  , mixins : ["ownable", "contactable", "unique_title"]
  , is_custom_attributable: true
  , attributes : {
      context : "CMS.Models.Context.stub"
    , owners : "CMS.Models.Person.stubs"
    , modified_by : "CMS.Models.Person.stub"
    , sections : "CMS.Models.get_stubs"
    , controls : "CMS.Models.Control.stubs"
    //, people : "CMS.Models.Person.stubs"
    //, documents : "CMS.Models.Document.stubs"
    , object_people : "CMS.Models.ObjectPerson.stubs"
    , object_documents : "CMS.Models.ObjectDocument.stubs"
    , related_sources : "CMS.Models.Relationship.stubs"
    , related_destinations : "CMS.Models.Relationship.stubs"
    , objective_objects : "CMS.Models.ObjectObjective.stubs"
    , custom_attribute_values : "CMS.Models.CustomAttributeValue.stubs"
  }

  , defaults : {
  }

  , tree_view_options : {
      show_view : GGRC.mustache_path + "/objectives/tree.mustache"
    , footer_view : GGRC.mustache_path + "/objectives/tree_footer.mustache"
    , attr_list : can.Model.Cacheable.attr_list.concat([
      {attr_title: 'URL', attr_name: 'url'},
      {attr_title: 'Reference URL', attr_name: 'reference_url'}
    ])
    , child_tree_display_list : ['Control']
    , add_item_view : GGRC.mustache_path + "/objectives/tree_add_item.mustache"
    , create_link : true
    //, draw_children : true
    , start_expanded : false
    , child_options : [{
        model : can.Model.Cacheable
      , mapping : "related_objects" //"related_and_able_objects"
      , footer_view : GGRC.mustache_path + "/base_objects/tree_footer.mustache"
      , add_item_view : GGRC.mustache_path + "/base_objects/tree_add_item.mustache"
      , title_plural : "Business Objects"
      , draw_children : false
    }]
  }

  , init : function() {
    this.validateNonBlank("title");
    this._super.apply(this, arguments);
  }
}, {
});

can.Model.Cacheable("CMS.Models.Help", {
  root_object : "help"
  , root_collection : "helps"
  , findAll : "GET /api/help"
  , findOne : "GET /api/help/{id}"
  , update : "PUT /api/help/{id}"
  , destroy : "DELETE /api/help/{id}"
  , create : "POST /api/help"
}, {});

can.Model.Cacheable("CMS.Models.Event", {
  root_object : "event"
  , root_collection : "events"
  , findAll : "GET /api/events"
  , list_view_options : { find_params: { __include: "revisions" } }
  , attributes : {
      modified_by : "CMS.Models.Person.stub"
    }
}, {});

can.Model.Cacheable("CMS.Models.Role", {
  root_object : "role"
  , root_collection : "roles"
  , findAll : "GET /api/roles"
  , findOne : "GET /api/roles/{id}"
  , update : "PUT /api/roles/{id}"
  , destroy : "DELETE /api/roles/{id}"
  , create : "POST /api/roles"
  , scopes : [
        "Private Program",
        "Workflow",
        "System"
    ]
  , defaults : {
      permissions: {
          read: []
        , update: []
        , create: []
        , "delete": []
      }
    }
}, {

  allowed : function(operation, object_or_class) {
    var cls = typeof object_or_class === "function" ? object_or_class : object_or_class.constructor;
    return !!~can.inArray(cls.model_singular, this.permissions[operation]);
  }

  , not_system_role : function() {
    return this.attr('scope') !== "System";
  }

  , permission_summary : function() {
    if (this.name == "ProgramOwner") return "Owner";
    if (this.name == "ProgramEditor") return "Can Edit";
    if (this.name == "ProgramReader") return "View Only";
    return this.name;
  }

});

can.Model.Cacheable("CMS.Models.MultitypeSearch", {}, {});

can.Model.Cacheable("CMS.Models.BackgroundTask", {
  root_object : "background_task"
  , root_collection : "background_tasks"
  , findAll : "GET /api/background_tasks"
  , findOne : "GET /api/background_tasks/{id}"
  , update : "PUT /api/background_tasks/{id}"
  , destroy : "DELETE /api/background_tasks/{id}"
  , create : "POST /api/background_tasks"
  , scopes : []
  , defaults : {}
}, {
  poll: function() {
    var dfd = new $.Deferred(),
        self = this,
        wait = 2000,
        interval;

    function _poll(){
      self.refresh().then(function(task) {
        // Poll until we either get a success or a failure:
        if (['Success', 'Failure'].indexOf(task.status) < 0) {
          setTimeout(_poll, wait);
        } else {
          dfd.resolve(task);
        }
      });
    }
    _poll();
    return dfd;
  }
});

CMS.Models.get_instance = function(object_type, object_id, params_or_object) {
  var model, params = {}, instance = null, href;

  if(typeof object_type === "object" || object_type instanceof can.Stub) {
    //assume we only passed in params_or_object
    params_or_object = object_type;
    if (!params_or_object)
      return null;
    if (params_or_object instanceof can.Model)
      object_type = params_or_object.constructor.shortName;
    else if (params_or_object instanceof can.Stub)
      object_type = params_or_object.type;
    else if (!params_or_object.selfLink && params_or_object.type)
      object_type = params_or_object.type;
    else {
      href = params_or_object.selfLink || params_or_object.href;
      object_type = can.map(
          window.cms_singularize(/^\/api\/(\w+)\//.exec(href)[1]).split("_"),
          can.capitalize
        ).join("");
    }
    object_id = params_or_object.id;
  }

  model = CMS.Models[object_type];

  if (!model)
    return null;

  if (!object_id)
    return null;

  if (!!params_or_object) {
    if ($.isFunction(params_or_object.serialize))
      $.extend(params, params_or_object.serialize());
    else
      $.extend(params, params_or_object || {});
  }

  instance = model.findInCacheById(object_id);
  if (!instance) {
    if (params.selfLink) {
      params.id = object_id;
      instance = new model(params);
    } else
      instance = new model({
          id: object_id
        , href: (params_or_object || {}).href
        });
  }
  return instance;
};

CMS.Models.get_stub = function (object) {
  var instance = CMS.Models.get_instance(object);
  if (!instance) {
    return;
  }
  return instance.stub();
};

CMS.Models.get_stubs = function (objects) {
  return new can.Stub.List(can.map(CMS.Models.get_instances(objects), function (o) {
    if (!o || !o.stub) {
      console.warn("`Models.get_stubs` instance has no stubs ", arguments);
      return;
    }
    return o.stub();
  }));
};

CMS.Models.get_instances = function (objects) {
  var i, instances = [];
  if (!objects)
    return [];
  for (i=0; i<objects.length; i++) {
    instances[i] = CMS.Models.get_instance(objects[i]);
  }
  return instances;
};

CMS.Models.get_link_type = function(instance, attr) {
  var type
    , model
    ;

  type = instance[attr + "_type"];
  if (!type) {
    model = instance[attr] && instance[attr].constructor;
    if (model)
      type = model.shortName;
    else if (instance[attr])
      type = instance[attr].type;
  }
  return type;
};

})(this.can);
<|endoftext|>


<commit_before>var constants = require('./constants.js');
var query = require('./query.js');

var getPseudoContent = function(node, selector) {
	var styles = window.getComputedStyle(node, selector);
	var ret = styles.getPropertyValue('content');
	if (ret === 'none' || ret.substr(0, 4) === '-moz') {
		return '';
	} else {
		return ret;
	}
};

var getContent = function(root) {
	var ret = getPseudoContent(root, ':before');
	var node = root.firstChild;
	while (node) {
		if (node.nodeType === node.TEXT_NODE) {
			ret += node.textContent;
		} else if (node.nodeType === node.ELEMENT_NODE) {
			ret += getName(node, true);
		}
		node = node.nextSibling;
	}
	ret += getPseudoContent(root, ':after');
	return ret;
};

var allowNameFromContent = function(el) {
	var role = query.getRole(el);
	return !role || constants.nameFromContents.indexOf(role) != -1;
};

var isLabelable = function(el) {
	var selector = constants.labelable.join(',');
	return el.matches(selector);
};

// Control.labels is part of the standard, but not supported in most browsers
var getLabelNode = function(node) {
	if (node.id) {
		var selector = 'label[for="' + node.id + '"]';
		var label = document.querySelector(selector);
		if (label) {
			return label;
		}
	}

	var p = node.parentNode;
	while (p) {
		if (p.tagName === 'LABEL') {
			return p;
		}
		p = p.parentNode;
	}
};

// http://www.ssbbartgroup.com/blog/how-the-w3c-text-alternative-computation-works/
// https://www.w3.org/TR/accname-aam-1.1/#h-mapping_additional_nd_te
var getName = function(el, recursive, force) {
	var ret;

	if (!force && query.matches(el, ':hidden')) {
		return '';
	}
	if (query.matches(el, 'presentation')) {
		return getContent(el);
	}
	if (!recursive && el.matches('[aria-labelledby')) {
		var ids = el.getAttribute('aria-labelledby').split(/\s+/);
		var strings = ids.map(function(id) {
			var label = document.getElementById(id);
			return getName(label, true, true);
		});
		ret = strings.join(' ');
	}
	if (!ret && el.matches('[aria-label]')) {
		ret = el.getAttribute('aria-label');
	}
	if (!ret && isLabelable(el)) {
		var label = getLabelNode(el);
		if (label) {
			ret = getName(label, noRecurse);
		}
	}
	if (!ret) {
		ret = el.getAttribute('placeholder');
	}
	// figcaption
	if (!ret && !query.matches(el, 'presentation')) {
		ret = el.getAttribute('alt');
	}
	// caption
	// table
	if (!ret && (recursive || allowNameFromContent(el))) {
		ret = getContent(el);
	}
	if (!ret) {
		ret = el.getAttribute('title');
	}
	if (!ret) {
		ret = el.value;
	}

	return (ret || '').trim().replace(/\s+/g, ' ');
};

var getDescription = function(el) {
	var ret = '';

	if (el.matches('[aria-describedby]')) {
		var ids = el.getAttribute('aria-describedby').split(/\s+/);
		var strings = ids.map(function(id) {
			var label = document.getElementById(id);
			return getName(label, true, true);
		});
		ret = strings.join(' ');
	} else if (el.title) {
		ret = el.title;
	} else if (el.placeholder) {
		ret = el.placeholder;
	}

	return ret;
};

module.exports = {
	getName: getName,
	getDescription: getDescription,
};
<commit_msg>improve getName<commit_after>var constants = require('./constants.js');
var query = require('./query.js');

var getPseudoContent = function(node, selector) {
	var styles = window.getComputedStyle(node, selector);
	var ret = styles.getPropertyValue('content');
	if (ret === 'none' || ret.substr(0, 4) === '-moz') {
		return '';
	} else {
		return ret;
	}
};

var getContent = function(root) {
	var ret = getPseudoContent(root, ':before');
	var node = root.firstChild;
	while (node) {
		if (node.nodeType === node.TEXT_NODE) {
			ret += node.textContent;
		} else if (node.nodeType === node.ELEMENT_NODE) {
			ret += getName(node, true);
		}
		node = node.nextSibling;
	}
	ret += getPseudoContent(root, ':after');
	return ret;
};

var allowNameFromContent = function(el) {
	var role = query.getRole(el);
	return !role || constants.nameFromContents.indexOf(role) != -1;
};

var isLabelable = function(el) {
	var selector = constants.labelable.join(',');
	return el.matches(selector);
};

// Control.labels is part of the standard, but not supported in most browsers
var getLabelNode = function(node) {
	if (node.id) {
		var selector = 'label[for="' + node.id + '"]';
		var label = document.querySelector(selector);
		if (label) {
			return label;
		}
	}

	var p = node.parentNode;
	while (p) {
		if (p.tagName === 'LABEL') {
			return p;
		}
		p = p.parentNode;
	}
};

// http://www.ssbbartgroup.com/blog/how-the-w3c-text-alternative-computation-works/
// https://www.w3.org/TR/accname-aam-1.1/#h-mapping_additional_nd_te
var getName = function(el, recursive, force) {
	var ret;

	if (!force && query.matches(el, ':hidden')) {
		return '';
	}
	if (query.matches(el, 'presentation')) {
		return getContent(el);
	}
	if (!recursive && el.matches('[aria-labelledby')) {
		var ids = el.getAttribute('aria-labelledby').split(/\s+/);
		var strings = ids.map(function(id) {
			var label = document.getElementById(id);
			return getName(label, true, true);
		});
		ret = strings.join(' ');
	}
	if (!ret && el.matches('[aria-label]')) {
		ret = el.getAttribute('aria-label');
	}
	if (!query.matches(el, 'presentation')) {
		if (!ret && isLabelable(el)) {
			var label = getLabelNode(el);
			if (label) {
				ret = getName(label, recursive);
			}
		}
		if (!ret) {
			ret = el.getAttribute('placeholder');
		}
		// figcaption
		if (!ret) {
			ret = el.getAttribute('alt');
		}
		// caption
		// table
	}
	if (!ret) {
		// FIXME: distinguish different input types
		ret = el.value;
	}
	if (!ret && (recursive || allowNameFromContent(el))) {
		ret = getContent(el);
	}
	if (!ret) {
		ret = el.getAttribute('title');
	}

	return (ret || '').trim().replace(/\s+/g, ' ');
};

var getDescription = function(el) {
	var ret = '';

	if (el.matches('[aria-describedby]')) {
		var ids = el.getAttribute('aria-describedby').split(/\s+/);
		var strings = ids.map(function(id) {
			var label = document.getElementById(id);
			return getName(label, true, true);
		});
		ret = strings.join(' ');
	} else if (el.title) {
		ret = el.title;
	} else if (el.placeholder) {
		ret = el.placeholder;
	}

	return ret;
};

module.exports = {
	getName: getName,
	getDescription: getDescription,
};
<|endoftext|>


<commit_before>/* ================================================

    CookieMaster - A Cookie Clicker plugin

    Version:      1.11.3
    Date:         23/12/2013
    Website:      http://cookiemaster.co.uk
    GitHub:       https://github.com/greenc/CookieMaster
    Dependencies: Cookie Clicker, jQuery
    Author:       Chris Green
                  c.robert.green@gmail.com

    This code was written to be used, abused,
    extended and improved upon. Feel free to do
    with it as you please, with or without
    permission from, nor credit given to the
    original author (me).

================================================ */

/*global CM:false,google:false*/

/**
 * This file acts as a bootstrap to load the CookieMaster dependencies and scripts.
 * It enables us to request the latest version of all files without users having
 * to update their bookmarks :)
 */
if(typeof CM === 'undefined') {

	(function() {

		var version = '1.11.3',
			cmcss   = document.createElement('link'),
			jquery  = document.createElement('script'),
			jsapi   = document.createElement('script'),
			cmex    = document.createElement('script'),
			cmjs    = document.createElement('script');

		// Set CSS file attributes
		cmcss.rel  = 'stylesheet';
		cmcss.type = 'text/css';
		cmcss.href = '../cookiemaster/src/cookiemaster.css?v=' + version;

		// Set async on scripts
		jquery.async = false;
		jsapi.async  = false;
		cmex.async   = false;
		cmjs.async   = false;

		// Set script sources
		jquery.src = '//ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.0.min.js';
		jsapi.src  = '//www.google.com/jsapi';
		cmex.src   = '../cookiemaster/src/external-methods.js?v=' + version;
		cmjs.src   = '../cookiemaster/src/cookiemaster.js?v='     + version;

		// Add to DOM
		document.head.appendChild(cmcss);
		document.body.appendChild(jquery);
		document.body.appendChild(jsapi);
		document.body.appendChild(cmex);
		document.body.appendChild(cmjs);

	})();

} else {

	CM.message('Error: CookieMaster is already loaded!', 'error');

}<commit_msg>Refactored bootstrap file for DRYness and performance<commit_after>/* ================================================

    CookieMaster - A Cookie Clicker plugin

    Version:      1.11.3
    Date:         23/12/2013
    Website:      http://cookiemaster.co.uk
    GitHub:       https://github.com/greenc/CookieMaster
    Dependencies: Cookie Clicker, jQuery
    Author:       Chris Green
                  c.robert.green@gmail.com

    This code was written to be used, abused,
    extended and improved upon. Feel free to do
    with it as you please, with or without
    permission from, nor credit given to the
    original author (me).

================================================ */

/*global CM:false,google:false*/

/**
 * This file acts as a bootstrap to load the CookieMaster dependencies and scripts.
 * It enables us to request the latest version of all files without users having
 * to update their bookmarks :)
 */
if(typeof CM === 'undefined') {

	(function() {

		var version = '1.11.3',
			docFrag = document.createDocumentFragment(),
			deps = [
				{
					// CookieMaster CSS
					type:    'link',
					url:     '../cookiemaster/src/cookiemaster.css',
					async:   true,
					nocache: true
				},
				{
					// jQuery
					type:    'script',
					url:     '//ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.0.min.js',
					async:   false,
					nocache: false
				},
				{
					// Google Charts API
					type:    'script',
					url:     '//www.google.com/jsapi',
					async:   false,
					nocache: false
				},
				{
					// External CookieMaster methods
					type:    'script',
					url:     '../cookiemaster/src/external-methods.js',
					async:   false,
					nocache: true
				},
				{
					// CookieMaster methods
					type:    'script',
					url:     '../cookiemaster/src/cookiemaster.js',
					async:   false,
					nocache: true
				},
			],
			dep, el, qp, i;

		/**
		 * Create an element for each dependency and
		 * append to a document fragment
		 */
		for(i = 0; i < deps.length; i++) {

			dep = deps[i];
			el  = document.createElement(dep.type);
			qp  = dep.nocache ? '?v=' + version : '';

			if(dep.type === 'link') {
				el.rel  = 'stylesheet';
				el.href = dep.url + qp;
			} else if(dep.type === 'script') {
				el.src = dep.url + qp;
			}

			el.async = dep.async;
			docFrag.appendChild(el);

		}

		/**
		 * Append fragment to DOM
		 */
		document.head.appendChild(docFrag);

	})();

} else {

	CM.message('Error: CookieMaster is already loaded!', 'error');

}<|endoftext|>


<commit_before>#! /usr/bin/env node

var fs = require('fs');
var clean = require('./commands/clean');

/* do we have a makefile? */
if (fs.existsSync('makefile')) {
  console.log('found a makefile');
} else {
  console.log('no makefile present');
}

clean();
<commit_msg>basic arg parsing<commit_after>#! /usr/bin/env node

var fs = require('fs');
var clean = require('./commands/clean');

var commands = ['clean', 'init'],
    options = {
      command: 'clean',
      path: '.'
    },
    args = process.argv.slice(2);

if (args.length == 0) {
} else if (args.length == 1) {
  if (commands.indexOf(args[0]) == -1) {
    console.log('invalid command: ' + args[0]);
    process.exit(1); // failure
  } else {
    options.command = args[0];
  }
} else if (args.length == 2) {
  if (!fs.existsSync(args[1])) {
    console.log('path not found: ' + args[1]);
    process.exit(1); // failure
  } else {
    options.path = args[1];
  }
} else {
  console.log('syntax error');
}

console.log('it worked ' + options.command + ' ' + options.path);
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var async = require('async');
var _ = require('underscore');
var path = require('path');

var config = {
    auth_url:'/login',
    register_url:'/register',
    admin_uri:'/admin',
    trigger_uri:'/trigger',
    whoami_uri:'/me',
    illegal_namespaces:[
        'admin',
        'bananas',
        'me',
        'iframe',
        'settings'
    ],
    developers:{
        iframes:[
            { name: 'Account Settings', namespace:"account_settings"},
            { name: 'Super Admin Settings', namespace:"super_admin_settings"}

        ]
    },
    core:{
        api:{
            prefix:'api.',
            protocol:'https',
            host:'api.localhost:3030'
        }
    }

}
var njax_util = require('njax-util');
var njax = function(options){
    options = _.extend(config, options)

    var app = njax_util.app(options);
    if(!app.njax.config.api && app.njax.config.core.api){
        app.njax.config.core.api = app.njax.config.api;
    }
    app.njax.config.njax_dir = path.join(__dirname, '..');

    app.njax.config.njax_tpl_dir = path.join(app.njax.config.njax_dir, 'public', 'templates');
    app.locals.partials = {
        _header:app.njax.config.njax_util_tpl_dir + '/_header',
        _footer:app.njax.config.njax_util_tpl_dir + '/_footer',
        _iframe_parent:app.njax.config.njax_tpl_dir + '/_iframe_parent'
    };
    app.njax.addTemplateDir(app.njax.config.njax_tpl_dir);
    require('./modules')(app);

    require('./routes')(app);
    var _start = _.bind(app.start, app);
    app.start = _.bind(function(){
        app.njax.cache('super_admins',function(cb){
            var query = {
                $or:[]
            }
            for(var i in app.njax.config.super_admin_emails){
                query.$or.push({ email:app.njax.config.super_admin_emails[i] });
            }
            app.model.Account.find(query).exec(function(err, accounts){
               if(err) return cb(err);
               return cb(null, accounts);
            });
        }, [], function(err){
            if(err) throw new err;
        });
        _start();
    }, app);
    return app;
}
module.exports = njax;

<commit_msg>Code flying from the fingertips<commit_after>
/**
 * Module dependencies.
 */

var async = require('async');
var _ = require('underscore');
var path = require('path');

var config = {
    auth_url:'/login',
    register_url:'/register',
    admin_uri:'/admin',
    trigger_uri:'/trigger',
    whoami_uri:'/me',
    illegal_namespaces:[
        'admin',
        'bananas',
        'me',
        'iframe',
        'settings'
    ],
    developers:{
        iframes:[
            { name: 'Account Settings', namespace:"account_settings"},
            { name: 'Super Admin Settings', namespace:"super_admin_settings"}

        ]
    },
    core:{
        api:{
            prefix:'api.',
            protocol:'https',
            host:'api.localhost:3030'
        }
    }

}
var njax_util = require('njax-util');
var njax = function(options){
    options = _.extend(config, options)

    var app = njax_util.app(options);
    if(!app.njax.config.api && app.njax.config.core.api){
        app.njax.config.api = app.njax.config.core.api;
    }
    app.njax.config.njax_dir = path.join(__dirname, '..');

    app.njax.config.njax_tpl_dir = path.join(app.njax.config.njax_dir, 'public', 'templates');
    app.locals.partials = {
        _header:app.njax.config.njax_util_tpl_dir + '/_header',
        _footer:app.njax.config.njax_util_tpl_dir + '/_footer',
        _iframe_parent:app.njax.config.njax_tpl_dir + '/_iframe_parent'
    };
    app.njax.addTemplateDir(app.njax.config.njax_tpl_dir);
    require('./modules')(app);

    require('./routes')(app);
    var _start = _.bind(app.start, app);
    app.start = _.bind(function(){
        app.njax.cache('super_admins',function(cb){
            var query = {
                $or:[]
            }
            for(var i in app.njax.config.super_admin_emails){
                query.$or.push({ email:app.njax.config.super_admin_emails[i] });
            }
            app.model.Account.find(query).exec(function(err, accounts){
               if(err) return cb(err);
               return cb(null, accounts);
            });
        }, [], function(err){
            if(err) throw new err;
        });
        _start();
    }, app);
    return app;
}
module.exports = njax;

<|endoftext|>


<commit_before>/* -*- Mode: Javascript; js-indent-level: 2 -*- */

var async = require('async');
var naan = require('naan');
var _ = require('underscore');
var util = require('util');

module.exports = {
  /**
   * Save or update an object. If a new object is passed, the callback will
   * return a copy of that object with the <options.id> key set to the id of the
   * created object.
   */
  save: function(obj, callback) {
    if (Array.isArray(obj)) {
      return this.throttleMap(obj, this.node.save, callback);
    }

    var id = this._getId(obj, true);

    if (!this._isValidId(id)) {
      if (typeof obj !== 'object') {
        return callback(new Error("No data to save"));
      }

      this.node._create(obj, callback);
    } else {
      this.node._update(obj, callback);
    }
  },

  /**
   * Create a new object. Maps to /node.
   */
  _create: function(obj, callback) {
    var op = this.operation('node', obj);
    this.call(op, function(err, body, location) {
      if (err) {
        return callback(err);
      }

      var result = _.clone(obj);
      result[this.options.id] = this._extractId(location);

      callback(null, result);
    });
  },

  /**
   * Save the properties of an object. Maps to PUT /node/{id}/properties.
   */
  _update: function(obj, callback) {
    var id = this._getId(obj, true);
    if (!this._isValidId(id)) {
      return callback(new Error("Invalid ID"));
    }

    var untouchedObj = _.clone(obj);
    if (untouchedObj[this.options.id] != null) {
      delete untouchedObj[this.options.id];
    }

    var endpoint = util.format('node/%s/properties', id);
    var op = this.operation(endpoint, 'PUT', untouchedObj);
    this.call(op, function(err, body, response) {
      if (err) {
        return callback(err);
      } else {
        return callback(null, obj);
      }
    });
  },

  /**
   * Read an object's properties. Maps to GET node/{id}/properties.
   */
  read: function(id, callback) {
    if (Array.isArray(id)) {
      return this.throttleMap(id, this.node.read, callback);
    }

    id = this._getId(id);
    if (!this._isValidId(id)) {
      return callback(new Error("Invalid ID"));
    }

    var endpoint = util.format('node/%s/properties', id);
    var op = this.operation(endpoint);
    this.call(op, function(err, body) {
      if (err) {
        return callback(err);
      } else {
        body[this.options.id] = id;
        return callback(null, body);
      }
    });
  },

  /**
   * Delete an object. Maps to DELETE node/{id}
   * If force is truthy, delete node and all its relations.
   */
  delete: function(id, force, callback) {
    if (typeof force === 'function') {
      callback = force;
      force = false;
    }

    if (Array.isArray(id)) {
      return this.throttleMap(id, this.node.delete, callback);
    }

    id = this._getId(id);
    if (!this._isValidId(id)) {
      return callback(new Error("Invalid ID"));
    }

    var self = this;

    function deleteRelations(cb) {
      function queryDone(err, data) {
        if (err)
          return cb(err);
        self.rel.delete(data, cb);
      }
      self.query("START n=node({id}) MATCH n-[r]-m RETURN r",
                 { id: id },
                 queryDone);
    }

    function deleteNode() {
      var endpoint = util.format('node/%s', id);
      var op = self.operation(endpoint, 'DELETE');
      self.call(op, function(err) {
        callback(err);
      });
    };

    if (force) {
      deleteRelations(function(err) {
        if (err)
          return callback(err);
        deleteNode();
      });
    } else {
      deleteNode();
    }
  },

  /**
   * Relate objects together. maps to POST node/{first}/relationships
   */
  relate: function(startNode, type, endNode, properties, callback) {
    this.rel.create(startNode, type, endNode, properties, callback);
  },

  /**
   * Retrieve a set of relationships for the given node. Optionally specify the
   * direction and relationship name.
   *
   * `direction` must be one of "all", "in" or "out".
   *
   * db.relationships(obj|id, [direction, [relationshipName]], callback)
   */
  relationships: function(obj, direction, relName, callback) {
    if (typeof direction === 'function') {
      callback = direction;
      direction = 'all';
      relName = '';
    } else {
      if (typeof relName === 'function') {
        callback = relName;
        relName = '';
      }

      if (typeof direction !== 'string') {
        return callback(new Error('Invalid direction - ' + direction));
      } else if (typeof relName !== 'string') {
        return callback(new Error('Invalid relationship name - ' + relName));
      }

      direction = direction.toLowerCase();
      if (['in', 'all', 'out'].indexOf(direction) === -1) {
        return callback(new Error('Invalid direction - ' + direction));
      }
    }

    if (Array.isArray(obj)) {
      var args = [ direction, relName ];
      var rels = naan.ecurry(this.node.relationships, args, [1, 2]);
      return this.throttleMap(obj, rels, callback);
    }

    var objId = this._getId(obj);

    if (!this._isValidId(objId)) {
      callback(new Error("Invalid ID"));
    }

    var endpoint = util.format('node/%s/relationships/%s', objId, direction);
    if (relName) {
      endpoint += "/" + relName;
    }
    var op = this.operation(endpoint);
    var self = this;
    this.call(op, function(err, rels) {
      if (err) {
        callback(err);
      } else {
        rels = rels.map(function(rel) {
          return self._createRelationshipObject(rel);
        });
        callback(null, rels);
      }
    });
  },

  /**
   * Perform a query based on a predicate. The predicate is translated to a
   * cypher query.
   */
  find: function(predicate, any, start, callback) {
    if (typeof any === 'function') {
      callback = any;
      any = false;
      start = 'node(*)';
    } else if (typeof start === 'function') {
      callback = start;
      start = 'node(*)';
    }

    if (Array.isArray(predicate)) {
      var finder = naan.ncurry(this.node.find, any, 2);
      return this.throttleMap(predicate, finder, callback);
    }

    if (typeof predicate !== 'object') {
      callback(new Error('Invalid Predicate'));
    }

    var matchers = Object.keys(predicate).reduce(function(matchers, key) {
      return matchers.push(util.format(" (n.%s! = {%s}) ", key, key)), matchers;
    }, []);

    var cypher = [
      "START n = " + start + " WHERE",
      matchers.join(any ? "or" : "and"),
      "RETURN n"
    ].join(" ");

    var self = this;
    this.query(cypher, predicate, callback);
  }
}
<commit_msg>Refactored node root to single function<commit_after>/* -*- Mode: Javascript; js-indent-level: 2 -*- */

var async = require('async');
var naan = require('naan');
var _ = require('underscore');
var util = require('util');

module.exports = {
  /**
   * Save or update an object. If a new object is passed, the callback will
   * return a copy of that object with the <options.id> key set to the id of the
   * created object.
   */
  save: function(obj, callback) {
    if (Array.isArray(obj)) {
      return this.throttleMap(obj, this.node.save, callback);
    }

    var id = this._getId(obj, true);

    if (!this._isValidId(id)) {
      if (typeof obj !== 'object') {
        return callback(new Error("No data to save"));
      }

      this.node._create(obj, callback);
    } else {
      this.node._update(obj, callback);
    }
  },

  /**
   * Create a new object. Maps to /node.
   */
  _create: function(obj, callback) {
    var op = this.operation('node', obj);
    this.call(op, function(err, body, location) {
      if (err) {
        return callback(err);
      }

      var result = _.clone(obj);
      result[this.options.id] = this._extractId(location);

      callback(null, result);
    });
  },

  /**
   * Save the properties of an object. Maps to PUT /node/{id}/properties.
   */
  _update: function(obj, callback) {
    var id = this._getId(obj, true);
    if (!this._isValidId(id)) {
      return callback(new Error("Invalid ID"));
    }

    var untouchedObj = _.clone(obj);
    if (untouchedObj[this.options.id] != null) {
      delete untouchedObj[this.options.id];
    }

    var endpoint = util.format('%s/properties', this._nodeRoot(id));
    var op = this.operation(endpoint, 'PUT', untouchedObj);
    this.call(op, function(err, body, response) {
      if (err) {
        return callback(err);
      } else {
        return callback(null, obj);
      }
    });
  },

  /**
   * Read an object's properties. Maps to GET node/{id}/properties.
   */
  read: function(id, callback) {
    if (Array.isArray(id)) {
      return this.throttleMap(id, this.node.read, callback);
    }

    id = this._getId(id);
    if (!this._isValidId(id)) {
      return callback(new Error("Invalid ID"));
    }

    var endpoint = util.format('%s/properties', this._nodeRoot(id));
    var op = this.operation(endpoint);
    this.call(op, function(err, body) {
      if (err) {
        return callback(err);
      } else {
        body[this.options.id] = id;
        return callback(null, body);
      }
    });
  },

  /**
   * Delete an object. Maps to DELETE node/{id}
   * If force is truthy, delete node and all its relations.
   */
  delete: function(id, force, callback) {
    if (typeof force === 'function') {
      callback = force;
      force = false;
    }

    if (Array.isArray(id)) {
      return this.throttleMap(id, this.node.delete, callback);
    }

    id = this._getId(id);
    if (!this._isValidId(id)) {
      return callback(new Error("Invalid ID"));
    }

    var self = this;

    function deleteRelations(cb) {
      function queryDone(err, data) {
        if (err)
          return cb(err);
        self.rel.delete(data, cb);
      }
      self.query("START n=node({id}) MATCH n-[r]-m RETURN r",
                 { id: id },
                 queryDone);
    }

    function deleteNode() {
      var endpoint = self._nodeRoot(id);
      var op = self.operation(endpoint, 'DELETE');
      self.call(op, function(err) {
        callback(err);
      });
    };

    if (force) {
      deleteRelations(function(err) {
        if (err)
          return callback(err);
        deleteNode();
      });
    } else {
      deleteNode();
    }
  },

  /**
   * Relate objects together. maps to POST node/{first}/relationships
   */
  relate: function(startNode, type, endNode, properties, callback) {
    this.rel.create(startNode, type, endNode, properties, callback);
  },

  /**
   * Retrieve a set of relationships for the given node. Optionally specify the
   * direction and relationship name.
   *
   * `direction` must be one of "all", "in" or "out".
   *
   * db.relationships(obj|id, [direction, [relationshipName]], callback)
   */
  relationships: function(obj, direction, relName, callback) {
    if (typeof direction === 'function') {
      callback = direction;
      direction = 'all';
      relName = '';
    } else {
      if (typeof relName === 'function') {
        callback = relName;
        relName = '';
      }

      if (typeof direction !== 'string') {
        return callback(new Error('Invalid direction - ' + direction));
      } else if (typeof relName !== 'string') {
        return callback(new Error('Invalid relationship name - ' + relName));
      }

      direction = direction.toLowerCase();
      if (['in', 'all', 'out'].indexOf(direction) === -1) {
        return callback(new Error('Invalid direction - ' + direction));
      }
    }

    if (Array.isArray(obj)) {
      var args = [ direction, relName ];
      var rels = naan.ecurry(this.node.relationships, args, [1, 2]);
      return this.throttleMap(obj, rels, callback);
    }

    var objId = this._getId(obj);

    if (!this._isValidId(objId)) {
      callback(new Error("Invalid ID"));
    }

    var nodeRoot = this._nodeRoot(objId);
    var endpoint = util.format('%s/relationships/%s', nodeRoot, direction);
    if (relName) {
      endpoint += "/" + relName;
    }
    var op = this.operation(endpoint);
    var self = this;
    this.call(op, function(err, rels) {
      if (err) {
        callback(err);
      } else {
        rels = rels.map(function(rel) {
          return self._createRelationshipObject(rel);
        });
        callback(null, rels);
      }
    });
  },

  /**
   * Perform a query based on a predicate. The predicate is translated to a
   * cypher query.
   */
  find: function(predicate, any, start, callback) {
    if (typeof any === 'function') {
      callback = any;
      any = false;
      start = 'node(*)';
    } else if (typeof start === 'function') {
      callback = start;
      start = 'node(*)';
    }

    if (Array.isArray(predicate)) {
      var finder = naan.ncurry(this.node.find, any, 2);
      return this.throttleMap(predicate, finder, callback);
    }

    if (typeof predicate !== 'object') {
      callback(new Error('Invalid Predicate'));
    }

    var matchers = Object.keys(predicate).reduce(function(matchers, key) {
      return matchers.push(util.format(" (n.%s! = {%s}) ", key, key)), matchers;
    }, []);

    var cypher = [
      "START n = " + start + " WHERE",
      matchers.join(any ? "or" : "and"),
      "RETURN n"
    ].join(" ");

    var self = this;
    this.query(cypher, predicate, callback);
  }
}
<|endoftext|>


<commit_before>'use strict'

const _ = require('lodash')
const co = require('co')
const fs = require('fs-extra')
const pify = require('pify')
const ansiHTML = require('ansi-html')
const serialize = require('serialize-javascript')
const build = require('./build')
const render = require('./render')
const generate = require('./generate')
const serveStatic = require('serve-static')
const { resolve, join } = require('path')
const { encodeHtml, setAnsiColors } = require('./utils')
setAnsiColors(ansiHTML)

class Nuxt {

  constructor (options = {}, cb) {
    var defaults = {
      // special options
      _renderer: true,
      _build: true,
      // general options
      dev: true,
      env: {},
      head: {},
      plugins: [],
      css: [],
      cache: false,
      loading: {
        color: 'black',
        failedColor: 'red',
        height: '2px',
        duration: 5000
      },
      transition: {
        name: 'page',
        mode: 'out-in'
      },
      router: {
        base: '/',
        linkActiveClass: 'router-link-active',
        routes: []
      },
      build: {
        filenames: {
          css: 'style.css'
        }
      }
    }
    if (options.loading === true) delete options.loading
    if (typeof options.transition === 'string') options.transition = { name: options.transition }
    this.options = _.defaultsDeep(options, defaults)
    // Env variables
    this.dev = this.options.dev
    this.dir = (typeof options.rootDir === 'string' && options.rootDir ? options.rootDir : process.cwd())
    // If store defined, update store options to true
    if (fs.existsSync(join(this.dir, 'store', 'index.js'))) {
      this.options.store = true
    }
    // Template
    this.appTemplate = _.template(fs.readFileSync(resolve(__dirname, 'views', 'app.html'), 'utf8'), {
      imports: { serialize }
    })
    this.errorTemplate = _.template(fs.readFileSync(resolve(__dirname, 'views', 'error.html'), 'utf8'), {
      imports: { ansiHTML, encodeHtml }
    })
    // renderer used by Vue.js (via createBundleRenderer)
    this.renderer = null
    // For serving static/ files to /
    this.serveStatic = pify(serveStatic(resolve(this.dir, 'static')))
    // For serving .nuxt/dist/ files
    this._nuxtRegexp = /^\/_nuxt\//
    this.serveStaticNuxt = pify(serveStatic(resolve(this.dir, '.nuxt', 'dist')))
    // Add this.build
    this.build = build.bind(this)
    // Add this.render and this.renderRoute
    this.render = render.render.bind(this)
    this.renderRoute = render.renderRoute.bind(this)
    // Add this.generate
    this.generate = generate.bind(this)
    // Launch build and set this.renderer
    return co(this.build)
    .then(() => {
      if (typeof cb === 'function') cb(null, this)
      return this
    })
    .catch((err) => {
      if (typeof cb === 'function') cb(err)
      return Promise.reject(err)
    })
  }

  close (callback) {
    let promises = []
    if (this.webpackDevMiddleware) {
      const p = new Promise((resolve, reject) => {
        this.webpackDevMiddleware.close(() => resolve())
      })
      promises.push(p)
    }
    if (this.webpackServerWatcher) {
      const p = new Promise((resolve, reject) => {
        this.webpackServerWatcher.close(() => resolve())
      })
      promises.push(p)
    }
    if (this.pagesFilesWatcher) {
      this.pagesFilesWatcher.close()
    }
    return co(function * () {
      yield promises
    })
    .then(function () {
      if (typeof callback === 'function') callback()
    })
  }

}

module.exports = Nuxt
<commit_msg>remove non-used option<commit_after>'use strict'

const _ = require('lodash')
const co = require('co')
const fs = require('fs-extra')
const pify = require('pify')
const ansiHTML = require('ansi-html')
const serialize = require('serialize-javascript')
const build = require('./build')
const render = require('./render')
const generate = require('./generate')
const serveStatic = require('serve-static')
const { resolve, join } = require('path')
const { encodeHtml, setAnsiColors } = require('./utils')
setAnsiColors(ansiHTML)

class Nuxt {

  constructor (options = {}, cb) {
    var defaults = {
      // special options
      _renderer: true,
      _build: true,
      // general options
      dev: true,
      env: {},
      head: {},
      plugins: [],
      css: [],
      cache: false,
      loading: {
        color: 'black',
        failedColor: 'red',
        height: '2px',
        duration: 5000
      },
      transition: {
        name: 'page',
        mode: 'out-in'
      },
      router: {
        base: '/',
        linkActiveClass: 'router-link-active',
        routes: []
      },
      build: {}
    }
    if (options.loading === true) delete options.loading
    if (typeof options.transition === 'string') options.transition = { name: options.transition }
    this.options = _.defaultsDeep(options, defaults)
    // Env variables
    this.dev = this.options.dev
    this.dir = (typeof options.rootDir === 'string' && options.rootDir ? options.rootDir : process.cwd())
    // If store defined, update store options to true
    if (fs.existsSync(join(this.dir, 'store', 'index.js'))) {
      this.options.store = true
    }
    // Template
    this.appTemplate = _.template(fs.readFileSync(resolve(__dirname, 'views', 'app.html'), 'utf8'), {
      imports: { serialize }
    })
    this.errorTemplate = _.template(fs.readFileSync(resolve(__dirname, 'views', 'error.html'), 'utf8'), {
      imports: { ansiHTML, encodeHtml }
    })
    // renderer used by Vue.js (via createBundleRenderer)
    this.renderer = null
    // For serving static/ files to /
    this.serveStatic = pify(serveStatic(resolve(this.dir, 'static')))
    // For serving .nuxt/dist/ files
    this._nuxtRegexp = /^\/_nuxt\//
    this.serveStaticNuxt = pify(serveStatic(resolve(this.dir, '.nuxt', 'dist')))
    // Add this.build
    this.build = build.bind(this)
    // Add this.render and this.renderRoute
    this.render = render.render.bind(this)
    this.renderRoute = render.renderRoute.bind(this)
    // Add this.generate
    this.generate = generate.bind(this)
    // Launch build and set this.renderer
    return co(this.build)
    .then(() => {
      if (typeof cb === 'function') cb(null, this)
      return this
    })
    .catch((err) => {
      if (typeof cb === 'function') cb(err)
      return Promise.reject(err)
    })
  }

  close (callback) {
    let promises = []
    if (this.webpackDevMiddleware) {
      const p = new Promise((resolve, reject) => {
        this.webpackDevMiddleware.close(() => resolve())
      })
      promises.push(p)
    }
    if (this.webpackServerWatcher) {
      const p = new Promise((resolve, reject) => {
        this.webpackServerWatcher.close(() => resolve())
      })
      promises.push(p)
    }
    if (this.pagesFilesWatcher) {
      this.pagesFilesWatcher.close()
    }
    return co(function * () {
      yield promises
    })
    .then(function () {
      if (typeof callback === 'function') callback()
    })
  }

}

module.exports = Nuxt
<|endoftext|>


<commit_before>// Sliding Window Maximum

// Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window.
// Each time the sliding window moves right by one position.

// For example,
// Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.

// Window position                Max
// ---------------               -----
// [1  3  -1] -3  5  3  6  7       3
//  1 [3  -1  -3] 5  3  6  7       3
//  1  3 [-1  -3  5] 3  6  7       5
//  1  3  -1 [-3  5  3] 6  7       5
//  1  3  -1  -3 [5  3  6] 7       6
//  1  3  -1  -3  5 [3  6  7]      7
// Therefore, return the max sliding window as [3,3,5,5,6,7].

// Note:
// You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.

// Follow up:
// Could you solve it in linear time?

/**
 * @param {array[]} nums
 * @param {number} k
 * @return {array[]}
 */

// first attempt

const maxSlidingWindow = function msw(nums, k) {
  if (nums.length < 1) return nums;
  if (k === 0) return [nums[0]].concat(nums);
  const result = [];
  for (let i = 0; i <= nums.length - k; i += 1) {
    result.push(Math.max.apply(null, nums.slice(i, i + k)));
  }
  return result;
};

maxSlidingWindow([1, 3, -1, -3, 5, 3, 6, 7], 3);
<commit_msg>add logic<commit_after>// Sliding Window Maximum

// Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window.
// Each time the sliding window moves right by one position.

// For example,
// Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.

// Window position                Max
// ---------------               -----
// [1  3  -1] -3  5  3  6  7       3
//  1 [3  -1  -3] 5  3  6  7       3
//  1  3 [-1  -3  5] 3  6  7       5
//  1  3  -1 [-3  5  3] 6  7       5
//  1  3  -1  -3 [5  3  6] 7       6
//  1  3  -1  -3  5 [3  6  7]      7
// Therefore, return the max sliding window as [3,3,5,5,6,7].

// Note:
// You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.

// Follow up:
// Could you solve it in linear time?

/**
 * @param {array[]} nums
 * @param {number} k
 * @return {array[]}
 */

// first attempt / naive solution

// if nums is empty return an empty array
// if sliding window is 0
  // return the first element twice and the rest of the array
// create result variable to store max in order
// create a loop that is the size of our array minus the size of the sliding door
  // for every iteration we only look at the k amount of elements - nums.slice(i, i + k)
  // each iteration we look for the max - Math.max.apply(null, nums.slice(i, i + k)), and push into the result array and check the next set
// at the end return elements we pushed into result array

const maxSlidingWindow = function msw(nums, k) {
  if (nums.length < 1) return nums;
  if (k === 0) return [nums[0]].concat(nums);
  const result = [];
  for (let i = 0; i <= nums.length - k; i += 1) {
    result.push(Math.max.apply(null, nums.slice(i, i + k)));
  }
  return result;
};

maxSlidingWindow([1, 3, -1, -3, 5, 3, 6, 7], 3);
<|endoftext|>


<commit_before>// Redundant Braces

// Write a program to validate if the input string has redundant braces?

// Input will be always a valid expression

// and operators allowed are only + , * , - , /

// Example:

// ((a + b)) has redundant braces so answer will be true
// (a + (a + b)) doesn't have have any redundant braces so answer will be false

<commit_msg>add params<commit_after>// Redundant Braces

// Write a program to validate if the input string has redundant braces?

// Input will be always a valid expression

// and operators allowed are only + , * , - , /

// Example:

// ((a + b)) has redundant braces so answer will be true
// (a + (a + b)) doesn't have have any redundant braces so answer will be false

// param A : string
// return an integer
<|endoftext|>


<commit_before>// need to initialize the _gaq array and GA tracking since DTM has it disabled
var _gaq = _gaq || [];
_gaq.push(['mymotechcom._setAccount','UA-66310-2']);
_gaq.push(['mymotechcom._trackPageview']);

/* ---------------------------------------------------------------------------
         d8888 8888888 8888888b.  888      .d88888b.   .d8888b.  888    d8P
        d88888   888   888   Y88b 888     d88P" "Y88b d88P  Y88b 888   d8P
       d88P888   888   888    888 888     888     888 888    888 888  d8P
      d88P 888   888   888   d88P 888     888     888 888        888d88K
     d88P  888   888   8888888P"  888     888     888 888        8888888b
    d88P   888   888   888 T88b   888     888     888 888    888 888  Y88b
   d8888888888   888   888  T88b  888     Y88b. .d88P Y88b  d88P 888   Y88b
  d88P     888 8888888 888   T88b 88888888 "Y88888P"   "Y8888P"  888    Y88b
------------------------------------------------------------------------------
Airlock v0.2.0
(c) 2013 by Search Discovery <http://searchdiscovery.com/>

airlock.js may be freely distributed under the MIT license.

For all details and documentation: http://www.searchdiscovery.com/airlock
----------------------------------------------------------------------------*/
(function (window, document, undefined) {

  // First thing's first; load the new hotness.
  (function(a, i, r, l, o, c, k) {
    if (a.GoogleAnalyticsObject && a[a.GoogleAnalyticsObject]) { return; }
    a.GoogleAnalyticsObject = o;
    a[o] = a[o] || (function() {
      (a[o].q = a[o].q || []).push(arguments);
    });
    a[o].l = 1 * (new Date());
    c = i.createElement(r);
    k = i.getElementsByTagName(r)[0];
    c.async = 1;
    c.src = l;
    k.parentNode.insertBefore(c, k);
  })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');

  // We're pretty loopy here, so this makes our lives easier.
  if (!Array.prototype.forEach) {
    Array.prototype.forEach = function (fn, scope) {
      for (var i = 0, len = this.length; i < len; ++i) {
        if (i in this) {
          fn.call(scope, this[i], i, this);
        }
      }
    };
  }

  // Convenience functions
  var returnArg = function (arg) { return arg; };

  var _gaq = window._gaq,
      ga = window[window.GoogleAnalyticsObject],
      rx = {
        actions: /^([\w\d_-]+)?\.?(_track(Event|Pageview|Trans|Social|Timing)|_add(Item|Trans)|_set(CustomVar|Account|DomainName|AllowLinker|SampleRate|CookiePath)?|_link|_require)$/,
        setupActions: /^(.+\.)?_(set(Account|CustomVar|DomainName|AllowLinker|SampleRate|CookiePath)?)$/,
        ecommerceActions: /^(.+\.)?_(add(Trans|Item)|trackTrans)$/,
        writeableSet: /^page|title$/
      }, i, ln;

  var Store = function () {
    this._contents = {};
    this._defaultKey = 't0';
  };
  Store.prototype.get = function (key) {
    key = key || this._defaultKey;
    return this._contents[key];
  };
  Store.prototype.set = function (key, val) {
    key = key || this._defaultKey;
    this._contents[key] = val;
    return this;
  };
  Store.prototype.has = function (key) {
    key = key || this._defaultKey;
    return !!this._contents[key];
  };
  Store.prototype.forEach = function (func, context) {
    for (var key in this._contents) {
      if (this._contents.hasOwnProperty(key)) {
        func.call(context, this._contents[key], key, this._contents);
      }
    }
  };

  // Each spaceship represents a tracker namespace.
  var SpaceShip = function (namespace, account) {
    if (typeof namespace === 'object') {
      tracker = namespace;
      namespace = tracker.get('name');
      account = tracker.get('trackingId');
      return new SpaceShip(namespace, account).initialize();
    }
    this.settings = {};
    this._settings = {};
    this.namespace = namespace;
    this.account = account;
    this.setupQueue = [];
    this.initialized = false;
    this.settings.name = this.namespace;
  };

  SpaceShip.prototype.setAccount = function (uaCode) {
    this.account = uaCode;
    return this;
  };

  SpaceShip.prototype.initialize = function () {
    this.setupQueue.forEach(function (qItem) { qItem(); });
    this.initialized = true;
    return this;
  };

  var Airlock = {};

  Airlock.spaceships = new Store();

  Airlock.readAction = function (actionName) {
    var match = actionName.match(rx.actions);
    return {
      namespace: match[1],
      action: match[2]
    };
  };

  Airlock.initialize = function () {
    var newQ = [], ga = window[window.GoogleAnalyticsObject];

    // loop through uninitialized ga to see if users have implemented a
    // custom "create". If so, add a function to the queue to fire directly
    // after the queue item has been processed.
    if (ga.q) {
      var tempQ = [].concat(ga.q),
          j = 0;

      ga.q.forEach(function (qItem, i) {
        if (typeof qItem[0] !== 'string' || qItem[0] !== 'create') { return; }
        j = j+i+1;
        tempQ.splice(j, 0, [function () {
          var ga = window[window.GoogleAnalyticsObject],
              settings = qItem[qItem.length - 1],
              namespace = typeof settings === 'object' && settings.name ? settings.name : 't0',
              tracker = ga.getByName(namespace),
              spaceship = new SpaceShip(tracker);

          Airlock.dock(spaceship);
        }]);
      });
      ga.q = tempQ;
    }

    // loop through initialized ga to see if users have implemented a
    // custom "create"
    if (ga.P) {
      ga.P.forEach(function (tracker) {
        var spaceship = new SpaceShip(tracker);
        this.dock(spaceship);
      }, this);
    }

    // loop through _gaq to strip out setup calls
    _gaq.forEach(function (qItem) {
      if (typeof qItem === 'function') {
        Airlock.pressurize(qItem);
        return;
      }

      var action = Airlock.readAction(qItem[0]);

      if (rx.setupActions.test(action.action)) {
        // If we find a tracker we have not yet initialized, set it up
        if (!this.spaceships.has(action.namespace)) {
          this.dock(new SpaceShip(action.namespace));
        }
        this.pressurize(qItem, this.spaceships.get(action.namespace));
        return;
      }
      newQ.push(qItem);
    }, this);

    Array.prototype.splice.apply(_gaq, [0, _gaq.length].concat(newQ));

    this.spaceships.forEach(function (spaceship) {
      Airlock.open(spaceship, [
        'create',
        spaceship.account,
        spaceship.settings
      ]);
    });

    // No need to do anything fancy here. Setting an instance method
    // `push()` on the global `_gaq` variable will intercept any calls
    // to `_gaq.prototype.push()`
    _gaq.push = function (args) {
      if (typeof args === 'function') {
        return Airlock.pressurize(args);
      }

      var action = args[0];
      // Ensure users are sending a valid action, otherwise do nothing.
      if (!rx.actions.test(action)) { return; }

      // If the user is trying to setup/send an ecommerce action
      if (rx.ecommerceActions.test(action) && !Airlock.ecommerceInitialized) {
        Airlock.ecommerceInitialized = true;
        ga('require', 'ecommerce', 'ecommerce.js');
      }
      var spaceship = Airlock.spaceships.get(Airlock.readAction(action).namespace);

      if (!spaceship) { return; }

      args = Airlock.pressurize(args, spaceship);
      Airlock.open(spaceship, args);
    };

    _gaq.forEach(_gaq.push.bind(_gaq));
  };

  // Add tracker to Airlock, push settings to ga
  Airlock.dock = function (spaceship) {
    this.spaceships.set(spaceship.namespace, spaceship);
  };

  // Once our arguments are "pressurized", send them off to `ga()`
  Airlock.open = function (spaceship, args) {
    if (!spaceship.account) { return; }
    var create = args[0] === 'create';
    if (args) {
      args[0] = !spaceship.namespace || create ?
        args[0] :
        [spaceship.namespace, args[0]].join('.');

      window[window.GoogleAnalyticsObject].apply(window, args);
      if (create) { spaceship.initialize(); }
    }
  };

  Airlock.pressurize = function (args, spaceship) {
    // break args reference
    args = [].concat(args);

    if (typeof args === 'function') {
      try {
        return args();
      } catch (e) {
        if (console && console.warn) {
          console.warn('AIRLOCK: function passed to _gaq threw error', _gaq[i].toString(), e);
        }
      }
    }

    var conversion = Airlock.conversions[args.slice(0,1)[0].replace(rx.actions, "$2")];
    if (!conversion) { return; }

    if (typeof conversion === 'function') {
      return conversion.apply(spaceship, args);
    }

    var index = {}, out = [],
        i = 0, ln = args.length < conversion.input.length ?
          args.length :
          conversion.input.length;

    // build an index to match input labels to input values
    for (; i < ln; i++) {
      index[conversion.input[i]] = args[i];
    }

    // loop through outputs and permute values as necessary
    i = 0; ln = conversion.output.length;
    conversion.output.forEach(function (output) {
      var val = permute(output, index);
      if (val) {
        out.push(val);
      }
    });
    return out;
  };

  var permute = function (template, data) {
    if (typeof template === 'function') {
      return template(data);
    }
    var templMatch = template.match(/\[\[([a-zA-Z_]+)\]\]/);
    if (templMatch) {
      if (!data[templMatch[1]]) { return; }
      // if there is no input value corresponding to the template identifier
      // (i.e., if this is an optional value), this will return undefined
      // and will be ignored.
      return template.replace(templMatch[0], data[templMatch[1]]);
    }
    return template;
  };

  Airlock.conversions = {
    // Setup actions
    _setAccount: function (uaCode) {
      this.setAccount(uaCode);
    },
    _setSampleRate: function (rate) {
      this.settings.sampleRate = rate;
    },
    _setCookiePath: function (path) {
      this.settings.cookiePath = path;
    },
    _set: function (key, val) {
      this.settings[key.replace('ua', 'cookie')] = val;

      if (rx.writeableSet.test(key)) {
        return ['set', key, val];
      }
    },
    _setDomainName: function (domainName) {
      this._settings.domainName = domainName;
    },
    _setAllowLinker: function (allow) {
      var that = this;
      this.settings.allowLinker = allow;
      this.setupQueue.push(function () {
        ga('require', 'linker');
        Airlock.open(that, ['linker:autoLink', that._settings.domainName]);
      });
    },
    // Enhanced Link Attribution
    _require: function (type){
      if (type === 'inpage_linkid') {
        return ['require','linkid','linkid.js'];
      }
    },

    // Custom Variables
    _setCustomVar: function (slot, name, value) {
      var args = ['set', 'dimension' + slot, value];

      if (this.initialized) { return args; }
      this.setupQueue.push(Airlock.open.bind(Airlock, this, args));
    },

    // Tracking actions
    _trackEvent: {
      input: ['eventCategory', 'eventAction', 'eventLabel', 'eventValue', 'nonInteraction'],
      output: ['send', 'event', returnArg]
    },
    _trackPageview: {
      input: ['pagePath'],
      output: ['send', 'pageview', '[[pagePath]]']
    },
    _trackTiming: {
      input: ['timingCategory', 'timingVar', 'timingValue', 'timingLabel'],
      output: ['send', 'timing', returnArg]
    },
    _trackSocial: {
      input: ['socialNetwork', 'socialAction', 'socialTarget', 'page'],
      output: ['send', 'social', returnArg]
    },

    // Ecommerce
    _addTrans: {
      input: ['id', 'affiliation', 'revenue', 'tax', 'shipping'],
      output: ['ecommerce:addTransaction', returnArg]
    },
    _addItem: {
      input: ['id', 'sku', 'name', 'category', 'price', 'quantity'],
      output: ['ecommerce:addItem', returnArg]
    },
    _trackTrans: {
      input: [],
      output: ['ecommerce:send']
    }
  };

  Airlock.initialize();
  window.Airlock = Airlock;
})(window, document);
<commit_msg>removed debug mechanics<commit_after>/* ---------------------------------------------------------------------------
         d8888 8888888 8888888b.  888      .d88888b.   .d8888b.  888    d8P
        d88888   888   888   Y88b 888     d88P" "Y88b d88P  Y88b 888   d8P
       d88P888   888   888    888 888     888     888 888    888 888  d8P
      d88P 888   888   888   d88P 888     888     888 888        888d88K
     d88P  888   888   8888888P"  888     888     888 888        8888888b
    d88P   888   888   888 T88b   888     888     888 888    888 888  Y88b
   d8888888888   888   888  T88b  888     Y88b. .d88P Y88b  d88P 888   Y88b
  d88P     888 8888888 888   T88b 88888888 "Y88888P"   "Y8888P"  888    Y88b
------------------------------------------------------------------------------
Airlock v0.2.0
(c) 2013 by Search Discovery <http://searchdiscovery.com/>

airlock.js may be freely distributed under the MIT license.

For all details and documentation: http://www.searchdiscovery.com/airlock
----------------------------------------------------------------------------*/
(function (window, document, undefined) {

  // First thing's first; load the new hotness.
  (function(a, i, r, l, o, c, k) {
    if (a.GoogleAnalyticsObject && a[a.GoogleAnalyticsObject]) { return; }
    a.GoogleAnalyticsObject = o;
    a[o] = a[o] || (function() {
      (a[o].q = a[o].q || []).push(arguments);
    });
    a[o].l = 1 * (new Date());
    c = i.createElement(r);
    k = i.getElementsByTagName(r)[0];
    c.async = 1;
    c.src = l;
    k.parentNode.insertBefore(c, k);
  })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');

  // We're pretty loopy here, so this makes our lives easier.
  if (!Array.prototype.forEach) {
    Array.prototype.forEach = function (fn, scope) {
      for (var i = 0, len = this.length; i < len; ++i) {
        if (i in this) {
          fn.call(scope, this[i], i, this);
        }
      }
    };
  }

  // Convenience functions
  var returnArg = function (arg) { return arg; };

  var _gaq = window._gaq,
      ga = window[window.GoogleAnalyticsObject],
      rx = {
        actions: /^([\w\d_-]+)?\.?(_track(Event|Pageview|Trans|Social|Timing)|_add(Item|Trans)|_set(CustomVar|Account|DomainName|AllowLinker|SampleRate|CookiePath)?|_link|_require)$/,
        setupActions: /^(.+\.)?_(set(Account|CustomVar|DomainName|AllowLinker|SampleRate|CookiePath)?)$/,
        ecommerceActions: /^(.+\.)?_(add(Trans|Item)|trackTrans)$/,
        writeableSet: /^page|title$/
      }, i, ln;

  var Store = function () {
    this._contents = {};
    this._defaultKey = 't0';
  };
  Store.prototype.get = function (key) {
    key = key || this._defaultKey;
    return this._contents[key];
  };
  Store.prototype.set = function (key, val) {
    key = key || this._defaultKey;
    this._contents[key] = val;
    return this;
  };
  Store.prototype.has = function (key) {
    key = key || this._defaultKey;
    return !!this._contents[key];
  };
  Store.prototype.forEach = function (func, context) {
    for (var key in this._contents) {
      if (this._contents.hasOwnProperty(key)) {
        func.call(context, this._contents[key], key, this._contents);
      }
    }
  };

  // Each spaceship represents a tracker namespace.
  var SpaceShip = function (namespace, account) {
    if (typeof namespace === 'object') {
      tracker = namespace;
      namespace = tracker.get('name');
      account = tracker.get('trackingId');
      return new SpaceShip(namespace, account).initialize();
    }
    this.settings = {};
    this._settings = {};
    this.namespace = namespace;
    this.account = account;
    this.setupQueue = [];
    this.initialized = false;
    this.settings.name = this.namespace;
  };

  SpaceShip.prototype.setAccount = function (uaCode) {
    this.account = uaCode;
    return this;
  };

  SpaceShip.prototype.initialize = function () {
    this.setupQueue.forEach(function (qItem) { qItem(); });
    this.initialized = true;
    return this;
  };

  var Airlock = {};

  Airlock.spaceships = new Store();

  Airlock.readAction = function (actionName) {
    var match = actionName.match(rx.actions);
    return {
      namespace: match[1],
      action: match[2]
    };
  };

  Airlock.initialize = function () {
    var newQ = [], ga = window[window.GoogleAnalyticsObject];

    // loop through uninitialized ga to see if users have implemented a
    // custom "create". If so, add a function to the queue to fire directly
    // after the queue item has been processed.
    if (ga.q) {
      var tempQ = [].concat(ga.q),
          j = 0;

      ga.q.forEach(function (qItem, i) {
        if (typeof qItem[0] !== 'string' || qItem[0] !== 'create') { return; }
        j = j+i+1;
        tempQ.splice(j, 0, [function () {
          var ga = window[window.GoogleAnalyticsObject],
              settings = qItem[qItem.length - 1],
              namespace = typeof settings === 'object' && settings.name ? settings.name : 't0',
              tracker = ga.getByName(namespace),
              spaceship = new SpaceShip(tracker);

          Airlock.dock(spaceship);
        }]);
      });
      ga.q = tempQ;
    }

    // loop through initialized ga to see if users have implemented a
    // custom "create"
    if (ga.P) {
      ga.P.forEach(function (tracker) {
        var spaceship = new SpaceShip(tracker);
        this.dock(spaceship);
      }, this);
    }

    // loop through _gaq to strip out setup calls
    _gaq.forEach(function (qItem) {
      if (typeof qItem === 'function') {
        Airlock.pressurize(qItem);
        return;
      }

      var action = Airlock.readAction(qItem[0]);

      if (rx.setupActions.test(action.action)) {
        // If we find a tracker we have not yet initialized, set it up
        if (!this.spaceships.has(action.namespace)) {
          this.dock(new SpaceShip(action.namespace));
        }
        this.pressurize(qItem, this.spaceships.get(action.namespace));
        return;
      }
      newQ.push(qItem);
    }, this);

    Array.prototype.splice.apply(_gaq, [0, _gaq.length].concat(newQ));

    this.spaceships.forEach(function (spaceship) {
      Airlock.open(spaceship, [
        'create',
        spaceship.account,
        spaceship.settings
      ]);
    });

    // No need to do anything fancy here. Setting an instance method
    // `push()` on the global `_gaq` variable will intercept any calls
    // to `_gaq.prototype.push()`
    _gaq.push = function (args) {
      if (typeof args === 'function') {
        return Airlock.pressurize(args);
      }

      var action = args[0];
      // Ensure users are sending a valid action, otherwise do nothing.
      if (!rx.actions.test(action)) { return; }

      // If the user is trying to setup/send an ecommerce action
      if (rx.ecommerceActions.test(action) && !Airlock.ecommerceInitialized) {
        Airlock.ecommerceInitialized = true;
        ga('require', 'ecommerce', 'ecommerce.js');
      }
      var spaceship = Airlock.spaceships.get(Airlock.readAction(action).namespace);

      if (!spaceship) { return; }

      args = Airlock.pressurize(args, spaceship);
      Airlock.open(spaceship, args);
    };

    _gaq.forEach(_gaq.push.bind(_gaq));
  };

  // Add tracker to Airlock, push settings to ga
  Airlock.dock = function (spaceship) {
    this.spaceships.set(spaceship.namespace, spaceship);
  };

  // Once our arguments are "pressurized", send them off to `ga()`
  Airlock.open = function (spaceship, args) {
    if (!spaceship.account) { return; }
    var create = args[0] === 'create';
    if (args) {
      args[0] = !spaceship.namespace || create ?
        args[0] :
        [spaceship.namespace, args[0]].join('.');

      window[window.GoogleAnalyticsObject].apply(window, args);
      if (create) { spaceship.initialize(); }
    }
  };

  Airlock.pressurize = function (args, spaceship) {
    // break args reference
    args = [].concat(args);

    if (typeof args === 'function') {
      try {
        return args();
      } catch (e) {
        if (console && console.warn) {
          console.warn('AIRLOCK: function passed to _gaq threw error', _gaq[i].toString(), e);
        }
      }
    }

    var conversion = Airlock.conversions[args.slice(0,1)[0].replace(rx.actions, "$2")];
    if (!conversion) { return; }

    if (typeof conversion === 'function') {
      return conversion.apply(spaceship, args);
    }

    var index = {}, out = [],
        i = 0, ln = args.length < conversion.input.length ?
          args.length :
          conversion.input.length;

    // build an index to match input labels to input values
    for (; i < ln; i++) {
      index[conversion.input[i]] = args[i];
    }

    // loop through outputs and permute values as necessary
    i = 0; ln = conversion.output.length;
    conversion.output.forEach(function (output) {
      var val = permute(output, index);
      if (val) {
        out.push(val);
      }
    });
    return out;
  };

  var permute = function (template, data) {
    if (typeof template === 'function') {
      return template(data);
    }
    var templMatch = template.match(/\[\[([a-zA-Z_]+)\]\]/);
    if (templMatch) {
      if (!data[templMatch[1]]) { return; }
      // if there is no input value corresponding to the template identifier
      // (i.e., if this is an optional value), this will return undefined
      // and will be ignored.
      return template.replace(templMatch[0], data[templMatch[1]]);
    }
    return template;
  };

  Airlock.conversions = {
    // Setup actions
    _setAccount: function (uaCode) {
      this.setAccount(uaCode);
    },
    _setSampleRate: function (rate) {
      this.settings.sampleRate = rate;
    },
    _setCookiePath: function (path) {
      this.settings.cookiePath = path;
    },
    _set: function (key, val) {
      this.settings[key.replace('ua', 'cookie')] = val;

      if (rx.writeableSet.test(key)) {
        return ['set', key, val];
      }
    },
    _setDomainName: function (domainName) {
      this._settings.domainName = domainName;
    },
    _setAllowLinker: function (allow) {
      var that = this;
      this.settings.allowLinker = allow;
      this.setupQueue.push(function () {
        ga('require', 'linker');
        Airlock.open(that, ['linker:autoLink', that._settings.domainName]);
      });
    },
    // Enhanced Link Attribution
    _require: function (type){
      if (type === 'inpage_linkid') {
        return ['require','linkid','linkid.js'];
      }
    },

    // Custom Variables
    _setCustomVar: function (slot, name, value) {
      var args = ['set', 'dimension' + slot, value];

      if (this.initialized) { return args; }
      this.setupQueue.push(Airlock.open.bind(Airlock, this, args));
    },

    // Tracking actions
    _trackEvent: {
      input: ['eventCategory', 'eventAction', 'eventLabel', 'eventValue', 'nonInteraction'],
      output: ['send', 'event', returnArg]
    },
    _trackPageview: {
      input: ['pagePath'],
      output: ['send', 'pageview', '[[pagePath]]']
    },
    _trackTiming: {
      input: ['timingCategory', 'timingVar', 'timingValue', 'timingLabel'],
      output: ['send', 'timing', returnArg]
    },
    _trackSocial: {
      input: ['socialNetwork', 'socialAction', 'socialTarget', 'page'],
      output: ['send', 'social', returnArg]
    },

    // Ecommerce
    _addTrans: {
      input: ['id', 'affiliation', 'revenue', 'tax', 'shipping'],
      output: ['ecommerce:addTransaction', returnArg]
    },
    _addItem: {
      input: ['id', 'sku', 'name', 'category', 'price', 'quantity'],
      output: ['ecommerce:addItem', returnArg]
    },
    _trackTrans: {
      input: [],
      output: ['ecommerce:send']
    }
  };

  Airlock.initialize();
  window.Airlock = Airlock;
})(window, document);
<|endoftext|>


<commit_before>import React, {Component} from "react";
import {connect} from "react-redux";
import PropTypes from "prop-types";
import {Button, Col, Grid, Input, Panel, Row} from 'react-bootstrap';
import Typeahead from 'react-bootstrap-typeahead';

import get from "lodash/get";
import filter from "lodash/filter";
import isEmpty from "lodash/isEmpty";
import negate from "lodash/negate";
import parseInt from "lodash/parseInt";
import split from "lodash/split";
import toString from "lodash/toString";

import {changeSearch, fetchSearchResults} from '../../../actions/search';
import {getWorkflowDefs} from '../../../actions/metadata';

const statusList = ['RUNNING', 'COMPLETED', 'FAILED', 'TIMED_OUT', 'TERMINATED', 'PAUSED'];

export function getSearchQuery(query) {
  const searchQuery = get(query, "q", "");
  const entirely = toString(get(query, "f", "true")) === "true";
  const types = filter(split(get(query, "workflowTypes", ""), ","), negate(isEmpty));
  const states = filter(split(get(query, "status", ""), ","), negate(isEmpty));
  const version = filter(split(get(query, "version", ""), ","), negate(isEmpty));
  const cutoff = get(query, "h", "");
  const start = parseInt(get(query, "start", "0"));

  return {query: searchQuery, entirely, types, states, cutoff, start, version};
}

class WorkflowSearch extends Component {
  constructor(props) {
    super(props);

    this.handleQueryChange = this.handleQueryChange.bind(this);
    this.handleEntirelyChange = this.handleEntirelyChange.bind(this);
    this.handleTypesChange = this.handleTypesChange.bind(this);
    this.handleStatesChange = this.handleStatesChange.bind(this);
    this.handleCutoffChange = this.handleCutoffChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleVersionChange = this.handleVersionChange.bind(this);

    // pull out variables from the location onLoad
    const {location: {query}, changeSearch, getWorkflowDefs, fetchSearchResults} = props;

    const search = getSearchQuery(query);

    // update the state
    changeSearch(search);

    // fetch workflow types
    getWorkflowDefs();
  }

  handleQueryChange({target: {value}}) {
    const {search, changeSearch} = this.props;

    changeSearch({...search, query: value});
  }

  handleEntirelyChange({target: {checked}}) {
    const {search, changeSearch} = this.props;

    changeSearch({...search, entirely: checked});
  }

  handleTypesChange(value) {
    const {search, changeSearch} = this.props;

    changeSearch({...search, types: value.map((v) => {
      if(v.customOption){
        return v.label;
      }
      return v;
    })});
  }

  handleStatesChange(value) {
    const {search, changeSearch} = this.props;

    changeSearch({...search, states: value});
  }

  handleCutoffChange({target: {value}}) {
    const {search, changeSearch} = this.props;

    changeSearch({...search, cutoff: value});
  }

  handleVersionChange({target: {value}}){
    const {search, changeSearch} = this.props;
    var versionRegex = /^[0-9]*$/
    if(versionRegex.test(value || "")){
      changeSearch({...search, version: value});
    } else {
      changeSearch({...search, version: ""});
    }
  }

  handleSubmit(e)  {
    const {history, search, changeSearch, fetchSearchResults} = this.props;

    e.preventDefault();

    const types = encodeURIComponent(toString(search.types));
    const states = toString(search.states);
    const version = toString(search.version);

    // always reset start to 0 for a new search
    changeSearch({...search, start: 0});

    const newUrl = `/workflow?q=${search.query}&f=${search.entirely}` +
        `&h=${search.cutoff}&workflowTypes=${types}&status=${states}&start=0&version=${version}`;

    history.pushState(null, newUrl);
    fetchSearchResults();
  }

  render() {
    const {search: {query, entirely, types, states, cutoff, isFetching, version}, workflows} = this.props;

    return <Panel header="Filter Workflows (Press Enter to search)">
        <Grid fluid>
          <form className="commentForm" onSubmit={this.handleSubmit}>
          <Row className="show-grid">
            <Col md={3}>
              <Input type="input" placeholder="Search"
                  value={query} onChange={this.handleQueryChange}
              />

              Free Text Query

                <input type="checkbox" checked={entirely} onChange={this.handleEntirelyChange}/>
                 Search for entire string
            </Col>
            <Col md={4}>
              <Typeahead onChange={this.handleTypesChange} options={workflows}
                         placeholder="Filter by workflow type" allowNew="true" multiple selected={types}/>

              Filter by Workflow Type

            </Col>
            <Col md={1}>
              <Input type="input" placeholder="Version"
                  value={version} onChange={this.handleVersionChange}
              />

              Filter by Version
            </Col>
            <Col md={2}>
              <Typeahead ref="status" onChange={this.handleStatesChange} options={statusList}
                         placeholder="Status" selected={states} multiple/>

              Filter by Workflow Status
            </Col>
            <Col md={2}>
              <Input className="number-input" type="text" groupClassName="inline"
                  value={cutoff} onChange={this.handleCutoffChange}/>

              <Button disabled={isFetching} bsStyle="success" type="submit" className="search-label btn">
                {isFetching &&  || }  Search
              </Button>

              Created (in past hours)
            </Col>
          </Row>
          </form>
        </Grid>
        <form />
      </Panel>
  }
}

WorkflowSearch.propTypes = {
  changeSearch: PropTypes.func.isRequired,
  fetchSearchResults: PropTypes.func.isRequired,
  getWorkflowDefs: PropTypes.func.isRequired,
  history: PropTypes.object.isRequired,
  location: PropTypes.object.isRequired,
  workflows: PropTypes.array.isRequired,
  search: PropTypes.shape({
    isFetching: PropTypes.bool.isRequired,
    query: PropTypes.string.isRequired,
    version: PropTypes.string.isRequired,
    entirely: PropTypes.bool.isRequired,
    types: PropTypes.arrayOf(PropTypes.string).isRequired,
    states: PropTypes.arrayOf(PropTypes.string).isRequired,
    cutoff: PropTypes.string.isRequired
  })
};

const mapDispatchToProps = {changeSearch, fetchSearchResults, getWorkflowDefs};

export default connect(null, mapDispatchToProps)(WorkflowSearch);
<commit_msg>added preload when a search query or workflow type has been filled in<commit_after>import React, {Component} from "react";
import {connect} from "react-redux";
import PropTypes from "prop-types";
import {Button, Col, Grid, Input, Panel, Row} from 'react-bootstrap';
import Typeahead from 'react-bootstrap-typeahead';

import get from "lodash/get";
import filter from "lodash/filter";
import isEmpty from "lodash/isEmpty";
import negate from "lodash/negate";
import parseInt from "lodash/parseInt";
import split from "lodash/split";
import toString from "lodash/toString";

import {changeSearch, fetchSearchResults} from '../../../actions/search';
import {getWorkflowDefs} from '../../../actions/metadata';

const statusList = ['RUNNING', 'COMPLETED', 'FAILED', 'TIMED_OUT', 'TERMINATED', 'PAUSED'];

export function getSearchQuery(query) {
  const searchQuery = get(query, "q", "");
  const entirely = toString(get(query, "f", "true")) === "true";
  const types = filter(split(get(query, "workflowTypes", ""), ","), negate(isEmpty));
  const states = filter(split(get(query, "status", ""), ","), negate(isEmpty));
  const version = filter(split(get(query, "version", ""), ","), negate(isEmpty));
  const cutoff = get(query, "h", "");
  const start = parseInt(get(query, "start", "0"));

  return {query: searchQuery, entirely, types, states, cutoff, start, version};
}

class WorkflowSearch extends Component {
  constructor(props) {
    super(props);

    this.handleQueryChange = this.handleQueryChange.bind(this);
    this.handleEntirelyChange = this.handleEntirelyChange.bind(this);
    this.handleTypesChange = this.handleTypesChange.bind(this);
    this.handleStatesChange = this.handleStatesChange.bind(this);
    this.handleCutoffChange = this.handleCutoffChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleVersionChange = this.handleVersionChange.bind(this);

    // pull out variables from the location onLoad
    const {location: {query}, changeSearch, getWorkflowDefs, fetchSearchResults} = props;

    const search = getSearchQuery(query);

    // update the state
    changeSearch(search);

    if(search !== null && (search.query !== "" || search.types.length !== 0)){
      fetchSearchResults()
    }

    // fetch workflow types
    getWorkflowDefs();
  }

  handleQueryChange({target: {value}}) {
    const {search, changeSearch} = this.props;

    changeSearch({...search, query: value});
  }

  handleEntirelyChange({target: {checked}}) {
    const {search, changeSearch} = this.props;

    changeSearch({...search, entirely: checked});
  }

  handleTypesChange(value) {
    const {search, changeSearch} = this.props;

    changeSearch({...search, types: value.map((v) => {
      if(v.customOption){
        return v.label;
      }
      return v;
    })});
  }

  handleStatesChange(value) {
    const {search, changeSearch} = this.props;

    changeSearch({...search, states: value});
  }

  handleCutoffChange({target: {value}}) {
    const {search, changeSearch} = this.props;

    changeSearch({...search, cutoff: value});
  }

  handleVersionChange({target: {value}}){
    const {search, changeSearch} = this.props;
    var versionRegex = /^[0-9]*$/
    if(versionRegex.test(value || "")){
      changeSearch({...search, version: value});
    } else {
      changeSearch({...search, version: ""});
    }
  }

  handleSubmit(e)  {
    const {history, search, changeSearch, fetchSearchResults} = this.props;

    e.preventDefault();

    const types = encodeURIComponent(toString(search.types));
    const states = toString(search.states);
    const version = toString(search.version);

    // always reset start to 0 for a new search
    changeSearch({...search, start: 0});

    const newUrl = `/workflow?q=${search.query}&f=${search.entirely}` +
        `&h=${search.cutoff}&workflowTypes=${types}&status=${states}&start=0&version=${version}`;

    history.pushState(null, newUrl);
    fetchSearchResults();
  }

  render() {
    const {search: {query, entirely, types, states, cutoff, isFetching, version}, workflows} = this.props;

    return <Panel header="Filter Workflows (Press Enter to search)">
        <Grid fluid>
          <form className="commentForm" onSubmit={this.handleSubmit}>
          <Row className="show-grid">
            <Col md={3}>
              <Input type="input" placeholder="Search"
                  value={query} onChange={this.handleQueryChange}
              />

              Free Text Query

                <input type="checkbox" checked={entirely} onChange={this.handleEntirelyChange}/>
                 Search for entire string
            </Col>
            <Col md={4}>
              <Typeahead onChange={this.handleTypesChange} options={workflows}
                         placeholder="Filter by workflow type" allowNew="true" multiple selected={types}/>

              Filter by Workflow Type

            </Col>
            <Col md={1}>
              <Input type="input" placeholder="Version"
                  value={version} onChange={this.handleVersionChange}
              />

              Filter by Version
            </Col>
            <Col md={2}>
              <Typeahead ref="status" onChange={this.handleStatesChange} options={statusList}
                         placeholder="Status" selected={states} multiple/>

              Filter by Workflow Status
            </Col>
            <Col md={2}>
              <Input className="number-input" type="text" groupClassName="inline"
                  value={cutoff} onChange={this.handleCutoffChange}/>

              <Button disabled={isFetching} bsStyle="success" type="submit" className="search-label btn">
                {isFetching &&  || }  Search
              </Button>

              Created (in past hours)
            </Col>
          </Row>
          </form>
        </Grid>
        <form />
      </Panel>
  }
}

WorkflowSearch.propTypes = {
  changeSearch: PropTypes.func.isRequired,
  fetchSearchResults: PropTypes.func.isRequired,
  getWorkflowDefs: PropTypes.func.isRequired,
  history: PropTypes.object.isRequired,
  location: PropTypes.object.isRequired,
  workflows: PropTypes.array.isRequired,
  search: PropTypes.shape({
    isFetching: PropTypes.bool.isRequired,
    query: PropTypes.string.isRequired,
    version: PropTypes.string.isRequired,
    entirely: PropTypes.bool.isRequired,
    types: PropTypes.arrayOf(PropTypes.string).isRequired,
    states: PropTypes.arrayOf(PropTypes.string).isRequired,
    cutoff: PropTypes.string.isRequired
  })
};

const mapDispatchToProps = {changeSearch, fetchSearchResults, getWorkflowDefs};

export default connect(null, mapDispatchToProps)(WorkflowSearch);
<|endoftext|>