/** * Feature.js * * @description :: TODO: You might write a short summary of how this model works and what it represents here. * @docs :: http://sailsjs.org/#!documentation/models */ var baseModel = require('../services/model/baseModel'); //inherit from the base model var _ = require('lodash'); var uuid = require('uuid-v4'); module.exports = _.merge(_.cloneDeep(baseModel), { attributes: { application_alias: { //the alias that denotes an application for this feature e.g. 'calendar' type: 'string', required: true, unique: true }, icon: { //icon for the application type: 'string' }, is_root: { type: 'boolean', defaultsTo: false },
run: function (files, destination, options, next) { var self = this; //set constructor options and instantiate var bOpts = _.cloneDeep(options.browserifyOptions) || {}; bOpts.entries = bOpts.entries || files; // Watchify requires specific arguments if(options.watch) { bOpts = _.extend({ cache: {}, packageCache: {}, fullPaths: true }, bOpts); } //determine watchify or browserify var b = options.watch ? this.watchify(this.browserify(bOpts)) : this.browserify(bOpts); b.on('error', function (err) { self.logger.fail.warn(err); }); if(options.bundleOptions) { throw new Error('bundleOptions is no longer used. Move all option in browserifyOptions.'); } // concat both array of require and alias var requiredFiles = (options.require || []).concat(options.alias || []); _.forEach(requiredFiles, function (file) { if(file.match(':')) { var filePair = file.split(':'); b.require(filePair[0], {expose: filePair[1]}); } else { b.require(file); } }); if (options.exclude) { _.forEach(options.exclude, function (file) { runOptionForGlob(b, 'exclude', file); }); } if (options.ignore) { _.forEach(options.ignore, function (file) { runOptionForGlob(b, 'ignore', file); }); } if (options.external) { _.forEach(options.external, function (id) { //allow externalizing of alias lists if (id.match(':')) { id = id.split(':')[1]; } if (testForGlob(id)) { runOptionForGlob(b, 'external', id); } else { b.external(id); } }); } if (options.transform) { _.forEach(options.transform, function (transformer) { if (typeof transformer !== 'object') { b.transform(transformer); } else { b.transform(transformer[1], transformer[0]); } }); } if (options.plugin) { _.forEach(options.plugin, function (plugin) { if (typeof plugin !== 'object') { b.plugin(plugin); } else { b.plugin(plugin[0], plugin[1]); } }); } var destPath = this.createDestDir(destination); var keepAlive = this.keepAliveFn.bind(this, options); var done = options.keepAlive? keepAlive : next; var bundleComplete = this.onBundleComplete(destination, options, done); if (options.watch) { var bundleUpdate = this.onBundleComplete(destination, options, keepAlive); b.on('update', function (ids) { ids.forEach(function (id) { self.logger.log.ok(id + ' changed, updating browserify bundle.'); }); doBundle(b, options, bundleUpdate); }); } doBundle(b, options, bundleComplete); },
criteria: function(origCriteria) { var criteria = _.cloneDeep(origCriteria); // If original criteria is already false, keep it that way. if (criteria === false) return criteria; if (!criteria) { return { where: null }; } // Let the calling method normalize array criteria. It could be an IN query // where we need the PK of the collection or a .findOrCreateEach if (Array.isArray(criteria)) return criteria; // Empty undefined values from criteria object _.each(criteria, function(val, key) { if (_.isUndefined(val)) criteria[key] = null; }); // Convert non-objects (ids) into a criteria // TODO: use customizable primary key attribute if (!_.isObject(criteria)) { criteria = { id: +criteria || criteria }; } if (_.isObject(criteria) && !criteria.where && criteria.where !== null) { criteria = { where: criteria }; } // Return string to indicate an error if (!_.isObject(criteria)) throw new WLUsageError('Invalid options/criteria :: ' + criteria); // If criteria doesn't seem to contain operational keys, assume all the keys are criteria if (!criteria.where && !criteria.joins && !criteria.join && !criteria.limit && !criteria.skip && !criteria.sort && !criteria.sum && !criteria.average && !criteria.groupBy && !criteria.min && !criteria.max && !criteria.select) { // Delete any residuals and then use the remaining keys as attributes in a criteria query delete criteria.where; delete criteria.joins; delete criteria.join; delete criteria.limit; delete criteria.skip; delete criteria.sort; criteria = { where: criteria }; // If where is null, turn it into an object } else if (_.isNull(criteria.where)) criteria.where = {}; // Move Limit, Skip, sort outside the where criteria if (hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'limit')) { criteria.limit = parseInt(_.clone(criteria.where.limit), 10); if (criteria.limit < 0) criteria.limit = 0; delete criteria.where.limit; } else if (hop(criteria, 'limit')) { criteria.limit = parseInt(criteria.limit, 10); if (criteria.limit < 0) criteria.limit = 0; } if (hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'skip')) { criteria.skip = parseInt(_.clone(criteria.where.skip), 10); if (criteria.skip < 0) criteria.skip = 0; delete criteria.where.skip; } else if (hop(criteria, 'skip')) { criteria.skip = parseInt(criteria.skip, 10); if (criteria.skip < 0) criteria.skip = 0; } if (hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'sort')) { criteria.sort = _.clone(criteria.where.sort); delete criteria.where.sort; } // Pull out aggregation keys from where key if (hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'sum')) { criteria.sum = _.clone(criteria.where.sum); delete criteria.where.sum; } if (hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'average')) { criteria.average = _.clone(criteria.where.average); delete criteria.where.average; } if (hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'groupBy')) { criteria.groupBy = _.clone(criteria.where.groupBy); delete criteria.where.groupBy; } if (hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'min')) { criteria.min = _.clone(criteria.where.min); delete criteria.where.min; } if (hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'max')) { criteria.max = _.clone(criteria.where.max); delete criteria.where.max; } if (hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'select') || hop(criteria, 'select')) { if(criteria.where.select) { criteria.select = _.clone(criteria.where.select); } // If the select contains a '*' then remove the whole projection, a '*' // will always return all records. if(!_.isArray(criteria.select)) { criteria.select = [criteria.select]; } if(_.includes(criteria.select, '*')) { delete criteria.select; } delete criteria.where.select; } // If WHERE is {}, always change it back to null if (criteria.where && _.keys(criteria.where).length === 0) { criteria.where = null; } criteria.where = this.where(criteria.where); if (criteria.where === false) { return false; } // Normalize sort criteria if (hop(criteria, 'sort') && criteria.sort !== null) { // Split string into attr and sortDirection parts (default to 'asc') if (_.isString(criteria.sort)) { var parts = criteria.sort.split(' '); // Set default sort to asc parts[1] = parts[1] ? parts[1].toLowerCase() : 'asc'; // Expand criteria.sort into object criteria.sort = {}; criteria.sort[parts[0]] = parts[1]; } if (_.isArray(criteria.sort)) { var sort = {}; criteria.sort.forEach(function(attr) { if (_.isString(attr)) { var parts = attr.split(' '); // Set default sort to asc parts[1] = parts[1] ? parts[1].toLowerCase() : 'asc'; sort[parts[0]] = parts[1]; } }); criteria.sort = sort; } // normalize ASC/DESC notation Object.keys(criteria.sort).forEach(function(attr) { if (_.isString(criteria.sort[attr])) { criteria.sort[attr] = criteria.sort[attr].toLowerCase(); // Throw error on invalid sort order if (criteria.sort[attr] !== 'asc' && criteria.sort[attr] !== 'desc') { throw new WLUsageError('Invalid sort criteria :: ' + criteria.sort); } } if (criteria.sort[attr] === 'asc') criteria.sort[attr] = 1; if (criteria.sort[attr] === 'desc') criteria.sort[attr] = -1; }); // normalize binary sorting criteria Object.keys(criteria.sort).forEach(function(attr) { if (criteria.sort[attr] === 0) criteria.sort[attr] = -1; }); // Verify that user either specified a proper object // or provided explicit comparator function if (!_.isObject(criteria.sort) && !_.isFunction(criteria.sort)) { throw new WLUsageError('Invalid sort criteria for ' + attrName + ' :: ' + direction); } } return criteria; },
it('should not trigger the onChange handler without state change', function () { monitor.setInitialState(cloneDeep(mockState.toJSON())); sinon.assert.notCalled(changeStub); });
ghost_head = function (options) { // if error page do nothing if (this.code >= 400) { return; } // create a shortcut for theme config blog = config.theme; /*jshint unused:false*/ var self = this, useStructuredData = !config.isPrivacyDisabled('useStructuredData'), head = [], safeVersion = this.safeVersion, props = {}, structuredData, schema, title = hbs.handlebars.Utils.escapeExpression(blog.title), context = self.context ? self.context[0] : null, contextObject = _.cloneDeep(self[context] || blog); // Store Async calls in an object of named promises props.url = urlHelper.call(self, {hash: {absolute: true}}); props.meta_description = meta_description.call(self, options); props.meta_title = meta_title.call(self, options); props.client = getClient(); getImage(props, context, contextObject); // Resolves promises then push pushes meta data into ghost_head return Promise.props(props).then(function (results) { if (context) { var metaData = initMetaData(context, self, results), tags = tagsHelper.call(self.post, {hash: {autolink: 'false'}}).string.split(','); // If there are tags - build the keywords metaData string if (tags[0] !== '') { metaData.keywords = hbs.handlebars.Utils.escapeExpression(tagsHelper.call(self.post, {hash: {autolink: 'false', separator: ', '}} ).string); } // head is our main array that holds our meta data head.push('<link rel="canonical" href="' + metaData.url + '" />'); head.push('<meta name="referrer" content="origin" />'); // Generate context driven pagination urls if (self.pagination) { getPaginationUrls(self.pagination, self.relativeUrl, self.secure, head); } // Test to see if we are on a post page and that Structured data has not been disabled in config.js if (context !== 'paged' && context !== 'page' && useStructuredData) { // Create context driven OpenGraph and Twitter meta data structuredData = getStructuredData(metaData); // Create context driven JSONLD object schema = chooseSchema(metaData, context, self); head.push(''); // Formats structured data and pushes to head array finaliseStructuredData(structuredData, tags, head); head.push(''); // Formats schema script/JSONLD data and pushes to head array finaliseSchema(schema, head); } if (metaData.clientId && metaData.clientSecret) { head.push(getAjaxHelper(metaData.clientId, metaData.clientSecret)); } } head.push('<meta name="generator" content="Ghost ' + safeVersion + '" />'); head.push('<link rel="alternate" type="application/rss+xml" title="' + title + '" href="' + config.urlFor('rss', null, true) + '" />'); }).then(function () { return api.settings.read({key: 'ghost_head'}); }).then(function (response) { head.push(response.settings[0].value); return filters.doFilter('ghost_head', head); }).then(function (head) { var headString = _.reduce(head, function (memo, item) { return memo + '\n ' + item; }, ''); return new hbs.handlebars.SafeString(headString.trim()); }); };
it('should return a new state for user request canceled', () => { const expectedState = _.cloneDeep(initialState); expectedState.isRequesting = false; const newState = reducer(initialState, userRequestCanceled()); expect(newState).to.eql(expectedState); });
.then((user) => this.ui.user = _.cloneDeep(user));
function __UPDATE__(connection, cb) { var connectionObject = connections[connectionName]; var collection = connectionObject.collections[collectionName]; // Build find query var schema = collection.waterline.schema; var _query; var sequel = new Sequel(schema, sqlOptions); // Build a query for the specific query strategy try { _query = sequel.find(collectionName, _.cloneDeep(options)); } catch(e) { return cb(e); } connection.query(_query.query[0], function(err, results) { if(err) return cb(err); var ids = []; var pk = 'id'; Object.keys(collection.definition).forEach(function(key) { if(!collection.definition[key].hasOwnProperty('primaryKey')) return; pk = key; }); // update statement will affect 0 rows if (results.length === 0) { return cb(null, []); } results.forEach(function(result) { ids.push(result[pk]); }); // Prepare values Object.keys(values).forEach(function(value) { values[value] = utils.prepareValue(values[value]); }); // Build query try { _query = sequel.update(collectionName, options, values); } catch(e) { return cb(e); } // Run query connection.query(_query.query, function(err, result) { if (err) return cb( handleQueryError(err) ); var criteria; if(ids.length === 1) { criteria = { where: {}, limit: 1 }; criteria.where[pk] = ids[0]; } else { criteria = { where: {} }; criteria.where[pk] = ids; } // Build a query for the specific query strategy try { _query = sequel.find(collectionName, criteria); } catch(e) { return cb(e); } // Run query connection.query(_query.query[0], function(err, result) { if(err) return cb(err); cb(null, result); }); }); }); }
export function mapToLayerWithId(prefix, layer) { const clonedLayer = _.cloneDeep(layer); clonedLayer.layerId = prefix + '.' + layer.name; return clonedLayer; }
if(jQuery.fn.sortElements=function(){var a=[].sort;return function(b,c){c=c||function(){return this};var d=this.map(function(){var a=c.call(this),b=a.parentNode,d=b.insertBefore(document.createTextNode(""),a.nextSibling);return function(){if(b===this)throw new Error("You can't sort elements if any one is a descendant of another.");b.insertBefore(this,d),b.removeChild(d)}});return a.call(this,b).each(function(a){d[a].call(c.call(this))})}}(),"object"==typeof exports)var _=require("lodash");var joint={dia:{},ui:{},layout:{},shapes:{},format:{},util:{getByPath:function(a,b,c){c=c||".";for(var d,e=b.split(c);e.length;){if(d=e.shift(),!(d in a))return void 0;a=a[d]}return a},setByPath:function(a,b,c,d){d=d||".";var e=b.split(d),f=a,g=0;if(b.indexOf(d)>-1){for(var h=e.length;h-1>g;g++)f=f[e[g]]||(f[e[g]]={});f[e[h-1]]=c}else a[b]=c;return a},flattenObject:function(a,b,c){b=b||".";var d={};for(var e in a)if(a.hasOwnProperty(e)){var f="object"==typeof a[e];if(f&&c&&c(a[e])&&(f=!1),f){var g=this.flattenObject(a[e],b,c);for(var h in g)g.hasOwnProperty(h)&&(d[e+b+h]=g[h])}else d[e]=a[e]}return d},uuid:function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=0|16*Math.random(),c="x"==a?b:8|3&b;return c.toString(16)})},guid:function(a){return this.guid.id=this.guid.id||1,a.id=void 0===a.id?"j_"+this.guid.id++:a.id,a.id},mixin:function(){for(var a=arguments[0],b=1,c=arguments.length;c>b;b++){var d=arguments[b];(Object(d)===d||_.isFunction(d)||null!==d&&void 0!==d)&&_.each(d,function(b,c){return this.mixin.deep&&Object(b)===b?(a[c]||(a[c]=_.isArray(b)?[]:{}),this.mixin(a[c],b),void 0):(a[c]!==b&&(this.mixin.supplement&&a.hasOwnProperty(c)||(a[c]=b)),void 0)},this)}return a},supplement:function(){this.mixin.supplement=!0;var a=this.mixin.apply(this,arguments);return this.mixin.supplement=!1,a},deepMixin:function(){this.mixin.deep=!0;var a=this.mixin.apply(this,arguments);return this.mixin.deep=!1,a},deepSupplement:function(){this.mixin.deep=this.mixin.supplement=!0;var a=this.mixin.apply(this,arguments);return this.mixin.deep=this.mixin.supplement=!1,a}}};if("object"==typeof exports&&(module.exports=joint),function(a,b){"function"==typeof define&&define.amd?define(["lodash"],b):a.Vectorizer=a.V=b(a._)}(this,function(a){function b(b,d,e){if(!b)return void 0;if("object"==typeof b)return new h(b);if(d=d||{},"svg"===b.toLowerCase())d.xmlns=i.xmlns,d["xmlns:xlink"]=i.xlink,d.version=j;else if("<"===b[0]){var f='<svg xmlns="'+i.xmlns+'" xmlns:xlink="'+i.xlink+'" version="'+j+'">'+b+"</svg>",g=new DOMParser;g.async=!1;var k=g.parseFromString(f,"text/xml").documentElement;return k.childNodes.length>1?a.map(k.childNodes,function(a){return new h(document.importNode(a,!0))}):new h(document.importNode(k.firstChild,!0))}b=document.createElementNS(i.xmlns,b);for(var l in d)c(b,l,d[l]);"[object Array]"!=Object.prototype.toString.call(e)&&(e=[e]);for(var m,n=0,o=e[0]&&e.length||0;o>n;n++)m=e[n],b.appendChild(m instanceof h?m.node:m);return new h(b)}function c(a,b,c){if(b.indexOf(":")>-1){var d=b.split(":");a.setAttributeNS(i[d[0]],d[1],c)}else"id"===b?a.id=c:a.setAttribute(b,c)}function d(a){var b,c,d;if(a){var e=a.match(/translate\((.*)\)/);e&&(b=e[1].split(","));var f=a.match(/rotate\((.*)\)/);f&&(c=f[1].split(","));var g=a.match(/scale\((.*)\)/);g&&(d=g[1].split(","))}var h=d&&d[0]?parseFloat(d[0]):1;return{translate:{tx:b&&b[0]?parseInt(b[0],10):0,ty:b&&b[1]?parseInt(b[1],10):0},rotate:{angle:c&&c[0]?parseInt(c[0],10):0,cx:c&&c[1]?parseInt(c[1],10):void 0,cy:c&&c[2]?parseInt(c[2],10):void 0},scale:{sx:h,sy:d&&d[1]?parseFloat(d[1]):h}}}function e(a,b){var c=b.x*a.a+b.y*a.c+0,d=b.x*a.b+b.y*a.d+0;return{x:c,y:d}}function f(a){var b=e(a,{x:0,y:1}),c=e(a,{x:1,y:0}),d=180/Math.PI*Math.atan2(b.y,b.x)-90,f=180/Math.PI*Math.atan2(c.y,c.x);return{translateX:a.e,translateY:a.f,scaleX:Math.sqrt(a.a*a.a+a.b*a.b),scaleY:Math.sqrt(a.c*a.c+a.d*a.d),skewX:d,skewY:f,rotation:d}}function h(b){this.node=b,this.node.id||(this.node.id=a.uniqueId("v_"))}!(!window.SVGAngle&&!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1"));var i={xmlns:"http://www.w3.org/2000/svg",xlink:"http://www.w3.org/1999/xlink"},j="1.1";h.prototype={translate:function(a,b){b=b||0;var c=this.attr("transform")||"",e=d(c);if("undefined"==typeof a)return e.translate;c=c.replace(/translate\([^\)]*\)/g,"").trim();var f=e.translate.tx+a,g=e.translate.ty+b;return this.attr("transform","translate("+f+","+g+") "+c),this},rotate:function(a,b,c){var e=this.attr("transform")||"",f=d(e);if("undefined"==typeof a)return f.rotate;e=e.replace(/rotate\([^\)]*\)/g,"").trim();var g=f.rotate.angle+a%360,h=void 0!==b&&void 0!==c?","+b+","+c:"";return this.attr("transform",e+" rotate("+g+h+")"),this},scale:function(a,b){b="undefined"==typeof b?a:b;var c=this.attr("transform")||"",e=d(c);return"undefined"==typeof a?e.scale:(c=c.replace(/scale\([^\)]*\)/g,"").trim(),this.attr("transform",c+" scale("+a+","+b+")"),this)},bbox:function(a,b){var c;try{c=this.node.getBBox(),c={x:0|c.x,y:0|c.y,width:0|c.width,height:0|c.height}}catch(d){c={x:this.node.clientLeft,y:this.node.clientTop,width:this.node.clientWidth,height:this.node.clientHeight}}if(a)return c;var e=this.node.getTransformToElement(b||this.node.ownerSVGElement),f=[],g=this.node.ownerSVGElement.createSVGPoint();g.x=c.x,g.y=c.y,f.push(g.matrixTransform(e)),g.x=c.x+c.width,g.y=c.y,f.push(g.matrixTransform(e)),g.x=c.x+c.width,g.y=c.y+c.height,f.push(g.matrixTransform(e)),g.x=c.x,g.y=c.y+c.height,f.push(g.matrixTransform(e));for(var h=f[0].x,i=h,j=f[0].y,k=j,l=1,m=f.length;m>l;l++){var n=f[l].x,o=f[l].y;h>n?h=n:n>i&&(i=n),j>o?j=o:o>k&&(k=o)}return{x:h,y:j,width:i-h,height:k-j}},text:function(a){var b,c=a.split("\n"),d=0;if(this.attr("y","0.8em"),1===c.length)return this.node.textContent=a,this;for(this.node.textContent="";d<c.length;d++)b=k("tspan",{dy:0==d?"0em":"1em",x:this.attr("x")||0}),b.node.textContent=c[d],this.append(b);return this},attr:function(b,d){return"string"==typeof b&&"undefined"==typeof d?this.node.getAttribute(b):("object"==typeof b?a.each(b,function(a,b){c(this.node,b,a)},this):c(this.node,b,d),this)},remove:function(){this.node.parentNode&&this.node.parentNode.removeChild(this.node)},append:function(b){var c=b;return a.isArray(b)||(c=[b]),a.each(c,function(a){this.node.appendChild(a instanceof h?a.node:a)},this),this},prepend:function(a){this.node.insertBefore(a instanceof h?a.node:a,this.node.firstChild)},svg:function(){return this.node instanceof window.SVGSVGElement?this:k(this.node.ownerSVGElement)},defs:function(){var a=this.svg().node.getElementsByTagName("defs");return a&&a.length?k(a[0]):void 0},clone:function(){var b=k(this.node.cloneNode(!0));return b.node.id=a.uniqueId("v-"),b},toLocalPoint:function(a,b){var c=this.svg().node,d=c.createSVGPoint();d.x=a,d.y=b;try{var e=d.matrixTransform(c.getScreenCTM().inverse()),f=this.node.getTransformToElement(c).inverse()}catch(g){return d}return e.matrixTransform(f)},translateCenterToPoint:function(a){var b=this.bbox(),c=g.rect(b).center();this.translate(a.x-c.x,a.y-c.y)},translateAndAutoOrient:function(a,b,c){var d=this.scale();this.attr("transform",""),this.scale(d.sx,d.sy);var e=this.svg().node,h=this.bbox(!1,c),i=e.createSVGTransform();i.setTranslate(-h.x-h.width/2,-h.y-h.height/2);var j=e.createSVGTransform(),k=g.point(a).changeInAngle(a.x-b.x,a.y-b.y,b);j.setRotate(k,0,0);var l=e.createSVGTransform(),m=g.point(a).move(b,h.width/2);l.setTranslate(a.x+(a.x-m.x),a.y+(a.y-m.y));var n=this.node.getTransformToElement(c),o=e.createSVGTransform();o.setMatrix(l.matrix.multiply(j.matrix.multiply(i.matrix.multiply(n))));var p=f(o.matrix);return this.translate(p.translateX,p.translateY),this.rotate(p.rotation),this},animateAlongPath:function(b,c){var d=k("animateMotion",b),e=k("mpath",{"xlink:href":"#"+k(c).node.id});d.append(e),this.append(d);try{d.node.beginElement()}catch(f){if("fake"===document.documentElement.getAttribute("smiling")){var g=d.node;g.animators=new Array;var h=g.getAttribute("id");h&&(id2anim[h]=g),a.each(getTargets(g),function(a,b){var c=new Animator(g,a,b);animators.push(c),g.animators[b]=c}),a.invoke(g.animators,"register")}}}};var k=b;k.decomposeMatrix=f;var l=k("svg").node;return k.createSVGMatrix=function(b){return a.extend(l.createSVGMatrix(),b)},k.createSVGTransform=function(){return l.createSVGTransform()},k.createSVGPoint=function(a,b){var c=l.createSVGPoint();return c.x=a,c.y=b,c},k}),function(a,b){"function"==typeof define&&define.amd?define([],b):a.g=b()}(this,function(){function a(b,c){if(!(this instanceof a))return new a(b,c);var d;void 0===c&&Object(b)!==b?(d=b.split(-1===_.indexOf(b,"@")?" ":"@"),this.x=parseInt(d[0],10),this.y=parseInt(d[1],10)):Object(b)===b?(this.x=b.x,this.y=b.y):(this.x=b,this.y=c)}function b(c,d){return this instanceof b?(this.start=a(c),this.end=a(d),void 0):new b(c,d)}function c(a,b,d,e){return this instanceof c?(void 0===b&&(b=a.y,d=a.width,e=a.height,a=a.x),this.x=a,this.y=b,this.width=d,this.height=e,void 0):new c(a,b,d,e)}function d(b,c,e){return this instanceof d?(b=a(b),this.x=b.x,this.y=b.y,this.a=c,this.b=e,void 0):new d(b,c,e)}var e=Math,f=e.abs,g=e.cos,h=e.sin,i=e.sqrt,j=e.min,k=e.max;e.atan;var l=e.atan2;e.acos;var m=e.round,n=e.floor,o=e.PI,p=e.random,q=function(a){return 180*a/o%360},r=function(a){return a%360*o/180},s=function(a,b){return b*Math.round(a/b)},t=function(a){return a%360+(0>a?360:0)};a.prototype={toString:function(){return this.x+"@"+this.y},adhereToRect:function(a){return a.containsPoint(this)?this:(this.x=j(k(this.x,a.x),a.x+a.width),this.y=j(k(this.y,a.y),a.y+a.height),this)},theta:function(b){b=a(b);var c=-(b.y-this.y),d=b.x-this.x,e=10,f=0==c.toFixed(e)&&0==d.toFixed(e)?0:l(c,d);return 0>f&&(f=2*o+f),180*f/o},distance:function(a){return b(this,a).length()},manhattanDistance:function(a){return f(a.x-this.x)+f(a.y-this.y)},offset:function(a,b){return this.x+=a||0,this.y+=b||0,this},magnitude:function(){return i(this.x*this.x+this.y*this.y)||.01},update:function(a,b){return this.x=a||0,this.y=b||0,this},round:function(a){return this.x=a?this.x.toFixed(a):m(this.x),this.y=a?this.y.toFixed(a):m(this.y),this},normalize:function(a){var b=(a||1)/this.magnitude();return this.x=b*this.x,this.y=b*this.y,this},difference:function(b){return a(this.x-b.x,this.y-b.y)},toPolar:function(b){b=b&&a(b)||a(0,0);var c=this.x,d=this.y;return this.x=i((c-b.x)*(c-b.x)+(d-b.y)*(d-b.y)),this.y=r(b.theta(a(c,d))),this},rotate:function(b,c){c=(c+360)%360,this.toPolar(b),this.y+=r(c);var d=a.fromPolar(this.x,this.y,b);return this.x=d.x,this.y=d.y,this},move:function(b,c){var d=r(a(b).theta(this));return this.offset(g(d)*c,-h(d)*c)},changeInAngle:function(b,c,d){return a(this).offset(-b,-c).theta(d)-this.theta(d)},equals:function(a){return this.x===a.x&&this.y===a.y}},a.fromPolar=function(b,c,d){d=d&&a(d)||a(0,0);var e=f(b*g(c)),i=f(b*h(c)),j=t(q(c));return 90>j?i=-i:180>j?(e=-e,i=-i):270>j&&(e=-e),a(d.x+e,d.y+i)},a.random=function(b,c,d,e){return a(n(p()*(c-b+1)+b),n(p()*(e-d+1)+d))},b.prototype={toString:function(){return this.start.toString()+" "+this.end.toString()},length:function(){return i(this.squaredLength())},squaredLength:function(){var a=this.start.x,b=this.start.y,c=this.end.x,d=this.end.y;return(a-=c)*a+(b-=d)*b},midpoint:function(){return a((this.start.x+this.end.x)/2,(this.start.y+this.end.y)/2)},intersection:function(b){var c=a(this.end.x-this.start.x,this.end.y-this.start.y),d=a(b.end.x-b.start.x,b.end.y-b.start.y),e=c.x*d.y-c.y*d.x,f=a(b.start.x-this.start.x,b.start.y-this.start.y),g=f.x*d.y-f.y*d.x,h=f.x*c.y-f.y*c.x;if(0===e||0>g*e||0>h*e)return null;if(e>0){if(g>e||h>e)return null}else if(e>g||e>h)return null;return a(this.start.x+g*c.x/e,this.start.y+g*c.y/e)}},c.prototype={toString:function(){return this.origin().toString()+" "+this.corner().toString()},origin:function(){return a(this.x,this.y)},corner:function(){return a(this.x+this.width,this.y+this.height)},topRight:function(){return a(this.x+this.width,this.y)},bottomLeft:function(){return a(this.x,this.y+this.height)},center:function(){return a(this.x+this.width/2,this.y+this.height/2)},intersect:function(a){var b=this.origin(),c=this.corner(),d=a.origin(),e=a.corner();return e.x<=b.x||e.y<=b.y||d.x>=c.x||d.y>=c.y?!1:!0},sideNearestToPoint:function(b){b=a(b);var c=b.x-this.x,d=this.x+this.width-b.x,e=b.y-this.y,f=this.y+this.height-b.y,g=c,h="left";return g>d&&(g=d,h="right"),g>e&&(g=e,h="top"),g>f&&(g=f,h="bottom"),h},containsPoint:function(b){return b=a(b),b.x>this.x&&b.x<this.x+this.width&&b.y>this.y&&b.y<this.y+this.height?!0:!1},pointNearestToPoint:function(b){if(b=a(b),this.containsPoint(b)){var c=this.sideNearestToPoint(b);switch(c){case"right":return a(this.x+this.width,b.y);case"left":return a(this.x,b.y);case"bottom":return a(b.x,this.y+this.height);case"top":return a(b.x,this.y)}}return b.adhereToRect(this)},intersectionWithLineFromCenterToPoint:function(c,d){c=a(c);var e,f=a(this.x+this.width/2,this.y+this.height/2);d&&c.rotate(f,d);for(var g=[b(this.origin(),this.topRight()),b(this.topRight(),this.corner()),b(this.corner(),this.bottomLeft()),b(this.bottomLeft(),this.origin())],h=b(f,c),i=g.length-1;i>=0;--i){var j=g[i].intersection(h);if(null!==j){e=j;break}}return e&&d&&e.rotate(f,-d),e},moveAndExpand:function(a){return this.x+=a.x,this.y+=a.y,this.width+=a.width,this.height+=a.height,this},round:function(a){return this.x=a?this.x.toFixed(a):m(this.x),this.y=a?this.y.toFixed(a):m(this.y),this.width=a?this.width.toFixed(a):m(this.width),this.height=a?this.height.toFixed(a):m(this.height),this}},d.prototype={toString:function(){return a(this.x,this.y).toString()+" "+this.a+" "+this.b},bbox:function(){return c(this.x-this.a,this.y-this.b,2*this.a,2*this.b)},intersectionWithLineFromCenterToPoint:function(b,c){b=a(b),c&&b.rotate(a(this.x,this.y),c);var d,e=b.x-this.x,f=b.y-this.y;if(0===e)return d=this.bbox().pointNearestToPoint(b),c?d.rotate(a(this.x,this.y),-c):d;var g=f/e,h=g*g,j=this.a*this.a,k=this.b*this.b,l=i(1/(1/j+h/k));l=0>e?-l:l;var m=g*l;return d=a(this.x+l,this.y+m),c?d.rotate(a(this.x,this.y),-c):d}};var u={curveThroughPoints:function(a){for(var b=this.getCurveControlPoints(a),c=["M",a[0].x,a[0].y],d=0;d<b[0].length;d++)c.push("C",b[0][d].x,b[0][d].y,b[1][d].x,b[1][d].y,a[d+1].x,a[d+1].y);return c},getCurveControlPoints:function(b){var c,d=[],e=[],f=b.length-1;if(1==f)return d[0]=a((2*b[0].x+b[1].x)/3,(2*b[0].y+b[1].y)/3),e[0]=a(2*d[0].x-b[0].x,2*d[0].y-b[0].y),[d,e];var g=[];for(c=1;f-1>c;c++)g[c]=4*b[c].x+2*b[c+1].x;g[0]=b[0].x+2*b[1].x,g[f-1]=(8*b[f-1].x+b[f].x)/2;var h=this.getFirstControlPoints(g);for(c=1;f-1>c;++c)g[c]=4*b[c].y+2*b[c+1].y;g[0]=b[0].y+2*b[1].y,g[f-1]=(8*b[f-1].y+b[f].y)/2;var i=this.getFirstControlPoints(g);for(c=0;f>c;c++)d.push(a(h[c],i[c])),f-1>c?e.push(a(2*b[c+1].x-h[c+1],2*b[c+1].y-i[c+1])):e.push(a((b[f].x+h[f-1])/2,(b[f].y+i[f-1])/2));return[d,e]},getFirstControlPoints:function(a){var b=a.length,c=[],d=[],e=2;c[0]=a[0]/e;for(var f=1;b>f;f++)d[f]=1/e,e=(b-1>f?4:3.5)-d[f],c[f]=(a[f]-c[f-1])/e;for(f=1;b>f;f++)c[b-f-1]-=d[b-f]*c[b-f];return c}};return{toDeg:q,toRad:r,snapToGrid:s,normalizeAngle:t,point:a,line:b,rect:c,ellipse:d,bezier:u}}),"object"==typeof exports)var joint={dia:{Link:require("./joint.dia.link").Link,Element:require("./joint.dia.element").Element},shapes:require("../plugins/shapes")},Backbone=require("backbone"),_=require("lodash");if(joint.dia.GraphCells=Backbone.Collection.extend({initialize:function(){this.on("change:z",this.sort,this)},model:function(a,b){if("link"===a.type)return new joint.dia.Link(a,b);var c=a.type.split(".")[0],d=a.type.split(".")[1];return joint.shapes[c]&&joint.shapes[c][d]?new joint.shapes[c][d](a,b):new joint.dia.Element(a,b)},comparator:function(a){return a.get("z")||0},getConnectedLinks:function(a,b){b=b||{},_.isUndefined(b.inbound)&&_.isUndefined(b.outbound)&&(b.inbound=b.outbound=!0);var c=[];return this.each(function(d){var e=d.get("source"),f=d.get("target");e&&e.id===a.id&&b.outbound&&c.push(d),f&&f.id===a.id&&b.inbound&&c.push(d)}),c}}),joint.dia.Graph=Backbone.Model.extend({initialize:function(){this.set("cells",new joint.dia.GraphCells),this.get("cells").on("all",this.trigger,this),this.get("cells").on("remove",this.removeCell,this)},fromJSON:function(a){if(!a.cells)throw new Error("Graph JSON must contain cells array.");var b=a,c=a.cells;delete b.cells,this.set(b),this.resetCells(c)},clear:function(){this.get("cells").remove(this.get("cells").models)},_prepareCell:function(a){return a instanceof Backbone.Model&&_.isUndefined(a.get("z"))?a.set("z",this.get("cells").length,{silent:!0}):_.isUndefined(a.z)&&(a.z=this.get("cells").length),a},addCell:function(a,b){return _.isArray(a)?this.addCells(a,b):(this.get("cells").add(this._prepareCell(a),b||{}),this)},addCells:function(a,b){return _.each(a,function(a){this.addCell(this._prepareCell(a),b||{})},this),this},resetCells:function(a){return this.get("cells").reset(_.map(a,this._prepareCell,this)),this},removeCell:function(a,b,c){c&&c.disconnectLinks?this.disconnectLinks(a):this.removeLinks(a),this.get("cells").remove(a,{silent:!0})},getCell:function(a){return this.get("cells").get(a)},getElements:function(){return this.get("cells").filter(function(a){return a instanceof joint.dia.Element})},getLinks:function(){return this.get("cells").filter(function(a){return a instanceof joint.dia.Link})},getConnectedLinks:function(a,b){return this.get("cells").getConnectedLinks(a,b)},getNeighbors:function(a){var b=this.getConnectedLinks(a),c=[],d=this.get("cells");return _.each(b,function(b){var e=b.get("source"),f=b.get("target");if(!e.x){var g=d.get(e.id);g!==a&&c.push(g)}if(!f.x){var h=d.get(f.id);h!==a&&c.push(h)}}),c},disconnectLinks:function(a){_.each(this.getConnectedLinks(a),function(b){b.set(b.get("source").id===a.id?"source":"target",g.point(0,0))})},removeLinks:function(a){_.invoke(this.getConnectedLinks(a),"remove")}}),"object"==typeof exports&&(module.exports.Graph=joint.dia.Graph),"object"==typeof exports)var joint={util:require("./core").util,dia:{Link:require("./joint.dia.link").Link}},Backbone=require("backbone"),_=require("lodash");if(joint.dia.Cell=Backbone.Model.extend({constructor:function(a,b){var c,d=a||{};this.cid=_.uniqueId("c"),this.attributes={},b&&b.collection&&(this.collection=b.collection),b&&b.parse&&(d=this.parse(d,b)||{}),(c=_.result(this,"defaults"))&&(d=_.merge({},c,d)),this.set(d,b),this.changed={},this.initialize.apply(this,arguments)},toJSON:function(){var a=this.constructor.prototype.defaults.attrs||{},b=this.attributes.attrs,c={};_.each(b,function(b,d){var e=a[d];_.each(b,function(a,b){_.isObject(a)&&!_.isArray(a)?_.each(a,function(a,f){e&&e[b]&&_.isEqual(e[b][f],a)||(c[d]=c[d]||{},(c[d][b]||(c[d][b]={}))[f]=a)}):e&&_.isEqual(e[b],a)||(c[d]=c[d]||{},c[d][b]=a)})});var d=_.cloneDeep(_.omit(this.attributes,"attrs"));return d.attrs=c,d},initialize:function(a){a&&a.id||this.set("id",joint.util.uuid(),{silent:!0})},remove:function(a){var b=this.collection;b&&b.trigger("batch:start");var c=this.get("parent");if(c){var d=this.collection&&this.collection.get(c);d.unembed(this)}_.invoke(this.getEmbeddedCells(),"remove",a),this.trigger("remove",this,this.collection,a),b&&b.trigger("batch:stop")},toFront:function(){this.collection&&this.set("z",(this.collection.last().get("z")||0)+1)},toBack:function(){this.collection&&this.set("z",(this.collection.first().get("z")||0)-1)},embed:function(a){this.trigger("batch:start");var b=a.id;a.set("parent",this.id),this.set("embeds",_.uniq((this.get("embeds")||[]).concat([b]))),this.trigger("batch:stop")},unembed:function(a){this.trigger("batch:start");var b=a.id;a.unset("parent"),this.set("embeds",_.without(this.get("embeds"),b)),this.trigger("batch:stop")},getEmbeddedCells:function(){return this.collection?_.map(this.get("embeds")||[],function(a){return this.collection.get(a)},this):[]},clone:function(a){a=a||{};var b=Backbone.Model.prototype.clone.apply(this,arguments);if(b.set("id",joint.util.uuid(),{silent:!0}),b.set("embeds",""),!a.deep)return b;var c=this.getEmbeddedCells(),d=[b],e={};return _.each(c,function(a){var c=a.clone({deep:!0});b.embed(c[0]),_.each(c,function(b){if(d.push(b),!(b instanceof joint.dia.Link)){var c=this.collection.getConnectedLinks(a,{inbound:!0});_.each(c,function(a){var c=e[a.id]||a.clone();e[a.id]=c;var d=_.clone(c.get("target"));d.id=b.id,c.set("target",d)});var f=this.collection.getConnectedLinks(a,{outbound:!0});_.each(f,function(a){var c=e[a.id]||a.clone();e[a.id]=c;var d=_.clone(c.get("source"));d.id=b.id,c.set("source",d)})}},this)},this),d=d.concat(_.values(e))},attr:function(a,b){var c=this.get("attrs"),d="/";if(_.isString(a)){if(b){var e={};return joint.util.setByPath(e,a,b,d),this.set("attrs",_.merge({},c,e))}return joint.util.getByPath(c,a,d)}return this.set("attrs",_.merge({},c,a))}}),joint.dia.CellView=Backbone.View.extend({initialize:function(){_.bindAll(this,"remove","update"),this.$el.data("view",this),this.model.on({remove:this.remove,"change:attrs":this.update})},_configure:function(a){a.id=a.id||joint.util.guid(this),Backbone.View.prototype._configure.apply(this,arguments)},_ensureElement:function(){this.el||(this.el=V("g",{id:this.id}).node),this.setElement(this.el,!1)},findBySelector:function(a){var b="."===a?this.$el:this.$el.find(a);return b},notify:function(a){if(this.paper){var b=Array.prototype.slice.call(arguments,1);this.trigger.apply(this,[a].concat(b)),this.paper.trigger.apply(this.paper,[a,this].concat(b))}},getStrokeBBox:function(a){var b=!!a;a=a||this.el;var c,d=V(a).bbox(!1,this.paper.viewport);return c=b?V(a).attr("stroke-width"):this.model.attr("rect/stroke-width")||this.model.attr("circle/stroke-width")||this.model.attr("ellipse/stroke-width")||this.model.attr("path/stroke-width"),c=parseFloat(c)||0,g.rect(d).moveAndExpand({x:-c/2,y:-c/2,width:c,height:c})},getBBox:function(){return V(this.el).bbox()},highlight:function(a){a=a?this.$(a)[0]||this.el:this.el;var b=V(a).attr("class")||"";/\bhighlighted\b/.exec(b)||V(a).attr("class",b.trim()+" highlighted")},unhighlight:function(a){a=a?this.$(a)[0]||this.el:this.el,V(a).attr("class",(V(a).attr("class")||"").replace(/\bhighlighted\b/,"").trim())},findMagnet:function(a){var b=this.$(a);if(0===b.length||b[0]===this.el){var c=this.model.get("attrs");return c["."]&&c["."].magnet===!1?void 0:this.el}return b.attr("magnet")?b[0]:this.findMagnet(b.parent())},getSelector:function(a,b){if(a===this.el)return b;var c=$(a).index();return b=a.tagName+":nth-child("+(c+1)+")"+" "+(b||""),this.getSelector($(a).parent()[0],b+" ")},pointerdown:function(a,b,c){this.model.collection&&(this.model.trigger("batch:start"),this._collection=this.model.collection),this.notify("cell:pointerdown",a,b,c)},pointermove:function(a,b,c){this.notify("cell:pointermove",a,b,c)},pointerup:function(a,b,c){this.notify("cell:pointerup",a,b,c),this._collection&&(this._collection.trigger("batch:stop"),delete this._collection)}}),"object"==typeof exports&&(module.exports.Cell=joint.dia.Cell,module.exports.CellView=joint.dia.CellView),"object"==typeof exports)var joint={dia:{Cell:require("./joint.dia.cell").Cell,CellView:require("./joint.dia.cell").CellView}},Backbone=require("backbone"),_=require("lodash");if(joint.dia.Element=joint.dia.Cell.extend({defaults:{size:{width:1,height:1}},position:function(a,b){this.set("position",{x:a,y:b})},translate:function(a,b,c){if(b=b||0,0===a&&0===b)return this;var d=this.get("position")||{x:0,y:0};return this.set("position",{x:d.x+a||0,y:d.y+b||0},c),_.invoke(this.getEmbeddedCells(),"translate",a,b),this},resize:function(a,b){return this.trigger("batch:start"),this.set("size",{width:a,height:b}),this.trigger("batch:stop"),this},rotate:function(a,b){return this.set("angle",b?a:((this.get("angle")||0)+a)%360)},getBBox:function(){var a=this.get("position"),b=this.get("size");return g.rect(a.x,a.y,b.width,b.height)}}),joint.dia.ElementView=joint.dia.CellView.extend({initialize:function(){_.bindAll(this,"translate","resize","rotate"),joint.dia.CellView.prototype.initialize.apply(this,arguments),V(this.el).attr({"class":"element "+this.model.get("type").split(".").join(" "),"model-id":this.model.id}),this.model.on({"change:position":this.translate,"change:size":this.resize,"change:angle":this.rotate})},update:function(a,b){var c=V(this.$(".rotatable")[0]);if(c){var d=c.attr("transform");c.attr("transform","")}var e=[],f=b||this.model.get("attrs");_.each(f,function(a,b){var c=this.findBySelector(b);if(0!==c.length){var d=["style","text","ref-x","ref-y","ref-dx","ref-dy","ref","x-alignment","y-alignment"],f=_.omit(a,d);c.each(function(){V(this).attr(f)}),a.style&&c.css(a.style),_.isUndefined(a.text)||c.each(function(){V(this).text(a.text+"")}),_.isUndefined(a["ref-x"])&&_.isUndefined(a["ref-y"])&&_.isUndefined(a["ref-dx"])&&_.isUndefined(a["ref-dy"])&&_.isUndefined(a["x-alignment"])&&_.isUndefined(a["y-alignment"])||e.push(c)}},this);var g=this.el.getBBox();_.each(e,function(a){this.positionRelative(a,g,f)},this),c&&c.attr("transform",d||"")},positionRelative:function(a,b,c){function d(a){return _.isNumber(a)&&!_.isNaN(a)}var e=c[a.selector],f=parseFloat(e["ref-x"]),g=parseFloat(e["ref-y"]),h=parseFloat(e["ref-dx"]),i=parseFloat(e["ref-dy"]),j=e["y-alignment"],k=e["x-alignment"],l=_.contains(_.pluck(_.pluck(a.parents("g"),"className"),"baseVal"),"scalable"),m=e.ref;m&&(b=V(this.findBySelector(m)[0]).bbox(!1,this.el));var n=V(a[0]);n.attr("transform")&&n.attr("transform",n.attr("transform").replace(/translate\([^)]*\)/g,"")||"");var o=0,p=0;if(d(h))if(l){var q=V(this.$(".scalable")[0]).scale();o=b.x+b.width+h/q.sx}else o=b.x+b.width+h;if(d(i))if(l){var q=V(this.$(".scalable")[0]).scale();p=b.y+b.height+i/q.sy}else p=b.y+b.height+i;if(d(f))if(f>0&&1>f)o=b.x+b.width*f;else if(l){var q=V(this.$(".scalable")[0]).scale();o=b.x+f/q.sx}else o=b.x+f;if(d(g))if(g>0&&1>g)p=b.y+b.height*g;else if(l){var q=V(this.$(".scalable")[0]).scale();p=b.y+g/q.sy}else p=b.y+g;var r=n.bbox(!1,this.paper.viewport);"middle"===j?p-=r.height/2:d(j)&&(p+=j>0&&1>j?r.height*j:j),"middle"===k?o-=r.width/2:d(k)&&(o+=k>0&&1>k?r.width*k:k),n.translate(o,p)},render:function(){var a=this.model.markup||this.model.get("markup");if(!a)throw new Error("properties.markup is missing while the default render() implementation is used.");var b=V(a);return V(this.el).append(b),this.update(),this.resize(),this.rotate(),this.translate(),this},scale:function(a,b){V(this.el).scale(a,b)},resize:function(){var a=this.model.get("size")||{width:1,height:1},b=this.model.get("angle")||0,c=V(this.$(".scalable")[0]);if(c){var d=c.bbox(!0);c.attr("transform","scale("+a.width/d.width+","+a.height/d.height+")");var e=V(this.$(".rotatable")[0]),f=e&&e.attr("transform");if(f&&"null"!==f){e.attr("transform",f+" rotate("+-b+","+a.width/2+","+a.height/2+")");var g=c.bbox(!1,this.paper.viewport);this.model.set("position",{x:g.x,y:g.y}),this.rotate()}this.update()}},translate:function(a,b,c){var d=this.model.get("position")||{x:0,y:0};if(c&&c.animation){var e=V("animateTransform",{attributeName:"transform",attributeType:"XML",type:"translate",from:(this.model.previous("position").x||0)+" "+(this.model.previous("position").y||0),to:d.x+" "+d.y,dur:"100ms",fill:"freeze"});V(this.el).append(e),e.node.beginElement()}else V(this.el).attr("transform","translate("+d.x+","+d.y+")")},rotate:function(){var a=V(this.$(".rotatable")[0]);if(a){var b=this.model.get("angle")||0,c=this.model.get("size")||{width:1,height:1},d=c.width/2,e=c.height/2;a.attr("transform","rotate("+b+","+d+","+e+")")}},pointerdown:function(a,b,c){this._dx=b,this._dy=c,joint.dia.CellView.prototype.pointerdown.apply(this,arguments)},pointermove:function(a,b,c){var d=this.paper.options.gridSize;if(this.options.interactive!==!1){var e=this.model.get("position");this.model.translate(g.snapToGrid(e.x,d)-e.x+g.snapToGrid(b-this._dx,d),g.snapToGrid(e.y,d)-e.y+g.snapToGrid(c-this._dy,d))}this._dx=g.snapToGrid(b,d),this._dy=g.snapToGrid(c,d),joint.dia.CellView.prototype.pointermove.apply(this,arguments)}}),"object"==typeof exports&&(module.exports.Element=joint.dia.Element,module.exports.ElementView=joint.dia.ElementView),"object"==typeof exports)var joint={dia:{Cell:require("./joint.dia.cell").Cell,CellView:require("./joint.dia.cell").CellView}},Backbone=require("backbone"),_=require("lodash");if(joint.dia.Link=joint.dia.Cell.extend({defaults:{type:"link"},disconnect:function(){return this.set({source:g.point(0,0),target:g.point(0,0)})},label:function(a,b){a=a||0;var c=this.get("labels");if(0===arguments.length||1===arguments.length)return c&&c[a];var d=_.merge({},c[a],b),e=c.slice();return e[a]=d,this.set({labels:e})}}),joint.dia.LinkView=joint.dia.CellView.extend({markup:['<path class="connection" stroke="black"/>','<path class="marker-source" fill="black" stroke="black" />','<path class="marker-target" fill="black" stroke="black" />','<path class="connection-wrap"/>','<g class="labels" />','<g class="marker-vertices"/>','<g class="marker-arrowheads"/>','<g class="link-tools" />'].join(""),labelMarkup:['<g class="label">',"<rect />","<text />","</g>"].join(""),toolMarkup:['<g class="link-tool">','<g class="tool-remove" event="remove">','<circle r="11" />','<path transform="scale(.8) translate(-16, -16)" d="M24.778,21.419 19.276,15.917 24.777,10.415 21.949,7.585 16.447,13.087 10.945,7.585 8.117,10.415 13.618,15.917 8.116,21.419 10.946,24.248 16.447,18.746 21.948,24.248z"/>',"<title>Remove link.</title>","</g>",'<g class="tool-options" event="link:options">','<circle r="11" transform="translate(25)"/>','<path fill="white" transform="scale(.55) translate(29, -16)" d="M31.229,17.736c0.064-0.571,0.104-1.148,0.104-1.736s-0.04-1.166-0.104-1.737l-4.377-1.557c-0.218-0.716-0.504-1.401-0.851-2.05l1.993-4.192c-0.725-0.91-1.549-1.734-2.458-2.459l-4.193,1.994c-0.647-0.347-1.334-0.632-2.049-0.849l-1.558-4.378C17.165,0.708,16.588,0.667,16,0.667s-1.166,0.041-1.737,0.105L12.707,5.15c-0.716,0.217-1.401,0.502-2.05,0.849L6.464,4.005C5.554,4.73,4.73,5.554,4.005,6.464l1.994,4.192c-0.347,0.648-0.632,1.334-0.849,2.05l-4.378,1.557C0.708,14.834,0.667,15.412,0.667,16s0.041,1.165,0.105,1.736l4.378,1.558c0.217,0.715,0.502,1.401,0.849,2.049l-1.994,4.193c0.725,0.909,1.549,1.733,2.459,2.458l4.192-1.993c0.648,0.347,1.334,0.633,2.05,0.851l1.557,4.377c0.571,0.064,1.148,0.104,1.737,0.104c0.588,0,1.165-0.04,1.736-0.104l1.558-4.377c0.715-0.218,1.399-0.504,2.049-0.851l4.193,1.993c0.909-0.725,1.733-1.549,2.458-2.458l-1.993-4.193c0.347-0.647,0.633-1.334,0.851-2.049L31.229,17.736zM16,20.871c-2.69,0-4.872-2.182-4.872-4.871c0-2.69,2.182-4.872,4.872-4.872c2.689,0,4.871,2.182,4.871,4.872C20.871,18.689,18.689,20.871,16,20.871z"/>',"<title>Link options.</title>","</g>","</g>"].join(""),vertexMarkup:['<g class="marker-vertex-group" transform="translate(<%= x %>, <%= y %>)">','<circle class="marker-vertex" idx="<%= idx %>" r="10"/>','<path class="marker-vertex-remove-area" idx="<%= idx %>" d="M16,5.333c-7.732,0-14,4.701-14,10.5c0,1.982,0.741,3.833,2.016,5.414L2,25.667l5.613-1.441c2.339,1.317,5.237,2.107,8.387,2.107c7.732,0,14-4.701,14-10.5C30,10.034,23.732,5.333,16,5.333z" transform="translate(5, -33)"/>','<path class="marker-vertex-remove" idx="<%= idx %>" transform="scale(.8) translate(9.5, -37)" d="M24.778,21.419 19.276,15.917 24.777,10.415 21.949,7.585 16.447,13.087 10.945,7.585 8.117,10.415 13.618,15.917 8.116,21.419 10.946,24.248 16.447,18.746 21.948,24.248z">',"<title>Remove vertex.</title>","</path>","</g>"].join(""),arrowheadMarkup:['<g class="marker-arrowhead-group" transform="translate(<%= x %>, <%= y %>)">','<path class="marker-arrowhead" end="<%= end %>" d="M 26 0 L 0 13 L 26 26 z" />',"</g>"].join(""),options:{shortLinkLength:100},initialize:function(){joint.dia.CellView.prototype.initialize.apply(this,arguments),_.bindAll(this,"update","updateEnds","render","renderVertexMarkers","renderLabels","renderTools","onSourceModelChange","onTargetModelChange"),V(this.el).attr({"class":"link","model-id":this.model.id}),this.model.on({"change:vertices change:smooth change:manhattan":this.update,"change:source change:target":this.updateEnds,"change:markup":this.render,"change:vertices change:vertexMarkup":this.renderVertexMarkers,"change:labels change:labelMarkup":_.bind(function(){this.renderLabels(),this.updateLabelPositions()
getAll() { return cloneDeep(this._cache); }
results.forEach(result => { // File with `CssSyntaxError` have not `_postcssResult` if (!result._postcssResult) { return } const unused = { source: result.source, ranges: [] } const rangeData = _.cloneDeep(result._postcssResult.stylelint.disabledRanges) if (!rangeData) { return } result.warnings.forEach(warning => { const rule/*: string*/ = warning.rule const ruleRanges = rangeData[rule] if (ruleRanges) { // Back to front so we get the *last* range that applies to the warning for (const range of ruleRanges.reverse()) { if (isWarningInRange(warning, range)) { range.used = true return } } } for (const range of rangeData.all.reverse()) { if (isWarningInRange(warning, range)) { range.used = true return } } }) Object.keys(rangeData).forEach(rule => { rangeData[rule].forEach(range => { // Is an equivalent range already marked as unused? const alreadyMarkedUnused = unused.ranges.find(unusedRange => { return unusedRange.start === range.start && unusedRange.end === range.end }) // If this range is unused and no equivalent is marked, // mark this range as unused if (!range.used && !alreadyMarkedUnused) { unused.ranges.push(range) } // If this range is used but an equivalent has been marked as unused, // remove that equivalent. This can happen because of the duplication // of ranges in rule-specific range sets and the "all" range set if (range.used && alreadyMarkedUnused) { _.remove(unused.ranges, alreadyMarkedUnused) } }) }) unused.ranges = _.sortBy(unused.ranges, [ "start", "end" ]) report.push(unused) })
function loop(component) { if (component === null) { return resolve(); } component.type = 'list'; component.pageSize = 30; if (!component._choices) { component._choices = component.choices; } var choices; if (typeof component._choices === 'function') { choices = component._choices(); } else if (Array.isArray(component._choices)) { choices = _.cloneDeep(component._choices); } else { choices = []; } Promise.resolve(choices).then(function (choices) { component.choices = choices; component.choices.push('--'); component.choices.push(['Go Back', function () { return BACK; }]); component.choices.push(['Exit!', function () { return EXIT; }]); component.choices.push('--'); component.default = component.default || component.choices.default || component._choices.default; inquirer .prompt(component) .then(function (result) { return result && result.then ? result : Promise.resolve(result); }) .then(function (prop) { var action = null; if (prop === EXIT) { return resolve(); } if (prop === HOME) { action = actions.HOME; } else if (prop === BACK) { action = actions.POP; } else if (prop && (typeof prop === 'function') || (prop && prop.message && prop.choices)) { action = actions.PUSH; } else { action = actions.REPLACE; } loop(menu.next(action, prop)); }) .catch(function (err) { reject(err); }); }); }
function walkTree(ignoreRules, subPath, callback) { var list = {}; try { // Respect nested ignore files. ignoreRules = LODASH.cloneDeep(ignoreRules); self._loadIgnoreRules(ignoreRules, subPath, options); } catch(err) { return callback(err); } var c = 0; FS.readdir(PATH.join(self._rootPath, subPath), function(err, files) { if (err) return callback(err); if (files.length === 0) { return callback(null, list, self._stats); } function error(err) { c = -1; return callback(err); } function done() { if (c !== 0) return; c = -1; return callback(null, list, self._stats); } files.forEach(function(basename) { if (c === -1) return; function ignore(type) { function select(ruleGroups, path) { var rules = null; if (ruleGroups[path]) { rules = ruleGroups[path]; } else { for (var prefix in ruleGroups) { if (path.substring(0, prefix.length) === prefix) { rules = ruleGroups[prefix]; break; } } } if (!rules && ruleGroups[""]) { rules = ruleGroups[""]; } if (rules) { for (var i=0 ; i<rules.length ; i++) { if (rules[i](path)) { return true; } } return false; } } if (select(ignoreRules.include, subPath + "/" + basename + ((type === "dir") ? "/" : ""))) { return false; } if (select(ignoreRules.top, subPath + "/" + basename + ((type === "dir") ? "/" : ""))) { return true; } // All deeper nodes. return select(ignoreRules.every, basename + ((type === "dir") ? "/" : "")); } c += 1; FS.lstat(PATH.join(self._rootPath, subPath, basename), function(err, stat) { if (err) return error(err); c -= 1; if (stat.isSymbolicLink()) { c += 1; FS.readlink(PATH.join(self._rootPath, subPath, basename), function(err, val) { if (err) return error(err); c -= 1; // TODO: Detect circular links. var linkDir = null; try { linkDir = FS.realpathSync(PATH.resolve(FS.realpathSync(PATH.join(self._rootPath, subPath)), val)); } catch(err) { if (err.code === "ENOENT") return done(); throw err; } c += 1; FS.lstat(linkDir, function(err, linkStat) { if (err) return error(err); c -= 1; self._stats.totalFiles += 1; if (!ignore( linkStat.isDirectory() ? "dir" : "file")) { list[subPath + "/" + basename] = { mtime: stat.mtime.getTime(), dir: linkStat.isDirectory() || false, symlink: val, symlinkReal: linkDir }; if (linkStat.isDirectory()) { if (traversedSymlink[linkDir]) { return done(); } traversedSymlink[linkDir] = true; c += 1; return walkTree(ignoreRules, subPath + "/" + basename, function(err, subList) { if (err) return error(err); c -= 1; for (var key in subList) { list[key] = subList[key]; } return done(); }); } else { return done(); } } else { self._stats.ignoredFiles += 1; return done(); } }); }); } else if (stat.isDirectory()) { var walk = false; if (!ignore("dir")) { list[subPath + "/" + basename] = { dir: true, mtime: stat.mtime.getTime() }; walk = true; } else { for (var path in ignoreRules.include) { if (path.substring(0, (subPath + "/" + basename).length) === (subPath + "/" + basename)) { walk = true; break; } } } if (walk) { c += 1; walkTree(ignoreRules, subPath + "/" + basename, function(err, subList) { if (err) return error(err); c -= 1; for (var key in subList) { list[key] = subList[key]; } done(); }); } } else if (stat.isFile()) { self._stats.totalFiles += 1; if (!ignore("file")) { var mtime = stat.mtime.getTime(); self._stats.totalSize += mtime; list[subPath + "/" + basename] = { mtime: mtime, size: stat.size }; } else { self._stats.ignoredFiles += 1; } } done(); }); }); done(); }); }
function normalize(options) { var normalized = _.cloneDeep(options); normalized.include = normalized.include || {}; normalized.includeDirs = normalized.includeDirs || []; return normalized; }
.then(function(resources) { that._resources[base] = resources; return _.cloneDeep(resources); });
it('should return a new state for user request failed', () => { const expectedState = _.cloneDeep(initialState); expect(initialState).to.eql(expectedState); });
config._vals = function () { return _.cloneDeep(vals); };
Database.prototype.update = function(collectionName, options, values, cb) { var self = this; // If no filePath is set for this collection, return an error in the object if(!this.filePath) return cb(new Error('No filePath was configured for this collection')); // Filter Data based on Options criteria var resultSet = waterlineCriteria(collectionName, this.data, options); // Get a list of any attributes we're updating that: // i) are in the schema // ii) have uniqueness constraints // var uniqueAttrs = _.where(_.keys(values), function(attrName) { // var attributeDef = self.schema[collectionName][attrName]; // return attributeDef && attributeDef.unique; // }); // If we're updating any attributes that are supposed to be unique, do some additional checks // if (uniqueAttrs.length && resultSet.indices.length) { // // If we would be updating more than one record, then uniqueness constraint automatically fails // if (resultSet.indices.length > 1) { // var error = new Error('Uniqueness check failed on attributes: ' + uniqueAttrs.join(',')); // return cb(error); // } // // Otherwise for each unique attribute, ensure that the matching result already has the value // // we're updating it to, so that there wouldn't be more than one record with the same value. // else { // var result = self.data[collectionName][resultSet.indices[0]]; // var records = _.reject(self.data[collectionName], result); // // Build an array of uniqueness errors // var uniquenessErrors = []; // uniquenessErrors.code = 'E_UNIQUE'; // _.each(uniqueAttrs, function eachAttribute (uniqueAttrName) { // // look for matching values in all records. note: this is case sensitive. // if (!!~_.pluck(records, uniqueAttrName).indexOf(values[uniqueAttrName])) { // uniquenessErrors.push({ // attribute: uniqueAttrName, // value: values[uniqueAttrName] // }); // // errors.push(new Error('Uniqueness check failed on attribute: ' + uniqueAttrName + ' with value: ' + values[uniqueAttrName])); // } // }); // // Finally, send the uniqueness errors back to Waterline. // if (uniquenessErrors.length) { // return cb(uniquenessErrors); // } // } // } // Enforce uniquness constraints // If uniqueness constraints were violated, send back a validation error. var violations = self.enforceUniqueness(collectionName, values); if (violations.length) { return cb(new UniquenessError(violations)); } // Otherwise, success! // Build up final set of results. var results = []; for (var i in resultSet.indices) { var matchIndex = resultSet.indices[i]; var _values = self.data[collectionName][matchIndex]; // Clone the data to avoid providing raw access to the underlying // in-memory data, lest a user makes inadvertent changes in her app. self.data[collectionName][matchIndex] = _.extend(_values, values); results.push(_.cloneDeep(self.data[collectionName][matchIndex])); } self.write(collectionName, function() { cb(null, results); }); };
module.exports = function(opts = {}) { // clone the options so we don't unintentionally modify them let options = _.cloneDeep(opts); options = _.defaultsDeep(options, defaultOptions); if (!options.model) { throw new Error('Must specify a model'); } const Model = options.model; validatePartialPairs(options); return function update(model, params) { return function(dispatch) { const proxyModel = new Model(model.data); proxyModel.set(params); proxyModel.save().then(function() { if (options.onSuccess) { dispatch({ type: options.onSuccess.actionType, payload: _.merge(model, { data: proxyModel.toJSON(), state: options.onSuccess.payloadState }) }); } }).catch(function(response) { const error = response.responseJSON; if (response.status === 404) { if (options.onNotFound) { if (options.onNotFound.beforeDispatch) { options.onNotFound.beforeDispatch(response, [model]); } dispatch({ type: options.onNotFound.actionType, payload: _.merge(model, { state: options.onNotFound.payloadState, error: error }) }); } } else if (options.onError) { if (options.onError.beforeDispatch) { options.onError.beforeDispatch(response, [model, params]); } dispatch({ type: options.onError.actionType, payload: _.merge(model, { data: proxyModel.toJSON(), state: options.onError.payloadState, error: error }) }); } }); if (options.optimistic) { return dispatch({ type: options.optimistic.actionType, payload: _.merge(model, { data: proxyModel.toJSON(), state: options.optimistic.payloadState }) }); } }; }; };
function setState(mockState, obj, emit = true) { mockState.toJSON = () => cloneDeep(obj); stateJSON = cloneDeep(obj); if (emit) mockState.emit(eventTypes[0]); }
import AppState from './store.js'; import Quiz from '../stores/quiz.js'; import { questions } from '../../data/data.json'; import Paramalama from 'paramalama'; import _ from 'lodash'; const QUESTIONS = { QUIZ: 3 } let pool = _.cloneDeep(questions); let used = []; const getUnique = (arr1, arr2) => { return _.find(arr1, i => { return !_.some(arr2, el => { return _.trim(el.databases.toLowerCase()) === _.trim(i.databases.toLowerCase()); }); }); }; export default { all() { return AppState.app; }, main() { return AppState.app.main; }, players() {
mockState.toJSON = () => cloneDeep(obj);
beforeEach(function(){ defaultConfig = _.cloneDeep(loadedConfig); });
add: function add(dataToClone, unfilteredOptions) { var options = this.filterOptions(unfilteredOptions, 'add'), self = this, data = _.cloneDeep(dataToClone), userData = this.filterData(data), roles; // check for too many roles if (data.roles && data.roles.length > 1) { return Promise.reject(new common.errors.ValidationError({ message: common.i18n.t('errors.models.user.onlyOneRolePerUserSupported') })); } function getAuthorRole() { return ghostBookshelf.model('Role').findOne({name: 'Author'}, _.pick(options, 'transacting')) .then(function then(authorRole) { return [authorRole.get('id')]; }); } /** * We need this default author role because of the following Ghost feature: * You setup your blog and you can invite people instantly, but without choosing a role. * roles: [] -> no default role (used for owner creation, see fixtures.json) * roles: undefined -> default role */ roles = data.roles; delete data.roles; return ghostBookshelf.Model.add.call(self, userData, options) .then(function then(addedUser) { // Assign the userData to our created user so we can pass it back userData = addedUser; }) .then(function () { if (!roles) { return getAuthorRole(); } return Promise.resolve(roles); }) .then(function (_roles) { roles = _roles; // CASE: it is possible to add roles by name, by id or by object if (_.isString(roles[0]) && !ObjectId.isValid(roles[0])) { return Promise.map(roles, function (roleName) { return ghostBookshelf.model('Role').findOne({ name: roleName }, options); }).then(function (roleModels) { roles = []; _.each(roleModels, function (roleModel) { roles.push(roleModel.id); }); }); } return Promise.resolve(); }) .then(function () { return baseUtils.attach(User, userData.id, 'roles', roles, options); }) .then(function then() { // find and return the added user return self.findOne({id: userData.id, status: 'all'}, options); }); },
describe(testTitle, function () { var dbName = util.format('fhir%sapi', resourceType.toLowerCase()); var appw = appWrap.instance(dbName); var r = supertestWrap({ appWrap: appw, resourceType: resourceType, }); var resources = samples(); var resource0Clone = _.cloneDeep(resources[0]); resource0Clone.birthDate = '1978-06-09'; resources.push(resource0Clone); var moments = { start: moment() }; before(fn(appw, appw.start)); it('check config (inits database as well)', fn(r, r.config)); it('clear database', fn(appw, appw.cleardb)); var n = resources.length; it('create patient 0 using update', fn(r, r.updateToCreate, [resources[0], moments])); _.range(1, n).forEach(function (i) { var title = util.format('create patient %s', i); it(title, fn(r, r.create, [resources[i], moments])); }, this); it('search error', fn(r, r.searchError, [model])); it('search all using get', fn(r, r.search, [n, {}])); it('search all using post', fn(r, r.searchByPost, [n, {}])); it('search not existing id', fn(r, r.search, [0, { _id: '123456789012345678901234' }])); _.range(n).forEach(function (i) { var title = util.format('search by id resource %s', i); it(title, fnId(r, r.search, resources[i])); }, this); it('search not existing family', fn(r, r.search, [0, { family: 'donotexist' }])); it('search by resource 0 family find 2', fn(r, r.search, [2, { family: resources[0].name[0].family[0] }])); it('search by resource 1 family find 1', fn(r, r.search, [1, { family: resources[1].name[0].family[0] }])); var birthDates = resources.map(function (resource) { return resource.birthDay; }); birthDates.sort(); var bbMiddleIndex = Math.floor(birthDates.length / 2); var bbMiddle = resources[bbMiddleIndex].birthDate; it('search by birthDate not existing', fn(r, r.search, [0, { birthDate: '1900-01-01' }])); it('search by birthDate find 1', fn(r, r.search, [1, { birthDate: bbMiddle }])); it('search by birthDate (use < )', fn(r, r.search, [bbMiddleIndex, { birthDate: '<' + bbMiddle }])); it('search by birthDate (use <= )', fn(r, r.search, [bbMiddleIndex + 1, { birthDate: '<=' + bbMiddle }])); it('search by birthDate (use >)', fn(r, r.search, [n - bbMiddleIndex - 1, { birthDate: '>' + bbMiddle }])); it('search by birthDate (use >=)', fn(r, r.search, [n - bbMiddleIndex, { birthDate: '>=' + bbMiddle }])); it('read missing (invalid id)', fn(r, r.readMissing, 'abc')); it('read missing (valid id)', fn(r, r.readMissing, '123456789012345678901234')); _.range(n).forEach(function (i) { var title = util.format('read resource %s', i); it(title, fn(r, r.read, [resources[i], moments, '1', false])); }, this); it('update missing (invalid id)', fn(r, r.updateInvalidId, [resources[0], 'abc'])); it('update local resource 0', function () { resources[0].gender = 'female'; }); it('update local resource 1', function () { resources[1].birthDate = "1981-11-11"; }); _.range(2).forEach(function (i) { it(util.format('detect local resource %s not on server', i), fn(r, r.readNegative, resources[i])); it(util.format('update resource %s', i), fn(r, r.update, [resources[i], moments, '2'])); it(util.format('read resource %s', i), fn(r, r.read, [resources[i], moments, '2', false])); }); it('delete missing (invalid id)', fn(r, r.deleteMissing, 'abc')); it('delete missing (valid id)', fn(r, r.deleteMissing, '123456789012345678901234')); it('refresh moment start', function () { moments.start = moment(); }); it('delete last resource', fn(r, r.delete, resources[n - 1])); it('delete next to last resource', fn(r, r.delete, resources[n - 2])); it('search all using get', fn(r, r.search, [n - 2, {}])); it('update deleted last resource', fn(r, r.updateDeleted, resources[n - 1])); it('update deletes next to last resource', fn(r, r.updateDeleted, resources[n - 2])); it('read deleted last resource for patient 0', fn(r, r.read, [resources[n - 1], moments, '2', true])); it('read deleted last resource for patient 1', fn(r, r.read, [resources[n - 2], moments, '2', true])); after(fn(appw, appw.cleanUp)); });
export default function app(state = initialState, action) { let messages = _.cloneDeep(state.messages); switch (action.type) { case types.LOAD_MESSAGES: let initialMessages = action.messages || [newMessage(0)]; let initialIndex = action.messages ? action.messages.length - 1 : state.index; return Object.assign({}, state, { messages: initialMessages, index: initialIndex, }); case types.NEW_MESSAGE: let index = messages.length; messages.push(newMessage(index)); return Object.assign({}, state, { messages: messages, index: index, }); case types.UPDATE_MESSAGE: messages[state.index].text = action.text; messages[state.index].timestamp = action.timestamp; return Object.assign({}, state, { messages: messages, }); case types.ANALYZE_MESSAGE: messages[state.index].sentiment = action.sentiment; messages[state.index].keywords = action.keywords; AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(messages)); return Object.assign({}, state, { messages: messages, loading: false, }); case types.REMOVE_MESSAGE: _.forEach(messages, (message) => { if (message.index > state.index) { message.index = message.index - 1; } }); messages.splice(state.index, 1); if (!messages.length) { messages = [newMessage(0)] } AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(messages)); return Object.assign({}, state, { messages: messages, index: (state.index === 0) ? 0 : state.index - 1, }); case types.REPLACE_MESSAGE: messages[state.index].text = action.message; AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(messages)); return Object.assign({}, state, { messages: messages, }); case types.GET_REPLACEMENTS: return Object.assign({}, state, { replacements: action.replacements, loading: false, }); case types.CLEAR_REPLACEMENTS: return Object.assign({}, state, { replacements: null, }); case types.PAGINATE_MESSAGES: return Object.assign({}, state, { index: action.index, }); case types.LOADING: return Object.assign({}, state, { loading: action.loading, }); case types.SUCCESS: return Object.assign({}, state, { success: action.success, }); case types.ERROR: return Object.assign({}, state, { error: !action.clear ? (action.error || ERROR_DEFAULT) : null, }); default: return state; } }
beforeEach(function () { sender = _.cloneDeep(validSender); });
criteria: function(origCriteria) { var criteria = _.cloneDeep(origCriteria); // If original criteria is already false, keep it that way. if (criteria === false) return criteria; if(!criteria) return { where: null }; // Let the calling method normalize array criteria. It could be an IN query // where we need the PK of the collection or a .findOrCreateEach if(Array.isArray(criteria)) return criteria; // Empty undefined values from criteria object _.each(criteria, function(val, key) { if(_.isUndefined(val)) criteria[key] = null; }); // Convert non-objects (ids) into a criteria // TODO: use customizable primary key attribute if(!_.isObject(criteria)) { criteria = { id: +criteria || criteria }; } if(_.isObject(criteria) && !criteria.where && criteria.where !== null) { criteria = { where: criteria }; } // Return string to indicate an error if(!_.isObject(criteria)) throw new WLUsageError('Invalid options/criteria :: ' + criteria); // If criteria doesn't seem to contain operational keys, assume all the keys are criteria if(!criteria.where && !criteria.joins && !criteria.join && !criteria.limit && !criteria.skip && !criteria.sort && !criteria.sum && !criteria.average && !criteria.select && !criteria.prune && !criteria.options && !criteria.groupBy && !criteria.min && !criteria.max) { // Delete any residuals and then use the remaining keys as attributes in a criteria query delete criteria.where; delete criteria.joins; delete criteria.join; delete criteria.limit; delete criteria.skip; delete criteria.sort; delete criteria.select; delete criteria.prune; delete criteria.options; criteria = { where: criteria }; } // If where is null, turn it into an object else if(_.isNull(criteria.where)) criteria.where = {}; // Move Limit, Skip, sort outside the where criteria if(hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'limit')) { criteria.limit = parseInt(_.clone(criteria.where.limit), 10); if(criteria.limit < 0) criteria.limit = 0; delete criteria.where.limit; } else if(hop(criteria, 'limit')) { criteria.limit = parseInt(criteria.limit, 10); if(criteria.limit < 0) criteria.limit = 0; } if(hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'skip')) { criteria.skip = parseInt(_.clone(criteria.where.skip), 10); if(criteria.skip < 0) criteria.skip = 0; delete criteria.where.skip; } else if(hop(criteria, 'skip')) { criteria.skip = parseInt(criteria.skip, 10); if(criteria.skip < 0) criteria.skip = 0; } if(hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'sort')) { criteria.sort = _.clone(criteria.where.sort); delete criteria.where.sort; } if(hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'select')) { criteria.select = _.clone(criteria.where.select); delete criteria.where.select; } if(hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'select')) { criteria.prune = _.clone(criteria.where.prune); delete criteria.where.prune; } // Pull out aggregation keys from where key if(hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'sum')) { criteria.sum = _.clone(criteria.where.sum); delete criteria.where.sum; } if(hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'average')) { criteria.average = _.clone(criteria.where.average); delete criteria.where.average; } if(hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'groupBy')) { criteria.groupBy = _.clone(criteria.where.groupBy); delete criteria.where.groupBy; } if(hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'min')) { criteria.min = _.clone(criteria.where.min); delete criteria.where.min; } if(hop(criteria, 'where') && criteria.where !== null && hop(criteria.where, 'max')) { criteria.max = _.clone(criteria.where.max); delete criteria.where.max; } // If WHERE is {}, always change it back to null if(criteria.where && _.keys(criteria.where).length === 0) { criteria.where = null; } // If an IN was specified in the top level query and is an empty array, we can return an // empty object without running the query because nothing will match anyway. Let's return // false from here so the query knows to exit out. if(criteria.where) { var falsy = false; Object.keys(criteria.where).forEach(function(key) { if(Array.isArray(criteria.where[key]) && criteria.where[key].length === 0) { falsy = true; } }); if(falsy) return false; } // If an IN was specified inside an OR clause and is an empty array, remove it because nothing will // match it anyway and it can prevent errors in the adapters if(criteria.where && hop(criteria.where, 'or')) { // Ensure `or` is an array if (!_.isArray(criteria.where.or)) { throw new WLUsageError('An `or` clause in a query should be specified as an array of subcriteria'); } var _clone = _.cloneDeep(criteria.where.or); criteria.where.or.forEach(function(clause, i) { Object.keys(clause).forEach(function(key) { if(Array.isArray(clause[key]) && clause[key].length === 0) { _clone.splice(i, 1); } }); }); criteria.where.or = _clone; } // Normalize sort criteria if(hop(criteria, 'sort') && criteria.sort !== null) { // Split string into attr and sortDirection parts (default to 'asc') if(_.isString(criteria.sort)) { var parts = criteria.sort.split(' '); // Set default sort to asc parts[1] = parts[1] ? parts[1].toLowerCase() : 'asc'; // Throw error on invalid sort order if(parts[1] !== 'asc' && parts[1] !== 'desc') { throw new WLUsageError('Invalid sort criteria :: ' + criteria.sort); } // Expand criteria.sort into object criteria.sort = {}; criteria.sort[parts[0]] = parts[1]; } // normalize ASC/DESC notation Object.keys(criteria.sort).forEach(function(attr) { if(criteria.sort[attr] === 'asc') criteria.sort[attr] = 1; if(criteria.sort[attr] === 'desc') criteria.sort[attr] = -1; }); // normalize binary sorting criteria Object.keys(criteria.sort).forEach(function(attr) { if(criteria.sort[attr] === 0) criteria.sort[attr] = -1; }); // Verify that user either specified a proper object // or provided explicit comparator function if(!_.isObject(criteria.sort) && !_.isFunction(criteria.sort)) { throw new WLUsageError('Invalid sort criteria for ' + attrName + ' :: ' + direction); } } return criteria; },
return setTimeout(function(){ var val = _.cloneDeep(staleVal); val._cached = true; cb(null, staleVal); }, 0);