StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics
https://doi.org/10.1109/TVCG.2020.3030352
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
396 lines
7.9 KiB
396 lines
7.9 KiB
'use strict';
|
|
|
|
var fs = require('fs');
|
|
var utils = require('lazy-cache')(require);
|
|
var fn = require;
|
|
require = utils; // eslint-disable-line
|
|
|
|
/**
|
|
* Lazily invoked module dependencies
|
|
*/
|
|
|
|
require('array-sort', 'sortBy');
|
|
require('async-each', 'each');
|
|
require('base-data');
|
|
require('base-engines', 'engines');
|
|
require('base-helpers', 'helpers');
|
|
require('base-option', 'option');
|
|
require('base-plugins', 'plugin');
|
|
require('base-routes', 'routes');
|
|
require('deep-bind', 'bindAll');
|
|
require('define-property', 'define');
|
|
require('engine-base', 'engine');
|
|
require('extend-shallow', 'extend');
|
|
require('falsey', 'isFalsey');
|
|
require('get-value', 'get');
|
|
require('get-view');
|
|
require('group-array', 'groupBy');
|
|
require('has-glob');
|
|
require('has-value', 'has');
|
|
require('inflection', 'inflect');
|
|
require('is-valid-app', 'isValid');
|
|
require('layouts');
|
|
require('match-file');
|
|
require('mixin-deep', 'merge');
|
|
require('paginationator');
|
|
require('pascalcase', 'pascal');
|
|
require('set-value', 'set');
|
|
require('template-error', 'rethrow');
|
|
require = fn; // eslint-disable-line
|
|
|
|
/**
|
|
* Expose default router methods used in all Template instances
|
|
*/
|
|
|
|
utils.methods = [
|
|
'onLoad',
|
|
'preCompile',
|
|
'preLayout',
|
|
'onLayout',
|
|
'postLayout',
|
|
'onMerge',
|
|
'onStream',
|
|
'postCompile',
|
|
'preRender',
|
|
'postRender',
|
|
'preWrite',
|
|
'postWrite'
|
|
];
|
|
|
|
utils.constructorKeys = [
|
|
'Collection',
|
|
'Group',
|
|
'Item',
|
|
'List',
|
|
'View',
|
|
'Views'
|
|
];
|
|
|
|
/**
|
|
* Options keys
|
|
*/
|
|
|
|
utils.optsKeys = [
|
|
'renameKey',
|
|
'namespaceData',
|
|
'mergePartials',
|
|
'rethrow',
|
|
'nocase',
|
|
'nonull',
|
|
'rename',
|
|
'cwd'
|
|
];
|
|
|
|
utils.endsWith = function(str, sub) {
|
|
return str.slice(-sub.length) === sub;
|
|
};
|
|
|
|
/**
|
|
* Return true if file exists and is not a directory.
|
|
*/
|
|
|
|
utils.fileExists = function(filepath) {
|
|
try {
|
|
return fs.statSync(filepath).isDirectory() === false;
|
|
} catch (err) {}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Keep a history of engines used to compile a view, and
|
|
* the compiled function for each, allowing the compiled
|
|
* function to be used again the next time the same view
|
|
* is rendered by the same engine.
|
|
*
|
|
* @param {Object} view
|
|
* @param {String} engine
|
|
* @param {Function} fn
|
|
*/
|
|
|
|
utils.engineStack = function(view, engine, fn, content) {
|
|
if (typeof view.engineStack === 'undefined') {
|
|
view.engineStack = {};
|
|
}
|
|
if (engine && engine.charAt(0) !== '.') {
|
|
engine = '.' + engine;
|
|
}
|
|
view.engineStack[engine] = fn;
|
|
view.engineStack[engine].content = content;
|
|
};
|
|
|
|
/**
|
|
* Return true if a template is a partial
|
|
*/
|
|
|
|
utils.isPartial = function(view) {
|
|
if (typeof view.isType !== 'function') {
|
|
return false;
|
|
}
|
|
if (typeof view.options === 'undefined') {
|
|
return false;
|
|
}
|
|
if (typeof view.options.viewType === 'undefined') {
|
|
return false;
|
|
}
|
|
return view.isType('partial');
|
|
};
|
|
|
|
/**
|
|
* Return true if a template is renderable, and not a partial or layout
|
|
*/
|
|
|
|
utils.isRenderable = function(view) {
|
|
if (typeof view.isType !== 'function') {
|
|
return false;
|
|
}
|
|
if (typeof view.options === 'undefined') {
|
|
return false;
|
|
}
|
|
if (typeof view.options.viewType === 'undefined') {
|
|
return false;
|
|
}
|
|
return view.isType('renderable') && view.viewType.length === 1;
|
|
};
|
|
|
|
/**
|
|
* When a constructor is defined after init, update any underlying
|
|
* properties that may rely on that option (constructor).
|
|
*/
|
|
|
|
utils.updateOptions = function(app, key, value) {
|
|
var k = utils.constructorKeys;
|
|
if (k.indexOf(key) > -1) {
|
|
app.define(key, value);
|
|
}
|
|
if (key === 'layout') {
|
|
app.viewTypes.renderable.forEach(function(name) {
|
|
app[name].option('layout', value);
|
|
});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Return the given value as-is.
|
|
*/
|
|
|
|
utils.identity = function(val) {
|
|
return val;
|
|
};
|
|
|
|
/**
|
|
* Arrayify the given value by casting it to an array.
|
|
*/
|
|
|
|
utils.arrayify = function(val) {
|
|
return val ? (Array.isArray(val) ? val : [val]) : [];
|
|
};
|
|
|
|
/**
|
|
* Return the last element in an array or array-like object.
|
|
*/
|
|
|
|
utils.last = function(array, n) {
|
|
return array[array.length - (n || 1)];
|
|
};
|
|
|
|
/**
|
|
* Return true if the given value is an object.
|
|
* @return {Boolean}
|
|
*/
|
|
|
|
utils.isObject = function(val) {
|
|
if (!val || Array.isArray(val)) {
|
|
return false;
|
|
}
|
|
return typeof val === 'function'
|
|
|| typeof val === 'object';
|
|
};
|
|
|
|
/**
|
|
* Return true if the given value is a string.
|
|
*/
|
|
|
|
utils.isString = function(val) {
|
|
return val && typeof val === 'string';
|
|
};
|
|
|
|
/**
|
|
* Return true if the given value is a buffer
|
|
*/
|
|
|
|
utils.isBuffer = function(val) {
|
|
if (val && val.constructor && typeof val.constructor.isBuffer === 'function') {
|
|
return val.constructor.isBuffer(val);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Return true if the given value is a stream.
|
|
*/
|
|
|
|
utils.isStream = function(val) {
|
|
return utils.isObject(val)
|
|
&& (typeof val.pipe === 'function')
|
|
&& (typeof val.on === 'function');
|
|
};
|
|
|
|
/**
|
|
* Assign own properties from provider to receiver, but only
|
|
* if the receiving object does not already have a value.
|
|
*/
|
|
|
|
utils.defaults = function(target) {
|
|
var args = [].slice.call(arguments, 1);
|
|
var len = args.length;
|
|
var i = -1;
|
|
|
|
while (++i < len) {
|
|
var obj = args[i];
|
|
|
|
for (var key in obj) {
|
|
target[key] = target[key] || obj[key];
|
|
}
|
|
}
|
|
return target;
|
|
};
|
|
|
|
/**
|
|
* Return true if the given value is an object.
|
|
* @return {Boolean}
|
|
*/
|
|
|
|
utils.isOptions = function(val) {
|
|
return utils.isObject(val) && val.hasOwnProperty('hash');
|
|
};
|
|
|
|
/**
|
|
* Format a helper error.
|
|
* TODO: create an error class for helpers
|
|
*/
|
|
|
|
utils.helperError = function(app, helperName, viewName, cb) {
|
|
var err = new Error('helper "' + helperName + '" cannot find "' + viewName + '"');
|
|
app.emit('error', err);
|
|
if (typeof cb === 'function') {
|
|
return cb(err);
|
|
} else {
|
|
throw err;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Convenience method for setting `this.isFoo` and `this._name = 'Foo'
|
|
* on the given `app`
|
|
*/
|
|
|
|
utils.setInstanceNames = function setInstanceNames(app, name) {
|
|
utils.define(app, 'is' + utils.pascal(name), true);
|
|
utils.define(app, '_name', name);
|
|
};
|
|
|
|
/**
|
|
* Singularize the given `name`
|
|
*/
|
|
|
|
utils.single = function single(name) {
|
|
return utils.inflect.singularize(name);
|
|
};
|
|
|
|
/**
|
|
* Pluralize the given `name`
|
|
*/
|
|
|
|
utils.plural = function plural(name) {
|
|
return utils.inflect.pluralize(name);
|
|
};
|
|
|
|
/**
|
|
* Ensure file extensions are formatted properly for lookups.
|
|
*
|
|
* ```js
|
|
* utils.formatExt('hbs');
|
|
* //=> '.hbs'
|
|
*
|
|
* utils.formatExt('.hbs');
|
|
* //=> '.hbs'
|
|
* ```
|
|
*
|
|
* @param {String} `ext` File extension
|
|
* @return {String}
|
|
* @api public
|
|
*/
|
|
|
|
utils.formatExt = function formatExt(ext) {
|
|
if (typeof ext !== 'string') {
|
|
throw new Error('utils.formatExt() expects `ext` to be a string.');
|
|
}
|
|
if (ext.charAt(0) !== '.') {
|
|
return '.' + ext;
|
|
}
|
|
return ext;
|
|
};
|
|
|
|
/**
|
|
* Return true if the given value looks like a
|
|
* `view` object.
|
|
*/
|
|
|
|
utils.isItem = utils.isView = function(val) {
|
|
if (!utils.isObject(val)) return false;
|
|
return val.hasOwnProperty('content')
|
|
|| val.hasOwnProperty('contents')
|
|
|| val.hasOwnProperty('path');
|
|
};
|
|
|
|
/**
|
|
* Get locals from helper arguments.
|
|
*
|
|
* @param {Object} `locals`
|
|
* @param {Object} `options`
|
|
*/
|
|
|
|
utils.getLocals = function(locals, options) {
|
|
options = options || {};
|
|
locals = locals || {};
|
|
var ctx = {};
|
|
|
|
if (options.hasOwnProperty('hash')) {
|
|
utils.extend(ctx, options.hash);
|
|
delete options.hash;
|
|
}
|
|
if (locals.hasOwnProperty('hash')) {
|
|
utils.extend(ctx, locals.hash);
|
|
delete locals.hash;
|
|
}
|
|
utils.extend(ctx, options);
|
|
utils.extend(ctx, locals);
|
|
return ctx;
|
|
};
|
|
|
|
/**
|
|
* Used on `collection` or `app` to resolve the name of the engine to use, or the file
|
|
* extension to use for the engine.
|
|
*
|
|
* If `options.resolveEngine` is a function, it will be
|
|
* used to resolve the engine.
|
|
*
|
|
* @param {Object} `view`
|
|
* @param {Object} `locals`
|
|
* @param {Object} `opts`
|
|
* @return {String}
|
|
*/
|
|
|
|
utils.resolveEngineExt = function(view, locals, opts) {
|
|
var engine = locals.engine || view.engine || opts.engine;
|
|
var fn = opts.resolveEngine
|
|
|| locals.resolveEngine
|
|
|| utils.identity;
|
|
return fn(engine);
|
|
};
|
|
|
|
/**
|
|
* Expose utils
|
|
*/
|
|
|
|
module.exports = utils;
|
|
|