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.
165 lines
3.1 KiB
165 lines
3.1 KiB
4 years ago
|
'use strict';
|
||
|
|
||
|
var isObject = require('isobject');
|
||
|
var path = require('path');
|
||
|
var fs = require('fs');
|
||
|
|
||
|
/**
|
||
|
* Expose `relative`
|
||
|
*/
|
||
|
|
||
|
module.exports = relative;
|
||
|
|
||
|
/**
|
||
|
* Get the relative path from `a` to `b`.
|
||
|
*/
|
||
|
|
||
|
function relative(a, b, stat) {
|
||
|
if (typeof a !== 'string') {
|
||
|
throw new TypeError('relative expects a string.');
|
||
|
}
|
||
|
|
||
|
if (a == '' && !b) return a;
|
||
|
|
||
|
var len = arguments.length;
|
||
|
if (len === 1) {
|
||
|
b = a; a = process.cwd(); stat = null;
|
||
|
}
|
||
|
|
||
|
if (len === 2 && typeof b === 'boolean') {
|
||
|
b = a; a = process.cwd(); stat = true;
|
||
|
}
|
||
|
|
||
|
if (len === 2 && typeof b === 'object') {
|
||
|
stat = b; b = a; a = process.cwd();
|
||
|
}
|
||
|
|
||
|
var origB = b;
|
||
|
|
||
|
// see if a slash exists before normalizing
|
||
|
var slashA = endsWith(a, '/');
|
||
|
var slashB = endsWith(b, '/');
|
||
|
|
||
|
a = unixify(a);
|
||
|
b = unixify(b);
|
||
|
|
||
|
// if `a` had a slash, add it back
|
||
|
if (slashA) { a = a + '/'; }
|
||
|
|
||
|
if (isFile(a, stat)) {
|
||
|
a = path.dirname(a);
|
||
|
}
|
||
|
|
||
|
var res = path.relative(a, b);
|
||
|
if (res === '') {
|
||
|
return '.';
|
||
|
}
|
||
|
|
||
|
// if `b` originally had a slash, and the path ends
|
||
|
// with `b` missing a slash, then re-add the slash.
|
||
|
var noslash = trimEnd(origB, '/');
|
||
|
if (slashB && (res === noslash || endsWith(res, noslash))) {
|
||
|
res = res + '/';
|
||
|
}
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the path relative to the given base path.
|
||
|
*/
|
||
|
|
||
|
relative.toBase = function toBase(base, fp) {
|
||
|
base = unixify(base);
|
||
|
fp = unixify(fp);
|
||
|
|
||
|
var res = fp.slice(base.length);
|
||
|
if (res.charAt(0) === '/') {
|
||
|
res = res.slice(1);
|
||
|
}
|
||
|
return res;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Normalize slashes in paths to unix slashes. This is necessary since
|
||
|
* paths are not calculated the same by node.js when
|
||
|
* windows paths are used.
|
||
|
*/
|
||
|
|
||
|
function unixify(str) {
|
||
|
return str.replace(/[\\\/]+/g, '/');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Remove the given character from the path.
|
||
|
*/
|
||
|
|
||
|
function trimEnd(fp, ch) {
|
||
|
return fp.slice(0, fp.length - ch.length);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Does the path end with the given `ch`aracter?
|
||
|
*/
|
||
|
|
||
|
function endsWith(fp, ch) {
|
||
|
return fp.slice(-ch.length)[0] === ch;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* If `fp` exists, return a `stat` object,
|
||
|
* otherwise return `null`.
|
||
|
*/
|
||
|
|
||
|
function tryStats(fp) {
|
||
|
try {
|
||
|
return fs.statSync(fp);
|
||
|
} catch(err) {}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns true if `fp` is a directory. To use a `fs`
|
||
|
* stat object to actually check the file system,
|
||
|
* either pass `true` as the second arg, or pass your
|
||
|
* own stat object as the second arg.
|
||
|
*
|
||
|
* @param {String} `fp`
|
||
|
* @param {Boolean|Object} `stat`
|
||
|
* @return {Boolean}
|
||
|
*/
|
||
|
|
||
|
function isDir(fp, stat) {
|
||
|
if (endsWith(fp, '/')) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (stat === null) {
|
||
|
// try to get the directory info if it hasn't been done yet
|
||
|
// to ensure directories containing dots are well handle
|
||
|
stat = tryStats(fp);
|
||
|
}
|
||
|
|
||
|
if (isObject(stat) && typeof stat.isDirectory === 'function') {
|
||
|
return stat.isDirectory();
|
||
|
}
|
||
|
|
||
|
var segs = fp.split('/');
|
||
|
var last = segs[segs.length - 1];
|
||
|
if (last && last.indexOf('.') !== -1) {
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return true if `fp` looks like a file, or
|
||
|
* actually is a file if fs.stat is used.
|
||
|
*/
|
||
|
|
||
|
function isFile(fp, stat) {
|
||
|
if (stat === true) {
|
||
|
stat = tryStats(fp);
|
||
|
}
|
||
|
return !isDir(fp, stat);
|
||
|
}
|