整理桌面

This commit is contained in:
satori 2022-04-10 00:38:45 +08:00
parent e25c8bb318
commit 5c7adaf68a
718 changed files with 0 additions and 985790 deletions

1
node_modules/.bin/esbuild generated vendored
View File

@ -1 +0,0 @@
../esbuild/bin/esbuild

1
node_modules/.bin/nanoid generated vendored
View File

@ -1 +0,0 @@
../nanoid/bin/nanoid.cjs

1
node_modules/.bin/rollup generated vendored
View File

@ -1 +0,0 @@
../rollup/dist/bin/rollup

1
node_modules/.bin/vite generated vendored
View File

@ -1 +0,0 @@
../vite/bin/vite.js

21
node_modules/.vite/_metadata.json generated vendored
View File

@ -1,21 +0,0 @@
{
"hash": "ee5cc2cf",
"browserHash": "7292be66",
"optimized": {
"neataptic": {
"file": "/home/satori/sakuya/node_modules/.vite/neataptic.js",
"src": "/home/satori/sakuya/node_modules/neataptic/src/neataptic.js",
"needsInterop": true
},
"frappe-charts": {
"file": "/home/satori/sakuya/node_modules/.vite/frappe-charts.js",
"src": "/home/satori/sakuya/node_modules/frappe-charts/dist/frappe-charts.min.esm.js",
"needsInterop": false
},
"p5": {
"file": "/home/satori/sakuya/node_modules/.vite/p5.js",
"src": "/home/satori/sakuya/node_modules/p5/lib/p5.min.js",
"needsInterop": true
}
}
}

28
node_modules/.vite/chunk-ELXAK55F.js generated vendored
View File

@ -1,28 +0,0 @@
var __defProp = Object.defineProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined")
return require.apply(this, arguments);
throw new Error('Dynamic require of "' + x + '" is not supported');
});
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[Object.keys(fn)[0]])(fn = 0)), res;
};
var __commonJS = (cb, mod) => function __require2() {
return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
__markAsModule(target);
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
export {
__require,
__esm,
__commonJS,
__export
};
//# sourceMappingURL=chunk-ELXAK55F.js.map

View File

@ -1,7 +0,0 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}

1988
node_modules/.vite/frappe-charts.js generated vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

3032
node_modules/.vite/neataptic.js generated vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

17062
node_modules/.vite/p5.js generated vendored

File diff suppressed because one or more lines are too long

7
node_modules/.vite/p5.js.map generated vendored

File diff suppressed because one or more lines are too long

1
node_modules/.vite/package.json generated vendored
View File

@ -1 +0,0 @@
{"type":"module"}

53
node_modules/.yarn-integrity generated vendored
View File

@ -1,53 +0,0 @@
{
"systemParams": "linux-x64-83",
"modulesFolders": [
"node_modules"
],
"flags": [],
"linkedModules": [
"fiora"
],
"topLevelPatterns": [
"frappe-charts@^1.6.2",
"neataptic@^1.4.7",
"p5@^1.4.0",
"vite@^2.6.4"
],
"lockfileEntries": {
"esbuild-android-arm64@0.13.15": "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz#3fc3ff0bab76fe35dd237476b5d2b32bb20a3d44",
"esbuild-darwin-64@0.13.15": "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.13.15.tgz#8e9169c16baf444eacec60d09b24d11b255a8e72",
"esbuild-darwin-arm64@0.13.15": "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.15.tgz#1b07f893b632114f805e188ddfca41b2b778229a",
"esbuild-freebsd-64@0.13.15": "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.15.tgz#0b8b7eca1690c8ec94c75680c38c07269c1f4a85",
"esbuild-freebsd-arm64@0.13.15": "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.15.tgz#2e1a6c696bfdcd20a99578b76350b41db1934e52",
"esbuild-linux-32@0.13.15": "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.13.15.tgz#6fd39f36fc66dd45b6b5f515728c7bbebc342a69",
"esbuild-linux-64@0.13.15": "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.13.15.tgz#9cb8e4bcd7574e67946e4ee5f1f1e12386bb6dd3",
"esbuild-linux-arm64@0.13.15": "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.15.tgz#3891aa3704ec579a1b92d2a586122e5b6a2bfba1",
"esbuild-linux-arm@0.13.15": "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.13.15.tgz#8a00e99e6a0c6c9a6b7f334841364d8a2b4aecfe",
"esbuild-linux-mips64le@0.13.15": "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.15.tgz#36b07cc47c3d21e48db3bb1f4d9ef8f46aead4f7",
"esbuild-linux-ppc64le@0.13.15": "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.15.tgz#f7e6bba40b9a11eb9dcae5b01550ea04670edad2",
"esbuild-netbsd-64@0.13.15": "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.15.tgz#a2fedc549c2b629d580a732d840712b08d440038",
"esbuild-openbsd-64@0.13.15": "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.15.tgz#b22c0e5806d3a1fbf0325872037f885306b05cd7",
"esbuild-sunos-64@0.13.15": "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.13.15.tgz#d0b6454a88375ee8d3964daeff55c85c91c7cef4",
"esbuild-windows-32@0.13.15": "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.13.15.tgz#c96d0b9bbb52f3303322582ef8e4847c5ad375a7",
"esbuild-windows-64@0.13.15": "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.13.15.tgz#1f79cb9b1e1bb02fb25cd414cb90d4ea2892c294",
"esbuild-windows-arm64@0.13.15": "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.15.tgz#482173070810df22a752c686509c370c3be3b3c3",
"esbuild@^0.13.2": "https://registry.yarnpkg.com/esbuild/-/esbuild-0.13.15.tgz#db56a88166ee373f87dbb2d8798ff449e0450cdf",
"frappe-charts@^1.6.2": "https://registry.yarnpkg.com/frappe-charts/-/frappe-charts-1.6.2.tgz#4671a943a8606e5020180fa65c8ea1835c510baf",
"fsevents@~2.3.2": "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a",
"function-bind@^1.1.1": "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d",
"has@^1.0.3": "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796",
"is-core-module@^2.2.0": "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548",
"nanoid@^3.1.30": "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362",
"neataptic@^1.4.7": "https://registry.yarnpkg.com/neataptic/-/neataptic-1.4.7.tgz#88cc00df1915572fe1af61652e3b1f87a7f50e74",
"p5@^1.4.0": "https://registry.yarnpkg.com/p5/-/p5-1.4.0.tgz#d4d0f001c297525831861af5e017cdb5ef517a75",
"path-parse@^1.0.6": "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735",
"picocolors@^1.0.0": "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c",
"postcss@^8.3.8": "https://registry.yarnpkg.com/postcss/-/postcss-8.4.1.tgz#73051f825509ad1a716ef500108001bf3d1fa8f7",
"resolve@^1.20.0": "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975",
"rollup@^2.57.0": "https://registry.yarnpkg.com/rollup/-/rollup-2.60.1.tgz#4b34cd247f09b421f10a3c9286eda2ecf9972079",
"source-map-js@^1.0.1": "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf",
"vite@^2.6.4": "https://registry.yarnpkg.com/vite/-/vite-2.6.14.tgz#35c09a15e4df823410819a2a239ab11efb186271"
},
"files": [],
"artifacts": {}
}

View File

@ -1,3 +0,0 @@
# esbuild
This is the Linux 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.

Binary file not shown.

View File

@ -1,14 +0,0 @@
{
"name": "esbuild-linux-64",
"version": "0.13.15",
"description": "The Linux 64-bit binary for esbuild, a JavaScript bundler.",
"repository": "https://github.com/evanw/esbuild",
"license": "MIT",
"preferUnplugged": false,
"os": [
"linux"
],
"cpu": [
"x64"
]
}

3
node_modules/esbuild/README.md generated vendored
View File

@ -1,3 +0,0 @@
# esbuild
This is a JavaScript bundler and minifier. See https://github.com/evanw/esbuild and the [JavaScript API documentation](https://esbuild.github.io/api/) for details.

108
node_modules/esbuild/bin/esbuild generated vendored
View File

@ -1,108 +0,0 @@
#!/usr/bin/env node
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
// lib/npm/node-platform.ts
var fs = require("fs");
var os = require("os");
var path = require("path");
var ESBUILD_BINARY_PATH = process.env.ESBUILD_BINARY_PATH || ESBUILD_BINARY_PATH;
var knownWindowsPackages = {
"win32 arm64 LE": "esbuild-windows-arm64",
"win32 ia32 LE": "esbuild-windows-32",
"win32 x64 LE": "esbuild-windows-64"
};
var knownUnixlikePackages = {
"android arm64 LE": "esbuild-android-arm64",
"darwin arm64 LE": "esbuild-darwin-arm64",
"darwin x64 LE": "esbuild-darwin-64",
"freebsd arm64 LE": "esbuild-freebsd-arm64",
"freebsd x64 LE": "esbuild-freebsd-64",
"linux arm LE": "esbuild-linux-arm",
"linux arm64 LE": "esbuild-linux-arm64",
"linux ia32 LE": "esbuild-linux-32",
"linux mips64el LE": "esbuild-linux-mips64le",
"linux ppc64 LE": "esbuild-linux-ppc64le",
"linux x64 LE": "esbuild-linux-64",
"netbsd x64 LE": "esbuild-netbsd-64",
"openbsd x64 LE": "esbuild-openbsd-64",
"sunos x64 LE": "esbuild-sunos-64"
};
function pkgAndSubpathForCurrentPlatform() {
let pkg;
let subpath;
let platformKey = `${process.platform} ${os.arch()} ${os.endianness()}`;
if (platformKey in knownWindowsPackages) {
pkg = knownWindowsPackages[platformKey];
subpath = "esbuild.exe";
} else if (platformKey in knownUnixlikePackages) {
pkg = knownUnixlikePackages[platformKey];
subpath = "bin/esbuild";
} else {
throw new Error(`Unsupported platform: ${platformKey}`);
}
return { pkg, subpath };
}
function downloadedBinPath(pkg, subpath) {
const esbuildLibDir = path.dirname(require.resolve("esbuild"));
return path.join(esbuildLibDir, `downloaded-${pkg}-${path.basename(subpath)}`);
}
function generateBinPath() {
if (ESBUILD_BINARY_PATH) {
return ESBUILD_BINARY_PATH;
}
const { pkg, subpath } = pkgAndSubpathForCurrentPlatform();
let binPath;
try {
binPath = require.resolve(`${pkg}/${subpath}`);
} catch (e) {
binPath = downloadedBinPath(pkg, subpath);
if (!fs.existsSync(binPath)) {
try {
require.resolve(pkg);
} catch {
throw new Error(`The package "${pkg}" could not be found, and is needed by esbuild.
If you are installing esbuild with npm, make sure that you don't specify the
"--no-optional" flag. The "optionalDependencies" package.json feature is used
by esbuild to install the correct binary executable for your current platform.`);
}
throw e;
}
}
let isYarnPnP = false;
try {
require("pnpapi");
isYarnPnP = true;
} catch (e) {
}
if (isYarnPnP) {
const esbuildLibDir = path.dirname(require.resolve("esbuild"));
const binTargetPath = path.join(esbuildLibDir, `pnpapi-${pkg}-${path.basename(subpath)}`);
if (!fs.existsSync(binTargetPath)) {
fs.copyFileSync(binPath, binTargetPath);
fs.chmodSync(binTargetPath, 493);
}
return binTargetPath;
}
return binPath;
}
// lib/npm/node-shim.ts
require("child_process").execFileSync(generateBinPath(), process.argv.slice(2), { stdio: "inherit" });

244
node_modules/esbuild/install.js generated vendored
View File

@ -1,244 +0,0 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
// lib/npm/node-platform.ts
var fs = require("fs");
var os = require("os");
var path = require("path");
var ESBUILD_BINARY_PATH = process.env.ESBUILD_BINARY_PATH || ESBUILD_BINARY_PATH;
var knownWindowsPackages = {
"win32 arm64 LE": "esbuild-windows-arm64",
"win32 ia32 LE": "esbuild-windows-32",
"win32 x64 LE": "esbuild-windows-64"
};
var knownUnixlikePackages = {
"android arm64 LE": "esbuild-android-arm64",
"darwin arm64 LE": "esbuild-darwin-arm64",
"darwin x64 LE": "esbuild-darwin-64",
"freebsd arm64 LE": "esbuild-freebsd-arm64",
"freebsd x64 LE": "esbuild-freebsd-64",
"linux arm LE": "esbuild-linux-arm",
"linux arm64 LE": "esbuild-linux-arm64",
"linux ia32 LE": "esbuild-linux-32",
"linux mips64el LE": "esbuild-linux-mips64le",
"linux ppc64 LE": "esbuild-linux-ppc64le",
"linux x64 LE": "esbuild-linux-64",
"netbsd x64 LE": "esbuild-netbsd-64",
"openbsd x64 LE": "esbuild-openbsd-64",
"sunos x64 LE": "esbuild-sunos-64"
};
function pkgAndSubpathForCurrentPlatform() {
let pkg;
let subpath;
let platformKey = `${process.platform} ${os.arch()} ${os.endianness()}`;
if (platformKey in knownWindowsPackages) {
pkg = knownWindowsPackages[platformKey];
subpath = "esbuild.exe";
} else if (platformKey in knownUnixlikePackages) {
pkg = knownUnixlikePackages[platformKey];
subpath = "bin/esbuild";
} else {
throw new Error(`Unsupported platform: ${platformKey}`);
}
return { pkg, subpath };
}
function downloadedBinPath(pkg, subpath) {
const esbuildLibDir = path.dirname(require.resolve("esbuild"));
return path.join(esbuildLibDir, `downloaded-${pkg}-${path.basename(subpath)}`);
}
// lib/npm/node-install.ts
var fs2 = require("fs");
var os2 = require("os");
var path2 = require("path");
var zlib = require("zlib");
var https = require("https");
var child_process = require("child_process");
var toPath = path2.join(__dirname, "bin", "esbuild");
var isToPathJS = true;
function validateBinaryVersion(...command) {
command.push("--version");
const stdout = child_process.execFileSync(command.shift(), command).toString().trim();
if (stdout !== "0.13.15") {
throw new Error(`Expected ${JSON.stringify("0.13.15")} but got ${JSON.stringify(stdout)}`);
}
}
function isYarn() {
const { npm_config_user_agent } = process.env;
if (npm_config_user_agent) {
return /\byarn\//.test(npm_config_user_agent);
}
return false;
}
function fetch(url) {
return new Promise((resolve, reject) => {
https.get(url, (res) => {
if ((res.statusCode === 301 || res.statusCode === 302) && res.headers.location)
return fetch(res.headers.location).then(resolve, reject);
if (res.statusCode !== 200)
return reject(new Error(`Server responded with ${res.statusCode}`));
let chunks = [];
res.on("data", (chunk) => chunks.push(chunk));
res.on("end", () => resolve(Buffer.concat(chunks)));
}).on("error", reject);
});
}
function extractFileFromTarGzip(buffer, subpath) {
try {
buffer = zlib.unzipSync(buffer);
} catch (err) {
throw new Error(`Invalid gzip data in archive: ${err && err.message || err}`);
}
let str = (i, n) => String.fromCharCode(...buffer.subarray(i, i + n)).replace(/\0.*$/, "");
let offset = 0;
subpath = `package/${subpath}`;
while (offset < buffer.length) {
let name = str(offset, 100);
let size = parseInt(str(offset + 124, 12), 8);
offset += 512;
if (!isNaN(size)) {
if (name === subpath)
return buffer.subarray(offset, offset + size);
offset += size + 511 & ~511;
}
}
throw new Error(`Could not find ${JSON.stringify(subpath)} in archive`);
}
function installUsingNPM(pkg, subpath, binPath) {
const env = __spreadProps(__spreadValues({}, process.env), { npm_config_global: void 0 });
const esbuildLibDir = path2.dirname(require.resolve("esbuild"));
const installDir = path2.join(esbuildLibDir, "npm-install");
fs2.mkdirSync(installDir);
try {
fs2.writeFileSync(path2.join(installDir, "package.json"), "{}");
child_process.execSync(`npm install --loglevel=error --prefer-offline --no-audit --progress=false ${pkg}@${"0.13.15"}`, { cwd: installDir, stdio: "pipe", env });
const installedBinPath = path2.join(installDir, "node_modules", pkg, subpath);
fs2.renameSync(installedBinPath, binPath);
} finally {
try {
removeRecursive(installDir);
} catch {
}
}
}
function removeRecursive(dir) {
for (const entry of fs2.readdirSync(dir)) {
const entryPath = path2.join(dir, entry);
let stats;
try {
stats = fs2.lstatSync(entryPath);
} catch {
continue;
}
if (stats.isDirectory())
removeRecursive(entryPath);
else
fs2.unlinkSync(entryPath);
}
fs2.rmdirSync(dir);
}
function applyManualBinaryPathOverride(overridePath) {
const pathString = JSON.stringify(overridePath);
fs2.writeFileSync(toPath, `#!/usr/bin/env node
require('child_process').execFileSync(${pathString}, process.argv.slice(2), { stdio: 'inherit' });
`);
const libMain = path2.join(__dirname, "lib", "main.js");
const code = fs2.readFileSync(libMain, "utf8");
fs2.writeFileSync(libMain, `var ESBUILD_BINARY_PATH = ${pathString};
${code}`);
}
function maybeOptimizePackage(binPath) {
if (os2.platform() !== "win32" && !isYarn()) {
const tempPath = path2.join(__dirname, "bin-esbuild");
try {
fs2.linkSync(binPath, tempPath);
fs2.renameSync(tempPath, toPath);
isToPathJS = false;
fs2.unlinkSync(tempPath);
} catch {
}
}
}
async function downloadDirectlyFromNPM(pkg, subpath, binPath) {
const url = `https://registry.npmjs.org/${pkg}/-/${pkg}-${"0.13.15"}.tgz`;
console.error(`[esbuild] Trying to download ${JSON.stringify(url)}`);
try {
fs2.writeFileSync(binPath, extractFileFromTarGzip(await fetch(url), subpath));
fs2.chmodSync(binPath, 493);
} catch (e) {
console.error(`[esbuild] Failed to download ${JSON.stringify(url)}: ${e && e.message || e}`);
throw e;
}
}
async function checkAndPreparePackage() {
if (ESBUILD_BINARY_PATH) {
applyManualBinaryPathOverride(ESBUILD_BINARY_PATH);
return;
}
const { pkg, subpath } = pkgAndSubpathForCurrentPlatform();
let binPath;
try {
binPath = require.resolve(`${pkg}/${subpath}`);
} catch (e) {
console.error(`[esbuild] Failed to find package "${pkg}" on the file system
This can happen if you use the "--no-optional" flag. The "optionalDependencies"
package.json feature is used by esbuild to install the correct binary executable
for your current platform. This install script will now attempt to work around
this. If that fails, you need to remove the "--no-optional" flag to use esbuild.
`);
binPath = downloadedBinPath(pkg, subpath);
try {
console.error(`[esbuild] Trying to install package "${pkg}" using npm`);
installUsingNPM(pkg, subpath, binPath);
} catch (e2) {
console.error(`[esbuild] Failed to install package "${pkg}" using npm: ${e2 && e2.message || e2}`);
try {
await downloadDirectlyFromNPM(pkg, subpath, binPath);
} catch (e3) {
throw new Error(`Failed to install package "${pkg}"`);
}
}
}
maybeOptimizePackage(binPath);
}
checkAndPreparePackage().then(() => {
if (isToPathJS) {
validateBinaryVersion("node", toPath);
} else {
validateBinaryVersion(toPath);
}
});

524
node_modules/esbuild/lib/main.d.ts generated vendored
View File

@ -1,524 +0,0 @@
export type Platform = 'browser' | 'node' | 'neutral';
export type Format = 'iife' | 'cjs' | 'esm';
export type Loader = 'js' | 'jsx' | 'ts' | 'tsx' | 'css' | 'json' | 'text' | 'base64' | 'file' | 'dataurl' | 'binary' | 'default';
export type LogLevel = 'verbose' | 'debug' | 'info' | 'warning' | 'error' | 'silent';
export type Charset = 'ascii' | 'utf8';
interface CommonOptions {
/** Documentation: https://esbuild.github.io/api/#sourcemap */
sourcemap?: boolean | 'inline' | 'external' | 'both';
/** Documentation: https://esbuild.github.io/api/#legal-comments */
legalComments?: 'none' | 'inline' | 'eof' | 'linked' | 'external';
/** Documentation: https://esbuild.github.io/api/#source-root */
sourceRoot?: string;
/** Documentation: https://esbuild.github.io/api/#sources-content */
sourcesContent?: boolean;
/** Documentation: https://esbuild.github.io/api/#format */
format?: Format;
/** Documentation: https://esbuild.github.io/api/#globalName */
globalName?: string;
/** Documentation: https://esbuild.github.io/api/#target */
target?: string | string[];
/** Documentation: https://esbuild.github.io/api/#minify */
minify?: boolean;
/** Documentation: https://esbuild.github.io/api/#minify */
minifyWhitespace?: boolean;
/** Documentation: https://esbuild.github.io/api/#minify */
minifyIdentifiers?: boolean;
/** Documentation: https://esbuild.github.io/api/#minify */
minifySyntax?: boolean;
/** Documentation: https://esbuild.github.io/api/#charset */
charset?: Charset;
/** Documentation: https://esbuild.github.io/api/#tree-shaking */
treeShaking?: boolean;
/** Documentation: https://esbuild.github.io/api/#ignore-annotations */
ignoreAnnotations?: boolean;
/** Documentation: https://esbuild.github.io/api/#jsx */
jsx?: 'transform' | 'preserve';
/** Documentation: https://esbuild.github.io/api/#jsx-factory */
jsxFactory?: string;
/** Documentation: https://esbuild.github.io/api/#jsx-fragment */
jsxFragment?: string;
/** Documentation: https://esbuild.github.io/api/#define */
define?: { [key: string]: string };
/** Documentation: https://esbuild.github.io/api/#pure */
pure?: string[];
/** Documentation: https://esbuild.github.io/api/#keep-names */
keepNames?: boolean;
/** Documentation: https://esbuild.github.io/api/#color */
color?: boolean;
/** Documentation: https://esbuild.github.io/api/#log-level */
logLevel?: LogLevel;
/** Documentation: https://esbuild.github.io/api/#log-limit */
logLimit?: number;
}
export interface BuildOptions extends CommonOptions {
/** Documentation: https://esbuild.github.io/api/#bundle */
bundle?: boolean;
/** Documentation: https://esbuild.github.io/api/#splitting */
splitting?: boolean;
/** Documentation: https://esbuild.github.io/api/#preserve-symlinks */
preserveSymlinks?: boolean;
/** Documentation: https://esbuild.github.io/api/#outfile */
outfile?: string;
/** Documentation: https://esbuild.github.io/api/#metafile */
metafile?: boolean;
/** Documentation: https://esbuild.github.io/api/#outdir */
outdir?: string;
/** Documentation: https://esbuild.github.io/api/#outbase */
outbase?: string;
/** Documentation: https://esbuild.github.io/api/#platform */
platform?: Platform;
/** Documentation: https://esbuild.github.io/api/#external */
external?: string[];
/** Documentation: https://esbuild.github.io/api/#loader */
loader?: { [ext: string]: Loader };
/** Documentation: https://esbuild.github.io/api/#resolve-extensions */
resolveExtensions?: string[];
/** Documentation: https://esbuild.github.io/api/#mainFields */
mainFields?: string[];
/** Documentation: https://esbuild.github.io/api/#conditions */
conditions?: string[];
/** Documentation: https://esbuild.github.io/api/#write */
write?: boolean;
/** Documentation: https://esbuild.github.io/api/#allow-overwrite */
allowOverwrite?: boolean;
/** Documentation: https://esbuild.github.io/api/#tsconfig */
tsconfig?: string;
/** Documentation: https://esbuild.github.io/api/#out-extension */
outExtension?: { [ext: string]: string };
/** Documentation: https://esbuild.github.io/api/#public-path */
publicPath?: string;
/** Documentation: https://esbuild.github.io/api/#entry-names */
entryNames?: string;
/** Documentation: https://esbuild.github.io/api/#chunk-names */
chunkNames?: string;
/** Documentation: https://esbuild.github.io/api/#asset-names */
assetNames?: string;
/** Documentation: https://esbuild.github.io/api/#inject */
inject?: string[];
/** Documentation: https://esbuild.github.io/api/#banner */
banner?: { [type: string]: string };
/** Documentation: https://esbuild.github.io/api/#footer */
footer?: { [type: string]: string };
/** Documentation: https://esbuild.github.io/api/#incremental */
incremental?: boolean;
/** Documentation: https://esbuild.github.io/api/#entry-points */
entryPoints?: string[] | Record<string, string>;
/** Documentation: https://esbuild.github.io/api/#stdin */
stdin?: StdinOptions;
/** Documentation: https://esbuild.github.io/plugins/ */
plugins?: Plugin[];
/** Documentation: https://esbuild.github.io/api/#working-directory */
absWorkingDir?: string;
/** Documentation: https://esbuild.github.io/api/#node-paths */
nodePaths?: string[]; // The "NODE_PATH" variable from Node.js
/** Documentation: https://esbuild.github.io/api/#watch */
watch?: boolean | WatchMode;
}
export interface WatchMode {
onRebuild?: (error: BuildFailure | null, result: BuildResult | null) => void;
}
export interface StdinOptions {
contents: string;
resolveDir?: string;
sourcefile?: string;
loader?: Loader;
}
export interface Message {
pluginName: string;
text: string;
location: Location | null;
notes: Note[];
/**
* Optional user-specified data that is passed through unmodified. You can
* use this to stash the original error, for example.
*/
detail: any;
}
export interface Note {
text: string;
location: Location | null;
}
export interface Location {
file: string;
namespace: string;
/** 1-based */
line: number;
/** 0-based, in bytes */
column: number;
/** in bytes */
length: number;
lineText: string;
suggestion: string;
}
export interface OutputFile {
path: string;
/** "text" as bytes */
contents: Uint8Array;
/** "contents" as text */
text: string;
}
export interface BuildInvalidate {
(): Promise<BuildIncremental>;
dispose(): void;
}
export interface BuildIncremental extends BuildResult {
rebuild: BuildInvalidate;
}
export interface BuildResult {
errors: Message[];
warnings: Message[];
/** Only when "write: false" */
outputFiles?: OutputFile[];
/** Only when "incremental: true" */
rebuild?: BuildInvalidate;
/** Only when "watch: true" */
stop?: () => void;
/** Only when "metafile: true" */
metafile?: Metafile;
}
export interface BuildFailure extends Error {
errors: Message[];
warnings: Message[];
}
/** Documentation: https://esbuild.github.io/api/#serve-arguments */
export interface ServeOptions {
port?: number;
host?: string;
servedir?: string;
onRequest?: (args: ServeOnRequestArgs) => void;
}
export interface ServeOnRequestArgs {
remoteAddress: string;
method: string;
path: string;
status: number;
/** The time to generate the response, not to send it */
timeInMS: number;
}
/** Documentation: https://esbuild.github.io/api/#serve-return-values */
export interface ServeResult {
port: number;
host: string;
wait: Promise<void>;
stop: () => void;
}
export interface TransformOptions extends CommonOptions {
tsconfigRaw?: string | {
compilerOptions?: {
jsxFactory?: string,
jsxFragmentFactory?: string,
useDefineForClassFields?: boolean,
importsNotUsedAsValues?: 'remove' | 'preserve' | 'error',
},
};
sourcefile?: string;
loader?: Loader;
banner?: string;
footer?: string;
}
export interface TransformResult {
code: string;
map: string;
warnings: Message[];
}
export interface TransformFailure extends Error {
errors: Message[];
warnings: Message[];
}
export interface Plugin {
name: string;
setup: (build: PluginBuild) => (void | Promise<void>);
}
export interface PluginBuild {
initialOptions: BuildOptions;
onStart(callback: () =>
(OnStartResult | null | void | Promise<OnStartResult | null | void>)): void;
onEnd(callback: (result: BuildResult) =>
(void | Promise<void>)): void;
onResolve(options: OnResolveOptions, callback: (args: OnResolveArgs) =>
(OnResolveResult | null | undefined | Promise<OnResolveResult | null | undefined>)): void;
onLoad(options: OnLoadOptions, callback: (args: OnLoadArgs) =>
(OnLoadResult | null | undefined | Promise<OnLoadResult | null | undefined>)): void;
}
export interface OnStartResult {
errors?: PartialMessage[];
warnings?: PartialMessage[];
}
export interface OnResolveOptions {
filter: RegExp;
namespace?: string;
}
export interface OnResolveArgs {
path: string;
importer: string;
namespace: string;
resolveDir: string;
kind: ImportKind;
pluginData: any;
}
export type ImportKind =
| 'entry-point'
// JS
| 'import-statement'
| 'require-call'
| 'dynamic-import'
| 'require-resolve'
// CSS
| 'import-rule'
| 'url-token'
export interface OnResolveResult {
pluginName?: string;
errors?: PartialMessage[];
warnings?: PartialMessage[];
path?: string;
external?: boolean;
sideEffects?: boolean;
namespace?: string;
pluginData?: any;
watchFiles?: string[];
watchDirs?: string[];
}
export interface OnLoadOptions {
filter: RegExp;
namespace?: string;
}
export interface OnLoadArgs {
path: string;
namespace: string;
pluginData: any;
}
export interface OnLoadResult {
pluginName?: string;
errors?: PartialMessage[];
warnings?: PartialMessage[];
contents?: string | Uint8Array;
resolveDir?: string;
loader?: Loader;
pluginData?: any;
watchFiles?: string[];
watchDirs?: string[];
}
export interface PartialMessage {
pluginName?: string;
text?: string;
location?: Partial<Location> | null;
notes?: PartialNote[];
detail?: any;
}
export interface PartialNote {
text?: string;
location?: Partial<Location> | null;
}
export interface Metafile {
inputs: {
[path: string]: {
bytes: number
imports: {
path: string
kind: ImportKind
}[]
}
}
outputs: {
[path: string]: {
bytes: number
inputs: {
[path: string]: {
bytesInOutput: number
}
}
imports: {
path: string
kind: ImportKind
}[]
exports: string[]
entryPoint?: string
}
}
}
export interface FormatMessagesOptions {
kind: 'error' | 'warning';
color?: boolean;
terminalWidth?: number;
}
export interface AnalyzeMetafileOptions {
color?: boolean;
verbose?: boolean;
}
/**
* This function invokes the "esbuild" command-line tool for you. It returns a
* promise that either resolves with a "BuildResult" object or rejects with a
* "BuildFailure" object.
*
* - Works in node: yes
* - Works in browser: yes
*
* Documentation: https://esbuild.github.io/api/#build-api
*/
export declare function build(options: BuildOptions & { write: false }): Promise<BuildResult & { outputFiles: OutputFile[] }>;
export declare function build(options: BuildOptions & { incremental: true }): Promise<BuildIncremental>;
export declare function build(options: BuildOptions): Promise<BuildResult>;
/**
* This function is similar to "build" but it serves the resulting files over
* HTTP on a localhost address with the specified port.
*
* - Works in node: yes
* - Works in browser: no
*
* Documentation: https://esbuild.github.io/api/#serve
*/
export declare function serve(serveOptions: ServeOptions, buildOptions: BuildOptions): Promise<ServeResult>;
/**
* This function transforms a single JavaScript file. It can be used to minify
* JavaScript, convert TypeScript/JSX to JavaScript, or convert newer JavaScript
* to older JavaScript. It returns a promise that is either resolved with a
* "TransformResult" object or rejected with a "TransformFailure" object.
*
* - Works in node: yes
* - Works in browser: yes
*
* Documentation: https://esbuild.github.io/api/#transform-api
*/
export declare function transform(input: string, options?: TransformOptions): Promise<TransformResult>;
/**
* Converts log messages to formatted message strings suitable for printing in
* the terminal. This allows you to reuse the built-in behavior of esbuild's
* log message formatter. This is a batch-oriented API for efficiency.
*
* - Works in node: yes
* - Works in browser: yes
*/
export declare function formatMessages(messages: PartialMessage[], options: FormatMessagesOptions): Promise<string[]>;
/**
* Pretty-prints an analysis of the metafile JSON to a string. This is just for
* convenience to be able to match esbuild's pretty-printing exactly. If you want
* to customize it, you can just inspect the data in the metafile yourself.
*
* - Works in node: yes
* - Works in browser: yes
*
* Documentation: https://esbuild.github.io/api/#analyze
*/
export declare function analyzeMetafile(metafile: Metafile | string, options?: AnalyzeMetafileOptions): Promise<string>;
/**
* A synchronous version of "build".
*
* - Works in node: yes
* - Works in browser: no
*
* Documentation: https://esbuild.github.io/api/#build-api
*/
export declare function buildSync(options: BuildOptions & { write: false }): BuildResult & { outputFiles: OutputFile[] };
export declare function buildSync(options: BuildOptions): BuildResult;
/**
* A synchronous version of "transform".
*
* - Works in node: yes
* - Works in browser: no
*
* Documentation: https://esbuild.github.io/api/#transform-api
*/
export declare function transformSync(input: string, options?: TransformOptions): TransformResult;
/**
* A synchronous version of "formatMessages".
*
* - Works in node: yes
* - Works in browser: no
*/
export declare function formatMessagesSync(messages: PartialMessage[], options: FormatMessagesOptions): string[];
/**
* A synchronous version of "analyzeMetafile".
*
* - Works in node: yes
* - Works in browser: no
*
* Documentation: https://esbuild.github.io/api/#analyze
*/
export declare function analyzeMetafileSync(metafile: Metafile | string, options?: AnalyzeMetafileOptions): string;
/**
* This configures the browser-based version of esbuild. It is necessary to
* call this first and wait for the returned promise to be resolved before
* making other API calls when using esbuild in the browser.
*
* - Works in node: yes
* - Works in browser: yes ("options" is required)
*
* Documentation: https://esbuild.github.io/api/#running-in-the-browser
*/
export declare function initialize(options: InitializeOptions): Promise<void>;
export interface InitializeOptions {
/**
* The URL of the "esbuild.wasm" file. This must be provided when running
* esbuild in the browser.
*/
wasmURL?: string
/**
* By default esbuild runs the WebAssembly-based browser API in a web worker
* to avoid blocking the UI thread. This can be disabled by setting "worker"
* to false.
*/
worker?: boolean
}
export let version: string;

2108
node_modules/esbuild/lib/main.js generated vendored

File diff suppressed because it is too large Load Diff

34
node_modules/esbuild/package.json generated vendored
View File

@ -1,34 +0,0 @@
{
"name": "esbuild",
"version": "0.13.15",
"description": "An extremely fast JavaScript and CSS bundler and minifier.",
"repository": "https://github.com/evanw/esbuild",
"scripts": {
"postinstall": "node install.js"
},
"main": "lib/main.js",
"types": "lib/main.d.ts",
"bin": {
"esbuild": "bin/esbuild"
},
"optionalDependencies": {
"esbuild-android-arm64": "0.13.15",
"esbuild-darwin-64": "0.13.15",
"esbuild-darwin-arm64": "0.13.15",
"esbuild-freebsd-64": "0.13.15",
"esbuild-freebsd-arm64": "0.13.15",
"esbuild-linux-32": "0.13.15",
"esbuild-linux-64": "0.13.15",
"esbuild-linux-arm": "0.13.15",
"esbuild-linux-arm64": "0.13.15",
"esbuild-linux-mips64le": "0.13.15",
"esbuild-linux-ppc64le": "0.13.15",
"esbuild-netbsd-64": "0.13.15",
"esbuild-openbsd-64": "0.13.15",
"esbuild-sunos-64": "0.13.15",
"esbuild-windows-32": "0.13.15",
"esbuild-windows-64": "0.13.15",
"esbuild-windows-arm64": "0.13.15"
},
"license": "MIT"
}

21
node_modules/frappe-charts/LICENSE generated vendored
View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2017 Prateeksha Singh
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

121
node_modules/frappe-charts/README.md generated vendored
View File

@ -1,121 +0,0 @@
<div align="center">
<img src="https://github.com/frappe/design/blob/master/logos/logo-2019/frappe-charts-logo.png" height="128">
<a href="https://frappe.github.io/charts">
<h2>Frappe Charts</h2>
</a>
<p align="center">
<p>GitHub-inspired modern, intuitive and responsive charts with zero dependencies</p>
<a href="https://frappe.io/charts">
<b>Explore Demos » </b>
</a>
<a href="https://codesandbox.io/s/frappe-charts-demo-viqud">
<b> Edit at CodeSandbox »</b>
</a>
<a href="https://frappe.io/charts/docs">
<b>Documentation » </b>
</a>
</p>
</div>
<p align="center">
<a href="https://bundlephobia.com/result?p=frappe-charts">
<img src="https://img.shields.io/bundlephobia/minzip/frappe-charts">
</a>
</p>
<p align="center">
<a href="https://frappe.github.io/charts">
<img src=".github/example.gif">
</a>
</p>
### Contents
* [Installation](#installation)
* [Usage](#usage)
* [Contribute](https://frappe.io/charts/docs/contributing)
* [License](#license)
#### Installation
##### Via NPM
Install via [`npm`](https://www.npmjs.com/get-npm):
```sh
$ npm install frappe-charts
```
and include in your project:
```js
import { Chart } from "frappe-charts"
```
Or include following for es-modules(eg:vuejs):
```js
import { Chart } from 'frappe-charts/dist/frappe-charts.esm.js'
// import css
import 'frappe-charts/dist/frappe-charts.min.css'
```
##### or include within your HTML
```html
<script src="https://cdn.jsdelivr.net/npm/frappe-charts@1.1.0/dist/frappe-charts.min.umd.js"></script>
<!-- or -->
<script src="https://unpkg.com/frappe-charts@1.1.0/dist/frappe-charts.min.umd.js"></script>
```
#### Usage
```js
const data = {
labels: ["12am-3am", "3am-6pm", "6am-9am", "9am-12am",
"12pm-3pm", "3pm-6pm", "6pm-9pm", "9am-12am"
],
datasets: [
{
name: "Some Data", type: "bar",
values: [25, 40, 30, 35, 8, 52, 17, -4]
},
{
name: "Another Set", type: "line",
values: [25, 50, -10, 15, 18, 32, 27, 14]
}
]
}
const chart = new frappe.Chart("#chart", { // or a DOM element,
// new Chart() in case of ES6 module with above usage
title: "My Awesome Chart",
data: data,
type: 'axis-mixed', // or 'bar', 'line', 'scatter', 'pie', 'percentage'
height: 250,
colors: ['#7cd6fd', '#743ee2']
})
```
Or for es-modules (replace `new frappe.Chart()` with `new Chart()`):
```diff
- const chart = new frappe.Chart("#chart", {
+ const chart = new Chart("#chart", { // or a DOM element,
// new Chart() in case of ES6 module with above usage
title: "My Awesome Chart",
data: data,
type: 'axis-mixed', // or 'bar', 'line', 'scatter', 'pie', 'percentage'
height: 250,
colors: ['#7cd6fd', '#743ee2']
})
```
If you want to contribute:
1. Clone this repo.
2. `cd` into project directory
3. `npm install`
4. `npm run dev`
#### License
This repository has been released under the [MIT License](LICENSE)
------------------
Project maintained by [Frappe](https://frappe.io).
Used in [ERPNext](https://erpnext.com). Read the [blog post](https://medium.com/@pratu16x7/so-we-decided-to-create-our-own-charts-a95cb5032c97).

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,68 +0,0 @@
{
"name": "frappe-charts",
"version": "1.6.2",
"description": "https://frappe.github.io/charts",
"main": "dist/frappe-charts.min.cjs.js",
"module": "dist/frappe-charts.min.esm.js",
"src": "dist/frappe-charts.esm.js",
"browser": "dist/frappe-charts.min.umd.js",
"directories": {
"doc": "docs"
},
"files": [
"src",
"dist"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "rollup -c --watch",
"dev": "npm-run-all --parallel watch",
"build": "rollup -c"
},
"repository": {
"type": "git",
"url": "git+https://github.com/frappe/charts.git"
},
"keywords": [
"js",
"charts"
],
"author": "Prateeksha Singh",
"license": "MIT",
"bugs": {
"url": "https://github.com/frappe/charts/issues"
},
"homepage": "https://github.com/frappe/charts#readme",
"devDependencies": {
"autoprefixer": "^8.2.0",
"babel-core": "^6.26.3",
"babel-plugin-external-helpers": "^6.22.0",
"babel-plugin-istanbul": "^5.1.4",
"babel-preset-env": "^1.7.0",
"babel-preset-latest": "^6.24.1",
"babel-register": "^6.26.0",
"clean-css": "^4.1.11",
"coveralls": "^3.0.0",
"cross-env": "^5.1.4",
"cssnano": "^4.1.10",
"eslint": "^4.18.2",
"mocha": "^5.0.5",
"node-sass": "^4.12.0",
"npm-run-all": "^4.1.1",
"nyc": "^14.1.1",
"postcss": "^6.0.21",
"postcss-cssnext": "^3.0.2",
"postcss-nested": "^2.1.2",
"precss": "^3.1.2",
"rollup": "^0.50.0",
"rollup-plugin-babel": "^3.0.2",
"rollup-plugin-eslint": "^6.0.0",
"rollup-plugin-node-resolve": "^3.0.0",
"rollup-plugin-postcss": "^2.0.3",
"rollup-plugin-replace": "^2.0.0",
"rollup-plugin-uglify": "^2.0.1",
"rollup-plugin-uglify-es": "0.0.1",
"rollup-watch": "^4.3.1"
},
"dependencies": {}
}

View File

@ -1,116 +0,0 @@
.chart-container {
position: relative; /* for absolutely positioned tooltip */
/* https://www.smashingmagazine.com/2015/11/using-system-ui-fonts-practical-guide/ */
font-family: -apple-system, BlinkMacSystemFont,
'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell',
'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
.axis, .chart-label {
fill: #555b51;
line {
stroke: #dadada;
}
}
.dataset-units {
circle {
stroke: #fff;
stroke-width: 2;
}
path {
fill: none;
stroke-opacity: 1;
stroke-width: 2px;
}
}
.dataset-path {
stroke-width: 2px;
}
.path-group {
path {
fill: none;
stroke-opacity: 1;
stroke-width: 2px;
}
}
line.dashed {
stroke-dasharray: 5, 3;
}
.axis-line {
.specific-value {
text-anchor: start;
}
.y-line {
text-anchor: end;
}
.x-line {
text-anchor: middle;
}
}
.legend-dataset-text {
fill: #6c7680;
font-weight: 600;
}
}
.graph-svg-tip {
position: absolute;
z-index: 99999;
padding: 10px;
font-size: 12px;
color: #959da5;
text-align: center;
background: rgba(0, 0, 0, 0.8);
border-radius: 3px;
ul {
padding-left: 0;
display: flex;
}
ol {
padding-left: 0;
display: flex;
}
ul.data-point-list {
li {
min-width: 90px;
flex: 1;
font-weight: 600;
}
}
strong {
color: #dfe2e5;
font-weight: 600;
}
.svg-pointer {
position: absolute;
height: 5px;
margin: 0 0 0 -5px;
content: ' ';
border: 5px solid transparent;
border-top-color: rgba(0, 0, 0, 0.8);
}
&.comparison {
padding: 0;
text-align: left;
pointer-events: none;
.title {
display: block;
padding: 10px;
margin: 0;
font-weight: 600;
line-height: 1;
pointer-events: none;
}
ul {
margin: 0;
white-space: nowrap;
list-style: none;
}
li {
display: inline-block;
padding: 5px 10px;
}
}
}

View File

@ -1 +0,0 @@
export const CSSTEXT = ".chart-container{position:relative;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI','Roboto','Oxygen','Ubuntu','Cantarell','Fira Sans','Droid Sans','Helvetica Neue',sans-serif}.chart-container .axis,.chart-container .chart-label{fill:#555b51}.chart-container .axis line,.chart-container .chart-label line{stroke:#dadada}.chart-container .dataset-units circle{stroke:#fff;stroke-width:2}.chart-container .dataset-units path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container .dataset-path{stroke-width:2px}.chart-container .path-group path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container line.dashed{stroke-dasharray:5,3}.chart-container .axis-line .specific-value{text-anchor:start}.chart-container .axis-line .y-line{text-anchor:end}.chart-container .axis-line .x-line{text-anchor:middle}.chart-container .legend-dataset-text{fill:#6c7680;font-weight:600}.graph-svg-tip{position:absolute;z-index:99999;padding:10px;font-size:12px;color:#959da5;text-align:center;background:rgba(0,0,0,.8);border-radius:3px}.graph-svg-tip ul{padding-left:0;display:flex}.graph-svg-tip ol{padding-left:0;display:flex}.graph-svg-tip ul.data-point-list li{min-width:90px;flex:1;font-weight:600}.graph-svg-tip strong{color:#dfe2e5;font-weight:600}.graph-svg-tip .svg-pointer{position:absolute;height:5px;margin:0 0 0 -5px;content:' ';border:5px solid transparent;border-top-color:rgba(0,0,0,.8)}.graph-svg-tip.comparison{padding:0;text-align:left;pointer-events:none}.graph-svg-tip.comparison .title{display:block;padding:10px;margin:0;font-weight:600;line-height:1;pointer-events:none}.graph-svg-tip.comparison ul{margin:0;white-space:nowrap;list-style:none}.graph-svg-tip.comparison li{display:inline-block;padding:5px 10px}";

View File

@ -1,40 +0,0 @@
import '../css/charts.scss';
// import MultiAxisChart from './charts/MultiAxisChart';
import PercentageChart from './charts/PercentageChart';
import PieChart from './charts/PieChart';
import Heatmap from './charts/Heatmap';
import AxisChart from './charts/AxisChart';
import DonutChart from './charts/DonutChart';
const chartTypes = {
bar: AxisChart,
line: AxisChart,
// multiaxis: MultiAxisChart,
percentage: PercentageChart,
heatmap: Heatmap,
pie: PieChart,
donut: DonutChart,
};
function getChartByType(chartType = 'line', parent, options) {
if (chartType === 'axis-mixed') {
options.type = 'line';
return new AxisChart(parent, options);
}
if (!chartTypes[chartType]) {
console.error("Undefined chart type: " + chartType);
return;
}
return new chartTypes[chartType](parent, options);
}
class Chart {
constructor(parent, options) {
return getChartByType(options.type, parent, options);
}
}
export { Chart, PercentageChart, PieChart, Heatmap, AxisChart };

View File

@ -1,95 +0,0 @@
import BaseChart from './BaseChart';
import { truncateString } from '../utils/draw-utils';
import { legendDot } from '../utils/draw';
import { round } from '../utils/helpers';
import { getExtraWidth } from '../utils/constants';
export default class AggregationChart extends BaseChart {
constructor(parent, args) {
super(parent, args);
}
configure(args) {
super.configure(args);
this.config.formatTooltipY = (args.tooltipOptions || {}).formatTooltipY;
this.config.maxSlices = args.maxSlices || 20;
this.config.maxLegendPoints = args.maxLegendPoints || 20;
}
calc() {
let s = this.state;
let maxSlices = this.config.maxSlices;
s.sliceTotals = [];
let allTotals = this.data.labels.map((label, i) => {
let total = 0;
this.data.datasets.map(e => {
total += e.values[i];
});
return [total, label];
}).filter(d => { return d[0] >= 0; }); // keep only positive results
let totals = allTotals;
if(allTotals.length > maxSlices) {
// Prune and keep a grey area for rest as per maxSlices
allTotals.sort((a, b) => { return b[0] - a[0]; });
totals = allTotals.slice(0, maxSlices-1);
let remaining = allTotals.slice(maxSlices-1);
let sumOfRemaining = 0;
remaining.map(d => {sumOfRemaining += d[0];});
totals.push([sumOfRemaining, 'Rest']);
this.colors[maxSlices-1] = 'grey';
}
s.labels = [];
totals.map(d => {
s.sliceTotals.push(round(d[0]));
s.labels.push(d[1]);
});
s.grandTotal = s.sliceTotals.reduce((a, b) => a + b, 0);
this.center = {
x: this.width / 2,
y: this.height / 2
};
}
renderLegend() {
let s = this.state;
this.legendArea.textContent = '';
this.legendTotals = s.sliceTotals.slice(0, this.config.maxLegendPoints);
let count = 0;
let y = 0;
this.legendTotals.map((d, i) => {
let barWidth = 150;
let divisor = Math.floor(
(this.width - getExtraWidth(this.measures))/barWidth
);
if (this.legendTotals.length < divisor) {
barWidth = this.width/this.legendTotals.length;
}
if(count > divisor) {
count = 0;
y += 20;
}
let x = barWidth * count + 5;
let label = this.config.truncateLegends ? truncateString(s.labels[i], barWidth/10) : s.labels[i];
let formatted = this.config.formatTooltipY ? this.config.formatTooltipY(d) : d;
let dot = legendDot(
x,
y,
5,
this.colors[i],
`${label}: ${formatted}`,
false
);
this.legendArea.appendChild(dot);
count++;
});
}
}

View File

@ -1,590 +0,0 @@
import BaseChart from './BaseChart';
import { dataPrep, zeroDataPrep, getShortenedLabels } from '../utils/axis-chart-utils';
import { AXIS_LEGEND_BAR_SIZE } from '../utils/constants';
import { getComponent } from '../objects/ChartComponents';
import { getOffset, fire } from '../utils/dom';
import { calcChartIntervals, getIntervalSize, getValueRange, getZeroIndex, scale, getClosestInArray } from '../utils/intervals';
import { floatTwo } from '../utils/helpers';
import { makeOverlay, updateOverlay, legendBar } from '../utils/draw';
import { getTopOffset, getLeftOffset, MIN_BAR_PERCENT_HEIGHT, BAR_CHART_SPACE_RATIO,
LINE_CHART_DOT_SIZE } from '../utils/constants';
export default class AxisChart extends BaseChart {
constructor(parent, args) {
super(parent, args);
this.barOptions = args.barOptions || {};
this.lineOptions = args.lineOptions || {};
this.type = args.type || 'line';
this.init = 1;
this.setup();
}
setMeasures() {
if(this.data.datasets.length <= 1) {
this.config.showLegend = 0;
this.measures.paddings.bottom = 30;
}
}
configure(options) {
super.configure(options);
options.axisOptions = options.axisOptions || {};
options.tooltipOptions = options.tooltipOptions || {};
this.config.xAxisMode = options.axisOptions.xAxisMode || 'span';
this.config.yAxisMode = options.axisOptions.yAxisMode || 'span';
this.config.xIsSeries = options.axisOptions.xIsSeries || 0;
this.config.shortenYAxisNumbers = options.axisOptions.shortenYAxisNumbers || 0;
this.config.formatTooltipX = options.tooltipOptions.formatTooltipX;
this.config.formatTooltipY = options.tooltipOptions.formatTooltipY;
this.config.valuesOverPoints = options.valuesOverPoints;
}
prepareData(data=this.data) {
return dataPrep(data, this.type);
}
prepareFirstData(data=this.data) {
return zeroDataPrep(data);
}
calc(onlyWidthChange = false) {
this.calcXPositions();
if(!onlyWidthChange) {
this.calcYAxisParameters(this.getAllYValues(), this.type === 'line');
}
this.makeDataByIndex();
}
calcXPositions() {
let s = this.state;
let labels = this.data.labels;
s.datasetLength = labels.length;
s.unitWidth = this.width/(s.datasetLength);
// Default, as per bar, and mixed. Only line will be a special case
s.xOffset = s.unitWidth/2;
// // For a pure Line Chart
// s.unitWidth = this.width/(s.datasetLength - 1);
// s.xOffset = 0;
s.xAxis = {
labels: labels,
positions: labels.map((d, i) =>
floatTwo(s.xOffset + i * s.unitWidth)
)
};
}
calcYAxisParameters(dataValues, withMinimum = 'false') {
const yPts = calcChartIntervals(dataValues, withMinimum);
const scaleMultiplier = this.height / getValueRange(yPts);
const intervalHeight = getIntervalSize(yPts) * scaleMultiplier;
const zeroLine = this.height - (getZeroIndex(yPts) * intervalHeight);
this.state.yAxis = {
labels: yPts,
positions: yPts.map(d => zeroLine - d * scaleMultiplier),
scaleMultiplier: scaleMultiplier,
zeroLine: zeroLine,
};
// Dependent if above changes
this.calcDatasetPoints();
this.calcYExtremes();
this.calcYRegions();
}
calcDatasetPoints() {
let s = this.state;
let scaleAll = values => values.map(val => scale(val, s.yAxis));
s.datasets = this.data.datasets.map((d, i) => {
let values = d.values;
let cumulativeYs = d.cumulativeYs || [];
return {
name: d.name && d.name.replace(/<|>|&/g, (char) => char == '&' ? '&amp;' : char == '<' ? '&lt;' : '&gt;'),
index: i,
chartType: d.chartType,
values: values,
yPositions: scaleAll(values),
cumulativeYs: cumulativeYs,
cumulativeYPos: scaleAll(cumulativeYs),
};
});
}
calcYExtremes() {
let s = this.state;
if(this.barOptions.stacked) {
s.yExtremes = s.datasets[s.datasets.length - 1].cumulativeYPos;
return;
}
s.yExtremes = new Array(s.datasetLength).fill(9999);
s.datasets.map(d => {
d.yPositions.map((pos, j) => {
if(pos < s.yExtremes[j]) {
s.yExtremes[j] = pos;
}
});
});
}
calcYRegions() {
let s = this.state;
if(this.data.yMarkers) {
this.state.yMarkers = this.data.yMarkers.map(d => {
d.position = scale(d.value, s.yAxis);
if(!d.options) d.options = {};
// if(!d.label.includes(':')) {
// d.label += ': ' + d.value;
// }
return d;
});
}
if(this.data.yRegions) {
this.state.yRegions = this.data.yRegions.map(d => {
d.startPos = scale(d.start, s.yAxis);
d.endPos = scale(d.end, s.yAxis);
if(!d.options) d.options = {};
return d;
});
}
}
getAllYValues() {
let key = 'values';
if(this.barOptions.stacked) {
key = 'cumulativeYs';
let cumulative = new Array(this.state.datasetLength).fill(0);
this.data.datasets.map((d, i) => {
let values = this.data.datasets[i].values;
d[key] = cumulative = cumulative.map((c, i) => c + values[i]);
});
}
let allValueLists = this.data.datasets.map(d => d[key]);
if(this.data.yMarkers) {
allValueLists.push(this.data.yMarkers.map(d => d.value));
}
if(this.data.yRegions) {
this.data.yRegions.map(d => {
allValueLists.push([d.end, d.start]);
});
}
return [].concat(...allValueLists);
}
setupComponents() {
let componentConfigs = [
[
'yAxis',
{
mode: this.config.yAxisMode,
width: this.width,
shortenNumbers: this.config.shortenYAxisNumbers
// pos: 'right'
},
function() {
return this.state.yAxis;
}.bind(this)
],
[
'xAxis',
{
mode: this.config.xAxisMode,
height: this.height,
// pos: 'right'
},
function() {
let s = this.state;
s.xAxis.calcLabels = getShortenedLabels(this.width,
s.xAxis.labels, this.config.xIsSeries);
return s.xAxis;
}.bind(this)
],
[
'yRegions',
{
width: this.width,
pos: 'right'
},
function() {
return this.state.yRegions;
}.bind(this)
],
];
let barDatasets = this.state.datasets.filter(d => d.chartType === 'bar');
let lineDatasets = this.state.datasets.filter(d => d.chartType === 'line');
let barsConfigs = barDatasets.map(d => {
let index = d.index;
return [
'barGraph' + '-' + d.index,
{
index: index,
color: this.colors[index],
stacked: this.barOptions.stacked,
// same for all datasets
valuesOverPoints: this.config.valuesOverPoints,
minHeight: this.height * MIN_BAR_PERCENT_HEIGHT,
},
function() {
let s = this.state;
let d = s.datasets[index];
let stacked = this.barOptions.stacked;
let spaceRatio = this.barOptions.spaceRatio || BAR_CHART_SPACE_RATIO;
let barsWidth = s.unitWidth * (1 - spaceRatio);
let barWidth = barsWidth/(stacked ? 1 : barDatasets.length);
let xPositions = s.xAxis.positions.map(x => x - barsWidth/2);
if(!stacked) {
xPositions = xPositions.map(p => p + barWidth * index);
}
let labels = new Array(s.datasetLength).fill('');
if(this.config.valuesOverPoints) {
if(stacked && d.index === s.datasets.length - 1) {
labels = d.cumulativeYs;
} else {
labels = d.values;
}
}
let offsets = new Array(s.datasetLength).fill(0);
if(stacked) {
offsets = d.yPositions.map((y, j) => y - d.cumulativeYPos[j]);
}
return {
xPositions: xPositions,
yPositions: d.yPositions,
offsets: offsets,
// values: d.values,
labels: labels,
zeroLine: s.yAxis.zeroLine,
barsWidth: barsWidth,
barWidth: barWidth,
};
}.bind(this)
];
});
let lineConfigs = lineDatasets.map(d => {
let index = d.index;
return [
'lineGraph' + '-' + d.index,
{
index: index,
color: this.colors[index],
svgDefs: this.svgDefs,
heatline: this.lineOptions.heatline,
regionFill: this.lineOptions.regionFill,
spline: this.lineOptions.spline,
hideDots: this.lineOptions.hideDots,
hideLine: this.lineOptions.hideLine,
// same for all datasets
valuesOverPoints: this.config.valuesOverPoints,
},
function() {
let s = this.state;
let d = s.datasets[index];
let minLine = s.yAxis.positions[0] < s.yAxis.zeroLine
? s.yAxis.positions[0] : s.yAxis.zeroLine;
return {
xPositions: s.xAxis.positions,
yPositions: d.yPositions,
values: d.values,
zeroLine: minLine,
radius: this.lineOptions.dotSize || LINE_CHART_DOT_SIZE,
};
}.bind(this)
];
});
let markerConfigs = [
[
'yMarkers',
{
width: this.width,
pos: 'right'
},
function() {
return this.state.yMarkers;
}.bind(this)
]
];
componentConfigs = componentConfigs.concat(barsConfigs, lineConfigs, markerConfigs);
let optionals = ['yMarkers', 'yRegions'];
this.dataUnitComponents = [];
this.components = new Map(componentConfigs
.filter(args => !optionals.includes(args[0]) || this.state[args[0]])
.map(args => {
let component = getComponent(...args);
if(args[0].includes('lineGraph') || args[0].includes('barGraph')) {
this.dataUnitComponents.push(component);
}
return [args[0], component];
}));
}
makeDataByIndex() {
this.dataByIndex = {};
let s = this.state;
let formatX = this.config.formatTooltipX;
let formatY = this.config.formatTooltipY;
let titles = s.xAxis.labels;
titles.map((label, index) => {
let values = this.state.datasets.map((set, i) => {
let value = set.values[index];
return {
title: set.name,
value: value,
yPos: set.yPositions[index],
color: this.colors[i],
formatted: formatY ? formatY(value) : value,
};
});
this.dataByIndex[index] = {
label: label,
formattedLabel: formatX ? formatX(label) : label,
xPos: s.xAxis.positions[index],
values: values,
yExtreme: s.yExtremes[index],
};
});
}
bindTooltip() {
// NOTE: could be in tooltip itself, as it is a given functionality for its parent
this.container.addEventListener('mousemove', (e) => {
let m = this.measures;
let o = getOffset(this.container);
let relX = e.pageX - o.left - getLeftOffset(m);
let relY = e.pageY - o.top;
if(relY < this.height + getTopOffset(m)
&& relY > getTopOffset(m)) {
this.mapTooltipXPosition(relX);
} else {
this.tip.hideTip();
}
});
}
mapTooltipXPosition(relX) {
let s = this.state;
if(!s.yExtremes) return;
let index = getClosestInArray(relX, s.xAxis.positions, true);
if (index >= 0) {
let dbi = this.dataByIndex[index];
this.tip.setValues(
dbi.xPos + this.tip.offset.x,
dbi.yExtreme + this.tip.offset.y,
{name: dbi.formattedLabel, value: ''},
dbi.values,
index
);
this.tip.showTip();
}
}
renderLegend() {
let s = this.data;
if(s.datasets.length > 1) {
this.legendArea.textContent = '';
s.datasets.map((d, i) => {
let barWidth = AXIS_LEGEND_BAR_SIZE;
// let rightEndPoint = this.baseWidth - this.measures.margins.left - this.measures.margins.right;
// let multiplier = s.datasets.length - i;
let rect = legendBar(
// rightEndPoint - multiplier * barWidth, // To right align
barWidth * i,
'0',
barWidth,
this.colors[i],
d.name,
this.config.truncateLegends);
this.legendArea.appendChild(rect);
});
}
}
// Overlay
makeOverlay() {
if(this.init) {
this.init = 0;
return;
}
if(this.overlayGuides) {
this.overlayGuides.forEach(g => {
let o = g.overlay;
o.parentNode.removeChild(o);
});
}
this.overlayGuides = this.dataUnitComponents.map(c => {
return {
type: c.unitType,
overlay: undefined,
units: c.units,
};
});
if(this.state.currentIndex === undefined) {
this.state.currentIndex = this.state.datasetLength - 1;
}
// Render overlays
this.overlayGuides.map(d => {
let currentUnit = d.units[this.state.currentIndex];
d.overlay = makeOverlay[d.type](currentUnit);
this.drawArea.appendChild(d.overlay);
});
}
updateOverlayGuides() {
if(this.overlayGuides) {
this.overlayGuides.forEach(g => {
let o = g.overlay;
o.parentNode.removeChild(o);
});
}
}
bindOverlay() {
this.parent.addEventListener('data-select', () => {
this.updateOverlay();
});
}
bindUnits() {
this.dataUnitComponents.map(c => {
c.units.map(unit => {
unit.addEventListener('click', () => {
let index = unit.getAttribute('data-point-index');
this.setCurrentDataPoint(index);
});
});
});
// Note: Doesn't work as tooltip is absolutely positioned
this.tip.container.addEventListener('click', () => {
let index = this.tip.container.getAttribute('data-point-index');
this.setCurrentDataPoint(index);
});
}
updateOverlay() {
this.overlayGuides.map(d => {
let currentUnit = d.units[this.state.currentIndex];
updateOverlay[d.type](currentUnit, d.overlay);
});
}
onLeftArrow() {
this.setCurrentDataPoint(this.state.currentIndex - 1);
}
onRightArrow() {
this.setCurrentDataPoint(this.state.currentIndex + 1);
}
getDataPoint(index=this.state.currentIndex) {
let s = this.state;
let data_point = {
index: index,
label: s.xAxis.labels[index],
values: s.datasets.map(d => d.values[index])
};
return data_point;
}
setCurrentDataPoint(index) {
let s = this.state;
index = parseInt(index);
if(index < 0) index = 0;
if(index >= s.xAxis.labels.length) index = s.xAxis.labels.length - 1;
if(index === s.currentIndex) return;
s.currentIndex = index;
fire(this.parent, "data-select", this.getDataPoint());
}
// API
addDataPoint(label, datasetValues, index=this.state.datasetLength) {
super.addDataPoint(label, datasetValues, index);
this.data.labels.splice(index, 0, label);
this.data.datasets.map((d, i) => {
d.values.splice(index, 0, datasetValues[i]);
});
this.update(this.data);
}
removeDataPoint(index = this.state.datasetLength-1) {
if (this.data.labels.length <= 1) {
return;
}
super.removeDataPoint(index);
this.data.labels.splice(index, 1);
this.data.datasets.map(d => {
d.values.splice(index, 1);
});
this.update(this.data);
}
updateDataset(datasetValues, index=0) {
this.data.datasets[index].values = datasetValues;
this.update(this.data);
}
// addDataset(dataset, index) {}
// removeDataset(index = 0) {}
updateDatasets(datasets) {
this.data.datasets.map((d, i) => {
if(datasets[i]) {
d.values = datasets[i];
}
});
this.update(this.data);
}
// updateDataPoint(dataPoint, index = 0) {}
// addDataPoint(dataPoint, index = 0) {}
// removeDataPoint(index = 0) {}
}

View File

@ -1,324 +0,0 @@
import SvgTip from '../objects/SvgTip';
import { $, isElementInViewport, getElementContentWidth, isHidden } from '../utils/dom';
import { makeSVGContainer, makeSVGDefs, makeSVGGroup, makeText } from '../utils/draw';
import { BASE_MEASURES, getExtraHeight, getExtraWidth, getTopOffset, getLeftOffset,
INIT_CHART_UPDATE_TIMEOUT, CHART_POST_ANIMATE_TIMEOUT, DEFAULT_COLORS} from '../utils/constants';
import { getColor, isValidColor } from '../utils/colors';
import { runSMILAnimation } from '../utils/animation';
import { downloadFile, prepareForExport } from '../utils/export';
import { deepClone } from '../utils/helpers';
export default class BaseChart {
constructor(parent, options) {
// deepclone options to avoid making changes to orignal object
options = deepClone(options);
this.parent = typeof parent === 'string'
? document.querySelector(parent)
: parent;
if (!(this.parent instanceof HTMLElement)) {
throw new Error('No `parent` element to render on was provided.');
}
this.rawChartArgs = options;
this.title = options.title || '';
this.type = options.type || '';
this.realData = this.prepareData(options.data);
this.data = this.prepareFirstData(this.realData);
this.colors = this.validateColors(options.colors, this.type);
this.config = {
showTooltip: 1, // calculate
showLegend: 1, // calculate
isNavigable: options.isNavigable || 0,
animate: (typeof options.animate !== 'undefined') ? options.animate : 1,
truncateLegends: options.truncateLegends || 1
};
this.measures = JSON.parse(JSON.stringify(BASE_MEASURES));
let m = this.measures;
this.setMeasures(options);
if(!this.title.length) { m.titleHeight = 0; }
if(!this.config.showLegend) m.legendHeight = 0;
this.argHeight = options.height || m.baseHeight;
this.state = {};
this.options = {};
this.initTimeout = INIT_CHART_UPDATE_TIMEOUT;
if(this.config.isNavigable) {
this.overlays = [];
}
this.configure(options);
}
prepareData(data) {
return data;
}
prepareFirstData(data) {
return data;
}
validateColors(colors, type) {
const validColors = [];
colors = (colors || []).concat(DEFAULT_COLORS[type]);
colors.forEach((string) => {
const color = getColor(string);
if(!isValidColor(color)) {
console.warn('"' + string + '" is not a valid color.');
} else {
validColors.push(color);
}
});
return validColors;
}
setMeasures() {
// Override measures, including those for title and legend
// set config for legend and title
}
configure() {
let height = this.argHeight;
this.baseHeight = height;
this.height = height - getExtraHeight(this.measures);
// Bind window events
this.boundDrawFn = () => this.draw(true);
if (ResizeObserver) {
this.resizeObserver = new ResizeObserver(this.boundDrawFn);
this.resizeObserver.observe(this.parent);
}
window.addEventListener('resize', this.boundDrawFn);
window.addEventListener('orientationchange', this.boundDrawFn);
}
destroy() {
if (this.resizeObserver) this.resizeObserver.disconnect();
window.removeEventListener('resize', this.boundDrawFn);
window.removeEventListener('orientationchange', this.boundDrawFn);
}
// Has to be called manually
setup() {
this.makeContainer();
this.updateWidth();
this.makeTooltip();
this.draw(false, true);
}
makeContainer() {
// Chart needs a dedicated parent element
this.parent.innerHTML = '';
let args = {
inside: this.parent,
className: 'chart-container'
};
if(this.independentWidth) {
args.styles = { width: this.independentWidth + 'px' };
}
this.container = $.create('div', args);
}
makeTooltip() {
this.tip = new SvgTip({
parent: this.container,
colors: this.colors
});
this.bindTooltip();
}
bindTooltip() {}
draw(onlyWidthChange=false, init=false) {
if (onlyWidthChange && isHidden(this.parent)) {
// Don't update anything if the chart is hidden
return;
}
this.updateWidth();
this.calc(onlyWidthChange);
this.makeChartArea();
this.setupComponents();
this.components.forEach(c => c.setup(this.drawArea));
// this.components.forEach(c => c.make());
this.render(this.components, false);
if(init) {
this.data = this.realData;
setTimeout(() => {this.update(this.data);}, this.initTimeout);
}
this.renderLegend();
this.setupNavigation(init);
}
calc() {} // builds state
updateWidth() {
this.baseWidth = getElementContentWidth(this.parent);
this.width = this.baseWidth - getExtraWidth(this.measures);
}
makeChartArea() {
if(this.svg) {
this.container.removeChild(this.svg);
}
let m = this.measures;
this.svg = makeSVGContainer(
this.container,
'frappe-chart chart',
this.baseWidth,
this.baseHeight
);
this.svgDefs = makeSVGDefs(this.svg);
if(this.title.length) {
this.titleEL = makeText(
'title',
m.margins.left,
m.margins.top,
this.title,
{
fontSize: m.titleFontSize,
fill: '#666666',
dy: m.titleFontSize
}
);
}
let top = getTopOffset(m);
this.drawArea = makeSVGGroup(
this.type + '-chart chart-draw-area',
`translate(${getLeftOffset(m)}, ${top})`
);
if(this.config.showLegend) {
top += this.height + m.paddings.bottom;
this.legendArea = makeSVGGroup(
'chart-legend',
`translate(${getLeftOffset(m)}, ${top})`
);
}
if(this.title.length) { this.svg.appendChild(this.titleEL); }
this.svg.appendChild(this.drawArea);
if(this.config.showLegend) { this.svg.appendChild(this.legendArea); }
this.updateTipOffset(getLeftOffset(m), getTopOffset(m));
}
updateTipOffset(x, y) {
this.tip.offset = {
x: x,
y: y
};
}
setupComponents() { this.components = new Map(); }
update(data) {
if(!data) {
console.error('No data to update.');
}
this.data = this.prepareData(data);
this.calc(); // builds state
this.render(this.components, this.config.animate);
this.renderLegend();
}
render(components=this.components, animate=true) {
if(this.config.isNavigable) {
// Remove all existing overlays
this.overlays.map(o => o.parentNode.removeChild(o));
// ref.parentNode.insertBefore(element, ref);
}
let elementsToAnimate = [];
// Can decouple to this.refreshComponents() first to save animation timeout
components.forEach(c => {
elementsToAnimate = elementsToAnimate.concat(c.update(animate));
});
if(elementsToAnimate.length > 0) {
runSMILAnimation(this.container, this.svg, elementsToAnimate);
setTimeout(() => {
components.forEach(c => c.make());
this.updateNav();
}, CHART_POST_ANIMATE_TIMEOUT);
} else {
components.forEach(c => c.make());
this.updateNav();
}
}
updateNav() {
if(this.config.isNavigable) {
this.makeOverlay();
this.bindUnits();
}
}
renderLegend() {}
setupNavigation(init=false) {
if(!this.config.isNavigable) return;
if(init) {
this.bindOverlay();
this.keyActions = {
'13': this.onEnterKey.bind(this),
'37': this.onLeftArrow.bind(this),
'38': this.onUpArrow.bind(this),
'39': this.onRightArrow.bind(this),
'40': this.onDownArrow.bind(this),
};
document.addEventListener('keydown', (e) => {
if(isElementInViewport(this.container)) {
e = e || window.event;
if(this.keyActions[e.keyCode]) {
this.keyActions[e.keyCode]();
}
}
});
}
}
makeOverlay() {}
updateOverlay() {}
bindOverlay() {}
bindUnits() {}
onLeftArrow() {}
onRightArrow() {}
onUpArrow() {}
onDownArrow() {}
onEnterKey() {}
addDataPoint() {}
removeDataPoint() {}
getDataPoint() {}
setCurrentDataPoint() {}
updateDataset() {}
export() {
let chartSvg = prepareForExport(this.svg);
downloadFile(this.title || 'Chart', [chartSvg]);
}
}

View File

@ -1,161 +0,0 @@
import AggregationChart from './AggregationChart';
import { getComponent } from '../objects/ChartComponents';
import { getOffset } from '../utils/dom';
import { getPositionByAngle } from '../utils/helpers';
import { makeArcStrokePathStr, makeStrokeCircleStr } from '../utils/draw';
import { lightenDarkenColor } from '../utils/colors';
import { transform } from '../utils/animation';
import { FULL_ANGLE } from '../utils/constants';
export default class DonutChart extends AggregationChart {
constructor(parent, args) {
super(parent, args);
this.type = 'donut';
this.initTimeout = 0;
this.init = 1;
this.setup();
}
configure(args) {
super.configure(args);
this.mouseMove = this.mouseMove.bind(this);
this.mouseLeave = this.mouseLeave.bind(this);
this.hoverRadio = args.hoverRadio || 0.1;
this.config.startAngle = args.startAngle || 0;
this.clockWise = args.clockWise || false;
this.strokeWidth = args.strokeWidth || 30;
}
calc() {
super.calc();
let s = this.state;
this.radius =
this.height > this.width
? this.center.x - this.strokeWidth / 2
: this.center.y - this.strokeWidth / 2;
const { radius, clockWise } = this;
const prevSlicesProperties = s.slicesProperties || [];
s.sliceStrings = [];
s.slicesProperties = [];
let curAngle = 180 - this.config.startAngle;
s.sliceTotals.map((total, i) => {
const startAngle = curAngle;
const originDiffAngle = (total / s.grandTotal) * FULL_ANGLE;
const largeArc = originDiffAngle > 180 ? 1: 0;
const diffAngle = clockWise ? -originDiffAngle : originDiffAngle;
const endAngle = curAngle = curAngle + diffAngle;
const startPosition = getPositionByAngle(startAngle, radius);
const endPosition = getPositionByAngle(endAngle, radius);
const prevProperty = this.init && prevSlicesProperties[i];
let curStart,curEnd;
if(this.init) {
curStart = prevProperty ? prevProperty.startPosition : startPosition;
curEnd = prevProperty ? prevProperty.endPosition : startPosition;
} else {
curStart = startPosition;
curEnd = endPosition;
}
const curPath =
originDiffAngle === 360
? makeStrokeCircleStr(curStart, curEnd, this.center, this.radius, this.clockWise, largeArc)
: makeArcStrokePathStr(curStart, curEnd, this.center, this.radius, this.clockWise, largeArc);
s.sliceStrings.push(curPath);
s.slicesProperties.push({
startPosition,
endPosition,
value: total,
total: s.grandTotal,
startAngle,
endAngle,
angle: diffAngle
});
});
this.init = 0;
}
setupComponents() {
let s = this.state;
let componentConfigs = [
[
'donutSlices',
{ },
function() {
return {
sliceStrings: s.sliceStrings,
colors: this.colors,
strokeWidth: this.strokeWidth,
};
}.bind(this)
]
];
this.components = new Map(componentConfigs
.map(args => {
let component = getComponent(...args);
return [args[0], component];
}));
}
calTranslateByAngle(property){
const{ radius, hoverRadio } = this;
const position = getPositionByAngle(property.startAngle+(property.angle / 2),radius);
return `translate3d(${(position.x) * hoverRadio}px,${(position.y) * hoverRadio}px,0)`;
}
hoverSlice(path,i,flag,e){
if(!path) return;
const color = this.colors[i];
if(flag) {
transform(path, this.calTranslateByAngle(this.state.slicesProperties[i]));
path.style.stroke = lightenDarkenColor(color, 50);
let g_off = getOffset(this.svg);
let x = e.pageX - g_off.left + 10;
let y = e.pageY - g_off.top - 10;
let title = (this.formatted_labels && this.formatted_labels.length > 0
? this.formatted_labels[i] : this.state.labels[i]) + ': ';
let percent = (this.state.sliceTotals[i] * 100 / this.state.grandTotal).toFixed(1);
this.tip.setValues(x, y, {name: title, value: percent + "%"});
this.tip.showTip();
} else {
transform(path,'translate3d(0,0,0)');
this.tip.hideTip();
path.style.stroke = color;
}
}
bindTooltip() {
this.container.addEventListener('mousemove', this.mouseMove);
this.container.addEventListener('mouseleave', this.mouseLeave);
}
mouseMove(e){
const target = e.target;
let slices = this.components.get('donutSlices').store;
let prevIndex = this.curActiveSliceIndex;
let prevAcitve = this.curActiveSlice;
if(slices.includes(target)) {
let i = slices.indexOf(target);
this.hoverSlice(prevAcitve, prevIndex,false);
this.curActiveSlice = target;
this.curActiveSliceIndex = i;
this.hoverSlice(target, i, true, e);
} else {
this.mouseLeave();
}
}
mouseLeave(){
this.hoverSlice(this.curActiveSlice,this.curActiveSliceIndex,false);
}
}

View File

@ -1,296 +0,0 @@
import BaseChart from './BaseChart';
import { getComponent } from '../objects/ChartComponents';
import { makeText, heatSquare } from '../utils/draw';
import { DAY_NAMES_SHORT, addDays, areInSameMonth, getLastDateInMonth, setDayToSunday, getYyyyMmDd, getWeeksBetween, getMonthName, clone,
NO_OF_MILLIS, NO_OF_YEAR_MONTHS, NO_OF_DAYS_IN_WEEK } from '../utils/date-utils';
import { calcDistribution, getMaxCheckpoint } from '../utils/intervals';
import { getExtraHeight, getExtraWidth, HEATMAP_DISTRIBUTION_SIZE, HEATMAP_SQUARE_SIZE,
HEATMAP_GUTTER_SIZE } from '../utils/constants';
const COL_WIDTH = HEATMAP_SQUARE_SIZE + HEATMAP_GUTTER_SIZE;
const ROW_HEIGHT = COL_WIDTH;
// const DAY_INCR = 1;
export default class Heatmap extends BaseChart {
constructor(parent, options) {
super(parent, options);
this.type = 'heatmap';
this.countLabel = options.countLabel || '';
let validStarts = ['Sunday', 'Monday'];
let startSubDomain = validStarts.includes(options.startSubDomain)
? options.startSubDomain : 'Sunday';
this.startSubDomainIndex = validStarts.indexOf(startSubDomain);
this.setup();
}
setMeasures(options) {
let m = this.measures;
this.discreteDomains = options.discreteDomains === 0 ? 0 : 1;
m.paddings.top = ROW_HEIGHT * 3;
m.paddings.bottom = 0;
m.legendHeight = ROW_HEIGHT * 2;
m.baseHeight = ROW_HEIGHT * NO_OF_DAYS_IN_WEEK
+ getExtraHeight(m);
let d = this.data;
let spacing = this.discreteDomains ? NO_OF_YEAR_MONTHS : 0;
this.independentWidth = (getWeeksBetween(d.start, d.end)
+ spacing) * COL_WIDTH + getExtraWidth(m);
}
updateWidth() {
let spacing = this.discreteDomains ? NO_OF_YEAR_MONTHS : 0;
let noOfWeeks = this.state.noOfWeeks ? this.state.noOfWeeks : 52;
this.baseWidth = (noOfWeeks + spacing) * COL_WIDTH
+ getExtraWidth(this.measures);
}
prepareData(data=this.data) {
if(data.start && data.end && data.start > data.end) {
throw new Error('Start date cannot be greater than end date.');
}
if(!data.start) {
data.start = new Date();
data.start.setFullYear( data.start.getFullYear() - 1 );
}
if(!data.end) { data.end = new Date(); }
data.dataPoints = data.dataPoints || {};
if(parseInt(Object.keys(data.dataPoints)[0]) > 100000) {
let points = {};
Object.keys(data.dataPoints).forEach(timestampSec => {
let date = new Date(timestampSec * NO_OF_MILLIS);
points[getYyyyMmDd(date)] = data.dataPoints[timestampSec];
});
data.dataPoints = points;
}
return data;
}
calc() {
let s = this.state;
s.start = clone(this.data.start);
s.end = clone(this.data.end);
s.firstWeekStart = clone(s.start);
s.noOfWeeks = getWeeksBetween(s.start, s.end);
s.distribution = calcDistribution(
Object.values(this.data.dataPoints), HEATMAP_DISTRIBUTION_SIZE);
s.domainConfigs = this.getDomains();
}
setupComponents() {
let s = this.state;
let lessCol = this.discreteDomains ? 0 : 1;
let componentConfigs = s.domainConfigs.map((config, i) => [
'heatDomain',
{
index: config.index,
colWidth: COL_WIDTH,
rowHeight: ROW_HEIGHT,
squareSize: HEATMAP_SQUARE_SIZE,
radius: this.rawChartArgs.radius || 0,
xTranslate: s.domainConfigs
.filter((config, j) => j < i)
.map(config => config.cols.length - lessCol)
.reduce((a, b) => a + b, 0)
* COL_WIDTH
},
function() {
return s.domainConfigs[i];
}.bind(this)
]);
this.components = new Map(componentConfigs
.map((args, i) => {
let component = getComponent(...args);
return [args[0] + '-' + i, component];
})
);
let y = 0;
DAY_NAMES_SHORT.forEach((dayName, i) => {
if([1, 3, 5].includes(i)) {
let dayText = makeText('subdomain-name', -COL_WIDTH/2, y, dayName,
{
fontSize: HEATMAP_SQUARE_SIZE,
dy: 8,
textAnchor: 'end'
}
);
this.drawArea.appendChild(dayText);
}
y += ROW_HEIGHT;
});
}
update(data) {
if(!data) {
console.error('No data to update.');
}
this.data = this.prepareData(data);
this.draw();
this.bindTooltip();
}
bindTooltip() {
this.container.addEventListener('mousemove', (e) => {
this.components.forEach(comp => {
let daySquares = comp.store;
let daySquare = e.target;
if(daySquares.includes(daySquare)) {
let count = daySquare.getAttribute('data-value');
let dateParts = daySquare.getAttribute('data-date').split('-');
let month = getMonthName(parseInt(dateParts[1])-1, true);
let gOff = this.container.getBoundingClientRect(), pOff = daySquare.getBoundingClientRect();
let width = parseInt(e.target.getAttribute('width'));
let x = pOff.left - gOff.left + width/2;
let y = pOff.top - gOff.top;
let value = count + ' ' + this.countLabel;
let name = ' on ' + month + ' ' + dateParts[0] + ', ' + dateParts[2];
this.tip.setValues(x, y, {name: name, value: value, valueFirst: 1}, []);
this.tip.showTip();
}
});
});
}
renderLegend() {
this.legendArea.textContent = '';
let x = 0;
let y = ROW_HEIGHT;
let radius = this.rawChartArgs.radius || 0;
let lessText = makeText('subdomain-name', x, y, 'Less',
{
fontSize: HEATMAP_SQUARE_SIZE + 1,
dy: 9
}
);
x = (COL_WIDTH * 2) + COL_WIDTH/2;
this.legendArea.appendChild(lessText);
this.colors.slice(0, HEATMAP_DISTRIBUTION_SIZE).map((color, i) => {
const square = heatSquare('heatmap-legend-unit', x + (COL_WIDTH + 3) * i,
y, HEATMAP_SQUARE_SIZE, radius, color);
this.legendArea.appendChild(square);
});
let moreTextX = x + HEATMAP_DISTRIBUTION_SIZE * (COL_WIDTH + 3) + COL_WIDTH/4;
let moreText = makeText('subdomain-name', moreTextX, y, 'More',
{
fontSize: HEATMAP_SQUARE_SIZE + 1,
dy: 9
}
);
this.legendArea.appendChild(moreText);
}
getDomains() {
let s = this.state;
const [startMonth, startYear] = [s.start.getMonth(), s.start.getFullYear()];
const [endMonth, endYear] = [s.end.getMonth(), s.end.getFullYear()];
const noOfMonths = (endMonth - startMonth + 1) + (endYear - startYear) * 12;
let domainConfigs = [];
let startOfMonth = clone(s.start);
for(var i = 0; i < noOfMonths; i++) {
let endDate = s.end;
if(!areInSameMonth(startOfMonth, s.end)) {
let [month, year] = [startOfMonth.getMonth(), startOfMonth.getFullYear()];
endDate = getLastDateInMonth(month, year);
}
domainConfigs.push(this.getDomainConfig(startOfMonth, endDate));
addDays(endDate, 1);
startOfMonth = endDate;
}
return domainConfigs;
}
getDomainConfig(startDate, endDate='') {
let [month, year] = [startDate.getMonth(), startDate.getFullYear()];
let startOfWeek = setDayToSunday(startDate); // TODO: Monday as well
endDate = clone(endDate) || getLastDateInMonth(month, year);
let domainConfig = {
index: month,
cols: []
};
addDays(endDate, 1);
let noOfMonthWeeks = getWeeksBetween(startOfWeek, endDate);
let cols = [], col;
for(var i = 0; i < noOfMonthWeeks; i++) {
col = this.getCol(startOfWeek, month);
cols.push(col);
startOfWeek = new Date(col[NO_OF_DAYS_IN_WEEK - 1].yyyyMmDd);
addDays(startOfWeek, 1);
}
if(col[NO_OF_DAYS_IN_WEEK - 1].dataValue !== undefined) {
addDays(startOfWeek, 1);
cols.push(this.getCol(startOfWeek, month, true));
}
domainConfig.cols = cols;
return domainConfig;
}
getCol(startDate, month, empty = false) {
let s = this.state;
// startDate is the start of week
let currentDate = clone(startDate);
let col = [];
for(var i = 0; i < NO_OF_DAYS_IN_WEEK; i++, addDays(currentDate, 1)) {
let config = {};
// Non-generic adjustment for entire heatmap, needs state
let currentDateWithinData = currentDate >= s.start && currentDate <= s.end;
if(empty || currentDate.getMonth() !== month || !currentDateWithinData) {
config.yyyyMmDd = getYyyyMmDd(currentDate);
} else {
config = this.getSubDomainConfig(currentDate);
}
col.push(config);
}
return col;
}
getSubDomainConfig(date) {
let yyyyMmDd = getYyyyMmDd(date);
let dataValue = this.data.dataPoints[yyyyMmDd];
let config = {
yyyyMmDd: yyyyMmDd,
dataValue: dataValue || 0,
fill: this.colors[getMaxCheckpoint(dataValue, this.state.distribution)]
};
return config;
}
}

View File

@ -1,173 +0,0 @@
import AxisChart from './AxisChart';
import { Y_AXIS_MARGIN } from '../utils/constants';
// import { ChartComponent } from '../objects/ChartComponents';
import { floatTwo } from '../utils/helpers';
export default class MultiAxisChart extends AxisChart {
constructor(args) {
super(args);
// this.unitType = args.unitType || 'line';
// this.setup();
}
preSetup() {
this.type = 'multiaxis';
}
setMeasures() {
super.setMeasures();
let noOfLeftAxes = this.data.datasets.filter(d => d.axisPosition === 'left').length;
this.measures.margins.left = (noOfLeftAxes) * Y_AXIS_MARGIN || Y_AXIS_MARGIN;
this.measures.margins.right = (this.data.datasets.length - noOfLeftAxes) * Y_AXIS_MARGIN || Y_AXIS_MARGIN;
}
prepareYAxis() { }
prepareData(data) {
super.prepareData(data);
let sets = this.state.datasets;
// let axesLeft = sets.filter(d => d.axisPosition === 'left');
// let axesRight = sets.filter(d => d.axisPosition === 'right');
// let axesNone = sets.filter(d => !d.axisPosition ||
// !['left', 'right'].includes(d.axisPosition));
let leftCount = 0, rightCount = 0;
sets.forEach((d, i) => {
d.yAxis = {
position: d.axisPosition,
index: d.axisPosition === 'left' ? leftCount++ : rightCount++
};
});
}
configure(args) {
super.configure(args);
this.config.xAxisMode = args.xAxisMode || 'tick';
this.config.yAxisMode = args.yAxisMode || 'span';
}
// setUnitWidthAndXOffset() {
// this.state.unitWidth = this.width/(this.state.datasetLength);
// this.state.xOffset = this.state.unitWidth/2;
// }
configUnits() {
this.unitArgs = {
type: 'bar',
args: {
spaceWidth: this.state.unitWidth/2,
}
};
}
setYAxis() {
this.state.datasets.map(d => {
this.calcYAxisParameters(d.yAxis, d.values, this.unitType === 'line');
});
}
calcYUnits() {
this.state.datasets.map(d => {
d.positions = d.values.map(val => floatTwo(d.yAxis.zeroLine - val * d.yAxis.scaleMultiplier));
});
}
// TODO: function doesn't exist, handle with components
renderConstants() {
this.state.datasets.map(d => {
let guidePos = d.yAxis.position === 'left'
? -1 * d.yAxis.index * Y_AXIS_MARGIN
: this.width + d.yAxis.index * Y_AXIS_MARGIN;
this.renderer.xLine(guidePos, '', {
pos:'top',
mode: 'span',
stroke: this.colors[i],
className: 'y-axis-guide'
})
});
}
getYAxesComponents() {
return this.data.datasets.map((e, i) => {
return new ChartComponent({
layerClass: 'y axis y-axis-' + i,
make: () => {
let yAxis = this.state.datasets[i].yAxis;
this.renderer.setZeroline(yAxis.zeroline);
let options = {
pos: yAxis.position,
mode: 'tick',
offset: yAxis.index * Y_AXIS_MARGIN,
stroke: this.colors[i]
};
return yAxis.positions.map((position, j) =>
this.renderer.yLine(position, yAxis.labels[j], options)
);
},
animate: () => {}
});
});
}
// TODO remove renderer zeroline from above and below
getChartComponents() {
return this.data.datasets.map((d, index) => {
return new ChartComponent({
layerClass: 'dataset-units dataset-' + index,
make: () => {
let d = this.state.datasets[index];
let unitType = this.unitArgs;
// the only difference, should be tied to datasets or default
this.renderer.setZeroline(d.yAxis.zeroLine);
return d.positions.map((y, j) => {
return this.renderer[unitType.type](
this.state.xAxisPositions[j],
y,
unitType.args,
this.colors[index],
j,
index,
this.state.datasetLength
);
});
},
animate: (svgUnits) => {
let d = this.state.datasets[index];
let unitType = this.unitArgs.type;
// have been updated in axis render;
let newX = this.state.xAxisPositions;
let newY = this.state.datasets[index].positions;
let lastUnit = svgUnits[svgUnits.length - 1];
let parentNode = lastUnit.parentNode;
if(this.oldState.xExtra > 0) {
for(var i = 0; i<this.oldState.xExtra; i++) {
let unit = lastUnit.cloneNode(true);
parentNode.appendChild(unit);
svgUnits.push(unit);
}
}
this.renderer.setZeroline(d.yAxis.zeroLine);
svgUnits.map((unit, i) => {
if(newX[i] === undefined || newY[i] === undefined) return;
this.elementsToAnimate.push(this.renderer['animate' + unitType](
unit, // unit, with info to replace where it came from in the data
newX[i],
newY[i],
index,
this.state.noOfDatasets
));
});
}
});
});
}
}

View File

@ -1,92 +0,0 @@
import AggregationChart from './AggregationChart';
import { getOffset } from '../utils/dom';
import { getComponent } from '../objects/ChartComponents';
import { PERCENTAGE_BAR_DEFAULT_HEIGHT, PERCENTAGE_BAR_DEFAULT_DEPTH } from '../utils/constants';
export default class PercentageChart extends AggregationChart {
constructor(parent, args) {
super(parent, args);
this.type = 'percentage';
this.setup();
}
setMeasures(options) {
let m = this.measures;
this.barOptions = options.barOptions || {};
let b = this.barOptions;
b.height = b.height || PERCENTAGE_BAR_DEFAULT_HEIGHT;
b.depth = b.depth || PERCENTAGE_BAR_DEFAULT_DEPTH;
m.paddings.right = 30;
m.legendHeight = 60;
m.baseHeight = (b.height + b.depth * 0.5) * 8;
}
setupComponents() {
let s = this.state;
let componentConfigs = [
[
'percentageBars',
{
barHeight: this.barOptions.height,
barDepth: this.barOptions.depth,
},
function() {
return {
xPositions: s.xPositions,
widths: s.widths,
colors: this.colors
};
}.bind(this)
]
];
this.components = new Map(componentConfigs
.map(args => {
let component = getComponent(...args);
return [args[0], component];
}));
}
calc() {
super.calc();
let s = this.state;
s.xPositions = [];
s.widths = [];
let xPos = 0;
s.sliceTotals.map((value) => {
let width = this.width * value / s.grandTotal;
s.widths.push(width);
s.xPositions.push(xPos);
xPos += width;
});
}
makeDataByIndex() { }
bindTooltip() {
let s = this.state;
this.container.addEventListener('mousemove', (e) => {
let bars = this.components.get('percentageBars').store;
let bar = e.target;
if(bars.includes(bar)) {
let i = bars.indexOf(bar);
let gOff = getOffset(this.container), pOff = getOffset(bar);
let x = pOff.left - gOff.left + parseInt(bar.getAttribute('width'))/2;
let y = pOff.top - gOff.top;
let title = (this.formattedLabels && this.formattedLabels.length>0
? this.formattedLabels[i] : this.state.labels[i]) + ': ';
let fraction = s.sliceTotals[i]/s.grandTotal;
this.tip.setValues(x, y, {name: title, value: (fraction*100).toFixed(1) + "%"});
this.tip.showTip();
}
});
}
}

View File

@ -1,155 +0,0 @@
import AggregationChart from './AggregationChart';
import { getComponent } from '../objects/ChartComponents';
import { getOffset } from '../utils/dom';
import { getPositionByAngle } from '../utils/helpers';
import { makeArcPathStr, makeCircleStr } from '../utils/draw';
import { lightenDarkenColor } from '../utils/colors';
import { transform } from '../utils/animation';
import { FULL_ANGLE } from '../utils/constants';
export default class PieChart extends AggregationChart {
constructor(parent, args) {
super(parent, args);
this.type = 'pie';
this.initTimeout = 0;
this.init = 1;
this.setup();
}
configure(args) {
super.configure(args);
this.mouseMove = this.mouseMove.bind(this);
this.mouseLeave = this.mouseLeave.bind(this);
this.hoverRadio = args.hoverRadio || 0.1;
this.config.startAngle = args.startAngle || 0;
this.clockWise = args.clockWise || false;
}
calc() {
super.calc();
let s = this.state;
this.radius = (this.height > this.width ? this.center.x : this.center.y);
const { radius, clockWise } = this;
const prevSlicesProperties = s.slicesProperties || [];
s.sliceStrings = [];
s.slicesProperties = [];
let curAngle = 180 - this.config.startAngle;
s.sliceTotals.map((total, i) => {
const startAngle = curAngle;
const originDiffAngle = (total / s.grandTotal) * FULL_ANGLE;
const largeArc = originDiffAngle > 180 ? 1: 0;
const diffAngle = clockWise ? -originDiffAngle : originDiffAngle;
const endAngle = curAngle = curAngle + diffAngle;
const startPosition = getPositionByAngle(startAngle, radius);
const endPosition = getPositionByAngle(endAngle, radius);
const prevProperty = this.init && prevSlicesProperties[i];
let curStart,curEnd;
if(this.init) {
curStart = prevProperty ? prevProperty.startPosition : startPosition;
curEnd = prevProperty ? prevProperty.endPosition : startPosition;
} else {
curStart = startPosition;
curEnd = endPosition;
}
const curPath =
originDiffAngle === 360
? makeCircleStr(curStart, curEnd, this.center, this.radius, clockWise, largeArc)
: makeArcPathStr(curStart, curEnd, this.center, this.radius, clockWise, largeArc);
s.sliceStrings.push(curPath);
s.slicesProperties.push({
startPosition,
endPosition,
value: total,
total: s.grandTotal,
startAngle,
endAngle,
angle: diffAngle
});
});
this.init = 0;
}
setupComponents() {
let s = this.state;
let componentConfigs = [
[
'pieSlices',
{ },
function() {
return {
sliceStrings: s.sliceStrings,
colors: this.colors
};
}.bind(this)
]
];
this.components = new Map(componentConfigs
.map(args => {
let component = getComponent(...args);
return [args[0], component];
}));
}
calTranslateByAngle(property){
const{radius,hoverRadio} = this;
const position = getPositionByAngle(property.startAngle+(property.angle / 2),radius);
return `translate3d(${(position.x) * hoverRadio}px,${(position.y) * hoverRadio}px,0)`;
}
hoverSlice(path,i,flag,e){
if(!path) return;
const color = this.colors[i];
if(flag) {
transform(path, this.calTranslateByAngle(this.state.slicesProperties[i]));
path.style.fill = lightenDarkenColor(color, 50);
let g_off = getOffset(this.svg);
let x = e.pageX - g_off.left + 10;
let y = e.pageY - g_off.top - 10;
let title = (this.formatted_labels && this.formatted_labels.length > 0
? this.formatted_labels[i] : this.state.labels[i]) + ': ';
let percent = (this.state.sliceTotals[i] * 100 / this.state.grandTotal).toFixed(1);
this.tip.setValues(x, y, {name: title, value: percent + "%"});
this.tip.showTip();
} else {
transform(path,'translate3d(0,0,0)');
this.tip.hideTip();
path.style.fill = color;
}
}
bindTooltip() {
this.container.addEventListener('mousemove', this.mouseMove);
this.container.addEventListener('mouseleave', this.mouseLeave);
}
mouseMove(e){
const target = e.target;
let slices = this.components.get('pieSlices').store;
let prevIndex = this.curActiveSliceIndex;
let prevAcitve = this.curActiveSlice;
if(slices.includes(target)) {
let i = slices.indexOf(target);
this.hoverSlice(prevAcitve, prevIndex,false);
this.curActiveSlice = target;
this.curActiveSliceIndex = i;
this.hoverSlice(target, i, true, e);
} else {
this.mouseLeave();
}
}
mouseLeave(){
this.hoverSlice(this.curActiveSlice,this.curActiveSliceIndex,false);
}
}

View File

@ -1,10 +0,0 @@
import * as Charts from './chart';
let frappe = { };
frappe.NAME = 'Frappe Charts';
frappe.VERSION = '1.6.2';
frappe = Object.assign({ }, frappe, Charts);
export default frappe;

View File

@ -1,446 +0,0 @@
import { makeSVGGroup } from '../utils/draw';
import { makeText, makePath, xLine, yLine, yMarker, yRegion, datasetBar, datasetDot, percentageBar, getPaths, heatSquare } from '../utils/draw';
import { equilizeNoOfElements } from '../utils/draw-utils';
import { translateHoriLine, translateVertLine, animateRegion, animateBar,
animateDot, animatePath, animatePathStr } from '../utils/animate';
import { getMonthName } from '../utils/date-utils';
class ChartComponent {
constructor({
layerClass = '',
layerTransform = '',
constants,
getData,
makeElements,
animateElements
}) {
this.layerTransform = layerTransform;
this.constants = constants;
this.makeElements = makeElements;
this.getData = getData;
this.animateElements = animateElements;
this.store = [];
this.labels = [];
this.layerClass = layerClass;
this.layerClass = typeof(this.layerClass) === 'function'
? this.layerClass() : this.layerClass;
this.refresh();
}
refresh(data) {
this.data = data || this.getData();
}
setup(parent) {
this.layer = makeSVGGroup(this.layerClass, this.layerTransform, parent);
}
make() {
this.render(this.data);
this.oldData = this.data;
}
render(data) {
this.store = this.makeElements(data);
this.layer.textContent = '';
this.store.forEach(element => {
this.layer.appendChild(element);
});
this.labels.forEach(element => {
this.layer.appendChild(element);
});
}
update(animate = true) {
this.refresh();
let animateElements = [];
if(animate) {
animateElements = this.animateElements(this.data) || [];
}
return animateElements;
}
}
let componentConfigs = {
donutSlices: {
layerClass: 'donut-slices',
makeElements(data) {
return data.sliceStrings.map((s, i) => {
let slice = makePath(s, 'donut-path', data.colors[i], 'none', data.strokeWidth);
slice.style.transition = 'transform .3s;';
return slice;
});
},
animateElements(newData) {
return this.store.map((slice, i) => animatePathStr(slice, newData.sliceStrings[i]));
},
},
pieSlices: {
layerClass: 'pie-slices',
makeElements(data) {
return data.sliceStrings.map((s, i) =>{
let slice = makePath(s, 'pie-path', 'none', data.colors[i]);
slice.style.transition = 'transform .3s;';
return slice;
});
},
animateElements(newData) {
return this.store.map((slice, i) =>
animatePathStr(slice, newData.sliceStrings[i])
);
}
},
percentageBars: {
layerClass: 'percentage-bars',
makeElements(data) {
return data.xPositions.map((x, i) =>{
let y = 0;
let bar = percentageBar(x, y, data.widths[i],
this.constants.barHeight, this.constants.barDepth, data.colors[i]);
return bar;
});
},
animateElements(newData) {
if(newData) return [];
}
},
yAxis: {
layerClass: 'y axis',
makeElements(data) {
return data.positions.map((position, i) =>
yLine(position, data.labels[i], this.constants.width,
{mode: this.constants.mode, pos: this.constants.pos, shortenNumbers: this.constants.shortenNumbers})
);
},
animateElements(newData) {
let newPos = newData.positions;
let newLabels = newData.labels;
let oldPos = this.oldData.positions;
let oldLabels = this.oldData.labels;
[oldPos, newPos] = equilizeNoOfElements(oldPos, newPos);
[oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);
this.render({
positions: oldPos,
labels: newLabels
});
return this.store.map((line, i) => {
return translateHoriLine(
line, newPos[i], oldPos[i]
);
});
}
},
xAxis: {
layerClass: 'x axis',
makeElements(data) {
return data.positions.map((position, i) =>
xLine(position, data.calcLabels[i], this.constants.height,
{mode: this.constants.mode, pos: this.constants.pos})
);
},
animateElements(newData) {
let newPos = newData.positions;
let newLabels = newData.calcLabels;
let oldPos = this.oldData.positions;
let oldLabels = this.oldData.calcLabels;
[oldPos, newPos] = equilizeNoOfElements(oldPos, newPos);
[oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);
this.render({
positions: oldPos,
calcLabels: newLabels
});
return this.store.map((line, i) => {
return translateVertLine(
line, newPos[i], oldPos[i]
);
});
}
},
yMarkers: {
layerClass: 'y-markers',
makeElements(data) {
return data.map(m =>
yMarker(m.position, m.label, this.constants.width,
{labelPos: m.options.labelPos, mode: 'span', lineType: 'dashed'})
);
},
animateElements(newData) {
[this.oldData, newData] = equilizeNoOfElements(this.oldData, newData);
let newPos = newData.map(d => d.position);
let newLabels = newData.map(d => d.label);
let newOptions = newData.map(d => d.options);
let oldPos = this.oldData.map(d => d.position);
this.render(oldPos.map((pos, i) => {
return {
position: oldPos[i],
label: newLabels[i],
options: newOptions[i]
};
}));
return this.store.map((line, i) => {
return translateHoriLine(
line, newPos[i], oldPos[i]
);
});
}
},
yRegions: {
layerClass: 'y-regions',
makeElements(data) {
return data.map(r =>
yRegion(r.startPos, r.endPos, this.constants.width,
r.label, {labelPos: r.options.labelPos})
);
},
animateElements(newData) {
[this.oldData, newData] = equilizeNoOfElements(this.oldData, newData);
let newPos = newData.map(d => d.endPos);
let newLabels = newData.map(d => d.label);
let newStarts = newData.map(d => d.startPos);
let newOptions = newData.map(d => d.options);
let oldPos = this.oldData.map(d => d.endPos);
let oldStarts = this.oldData.map(d => d.startPos);
this.render(oldPos.map((pos, i) => {
return {
startPos: oldStarts[i],
endPos: oldPos[i],
label: newLabels[i],
options: newOptions[i]
};
}));
let animateElements = [];
this.store.map((rectGroup, i) => {
animateElements = animateElements.concat(animateRegion(
rectGroup, newStarts[i], newPos[i], oldPos[i]
));
});
return animateElements;
}
},
heatDomain: {
layerClass: function() { return 'heat-domain domain-' + this.constants.index; },
makeElements(data) {
let {index, colWidth, rowHeight, squareSize, radius, xTranslate} = this.constants;
let monthNameHeight = -12;
let x = xTranslate, y = 0;
this.serializedSubDomains = [];
data.cols.map((week, weekNo) => {
if(weekNo === 1) {
this.labels.push(
makeText('domain-name', x, monthNameHeight, getMonthName(index, true).toUpperCase(),
{
fontSize: 9
}
)
);
}
week.map((day, i) => {
if(day.fill) {
let data = {
'data-date': day.yyyyMmDd,
'data-value': day.dataValue,
'data-day': i
};
let square = heatSquare('day', x, y, squareSize, radius, day.fill, data);
this.serializedSubDomains.push(square);
}
y += rowHeight;
});
y = 0;
x += colWidth;
});
return this.serializedSubDomains;
},
animateElements(newData) {
if(newData) return [];
}
},
barGraph: {
layerClass: function() { return 'dataset-units dataset-bars dataset-' + this.constants.index; },
makeElements(data) {
let c = this.constants;
this.unitType = 'bar';
this.units = data.yPositions.map((y, j) => {
return datasetBar(
data.xPositions[j],
y,
data.barWidth,
c.color,
data.labels[j],
j,
data.offsets[j],
{
zeroLine: data.zeroLine,
barsWidth: data.barsWidth,
minHeight: c.minHeight
}
);
});
return this.units;
},
animateElements(newData) {
let newXPos = newData.xPositions;
let newYPos = newData.yPositions;
let newOffsets = newData.offsets;
let newLabels = newData.labels;
let oldXPos = this.oldData.xPositions;
let oldYPos = this.oldData.yPositions;
let oldOffsets = this.oldData.offsets;
let oldLabels = this.oldData.labels;
[oldXPos, newXPos] = equilizeNoOfElements(oldXPos, newXPos);
[oldYPos, newYPos] = equilizeNoOfElements(oldYPos, newYPos);
[oldOffsets, newOffsets] = equilizeNoOfElements(oldOffsets, newOffsets);
[oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);
this.render({
xPositions: oldXPos,
yPositions: oldYPos,
offsets: oldOffsets,
labels: newLabels,
zeroLine: this.oldData.zeroLine,
barsWidth: this.oldData.barsWidth,
barWidth: this.oldData.barWidth,
});
let animateElements = [];
this.store.map((bar, i) => {
animateElements = animateElements.concat(animateBar(
bar, newXPos[i], newYPos[i], newData.barWidth, newOffsets[i],
{zeroLine: newData.zeroLine}
));
});
return animateElements;
}
},
lineGraph: {
layerClass: function() { return 'dataset-units dataset-line dataset-' + this.constants.index; },
makeElements(data) {
let c = this.constants;
this.unitType = 'dot';
this.paths = {};
if(!c.hideLine) {
this.paths = getPaths(
data.xPositions,
data.yPositions,
c.color,
{
heatline: c.heatline,
regionFill: c.regionFill,
spline: c.spline
},
{
svgDefs: c.svgDefs,
zeroLine: data.zeroLine
}
);
}
this.units = [];
if(!c.hideDots) {
this.units = data.yPositions.map((y, j) => {
return datasetDot(
data.xPositions[j],
y,
data.radius,
c.color,
(c.valuesOverPoints ? data.values[j] : ''),
j
);
});
}
return Object.values(this.paths).concat(this.units);
},
animateElements(newData) {
let newXPos = newData.xPositions;
let newYPos = newData.yPositions;
let newValues = newData.values;
let oldXPos = this.oldData.xPositions;
let oldYPos = this.oldData.yPositions;
let oldValues = this.oldData.values;
[oldXPos, newXPos] = equilizeNoOfElements(oldXPos, newXPos);
[oldYPos, newYPos] = equilizeNoOfElements(oldYPos, newYPos);
[oldValues, newValues] = equilizeNoOfElements(oldValues, newValues);
this.render({
xPositions: oldXPos,
yPositions: oldYPos,
values: newValues,
zeroLine: this.oldData.zeroLine,
radius: this.oldData.radius,
});
let animateElements = [];
if(Object.keys(this.paths).length) {
animateElements = animateElements.concat(animatePath(
this.paths, newXPos, newYPos, newData.zeroLine, this.constants.spline));
}
if(this.units.length) {
this.units.map((dot, i) => {
animateElements = animateElements.concat(animateDot(
dot, newXPos[i], newYPos[i]));
});
}
return animateElements;
}
}
};
export function getComponent(name, constants, getData) {
let keys = Object.keys(componentConfigs).filter(k => name.includes(k));
let config = componentConfigs[keys[0]];
Object.assign(config, {
constants: constants,
getData: getData
});
return new ChartComponent(config);
}

View File

@ -1,127 +0,0 @@
import { $ } from '../utils/dom';
import { TOOLTIP_POINTER_TRIANGLE_HEIGHT } from '../utils/constants';
export default class SvgTip {
constructor({
parent = null,
colors = []
}) {
this.parent = parent;
this.colors = colors;
this.titleName = '';
this.titleValue = '';
this.listValues = [];
this.titleValueFirst = 0;
this.x = 0;
this.y = 0;
this.top = 0;
this.left = 0;
this.setup();
}
setup() {
this.makeTooltip();
}
refresh() {
this.fill();
this.calcPosition();
}
makeTooltip() {
this.container = $.create('div', {
inside: this.parent,
className: 'graph-svg-tip comparison',
innerHTML: `<span class="title"></span>
<ul class="data-point-list"></ul>
<div class="svg-pointer"></div>`
});
this.hideTip();
this.title = this.container.querySelector('.title');
this.dataPointList = this.container.querySelector('.data-point-list');
this.parent.addEventListener('mouseleave', () => {
this.hideTip();
});
}
fill() {
let title;
if(this.index) {
this.container.setAttribute('data-point-index', this.index);
}
if(this.titleValueFirst) {
title = `<strong>${this.titleValue}</strong>${this.titleName}`;
} else {
title = `${this.titleName}<strong>${this.titleValue}</strong>`;
}
this.title.innerHTML = title;
this.dataPointList.innerHTML = '';
this.listValues.map((set, i) => {
const color = this.colors[i] || 'black';
let value = set.formatted === 0 || set.formatted ? set.formatted : set.value;
let li = $.create('li', {
styles: {
'border-top': `3px solid ${color}`
},
innerHTML: `<strong style="display: block;">${ value === 0 || value ? value : '' }</strong>
${set.title ? set.title : '' }`
});
this.dataPointList.appendChild(li);
});
}
calcPosition() {
let width = this.container.offsetWidth;
this.top = this.y - this.container.offsetHeight
- TOOLTIP_POINTER_TRIANGLE_HEIGHT;
this.left = this.x - width/2;
let maxLeft = this.parent.offsetWidth - width;
let pointer = this.container.querySelector('.svg-pointer');
if(this.left < 0) {
pointer.style.left = `calc(50% - ${-1 * this.left}px)`;
this.left = 0;
} else if(this.left > maxLeft) {
let delta = this.left - maxLeft;
let pointerOffset = `calc(50% + ${delta}px)`;
pointer.style.left = pointerOffset;
this.left = maxLeft;
} else {
pointer.style.left = `50%`;
}
}
setValues(x, y, title = {}, listValues = [], index = -1) {
this.titleName = title.name;
this.titleValue = title.value;
this.listValues = listValues;
this.x = x;
this.y = y;
this.titleValueFirst = title.valueFirst || 0;
this.index = index;
this.refresh();
}
hideTip() {
this.container.style.top = '0px';
this.container.style.left = '0px';
this.container.style.opacity = '0';
}
showTip() {
this.container.style.top = this.top + 'px';
this.container.style.left = this.left + 'px';
this.container.style.opacity = '1';
}
}

View File

@ -1,105 +0,0 @@
import { getBarHeightAndYAttr, getSplineCurvePointsStr } from './draw-utils';
export const UNIT_ANIM_DUR = 350;
export const PATH_ANIM_DUR = 350;
export const MARKER_LINE_ANIM_DUR = UNIT_ANIM_DUR;
export const REPLACE_ALL_NEW_DUR = 250;
export const STD_EASING = 'easein';
export function translate(unit, oldCoord, newCoord, duration) {
let old = typeof oldCoord === 'string' ? oldCoord : oldCoord.join(', ');
return [
unit,
{transform: newCoord.join(', ')},
duration,
STD_EASING,
"translate",
{transform: old}
];
}
export function translateVertLine(xLine, newX, oldX) {
return translate(xLine, [oldX, 0], [newX, 0], MARKER_LINE_ANIM_DUR);
}
export function translateHoriLine(yLine, newY, oldY) {
return translate(yLine, [0, oldY], [0, newY], MARKER_LINE_ANIM_DUR);
}
export function animateRegion(rectGroup, newY1, newY2, oldY2) {
let newHeight = newY1 - newY2;
let rect = rectGroup.childNodes[0];
let width = rect.getAttribute("width");
let rectAnim = [
rect,
{ height: newHeight, 'stroke-dasharray': `${width}, ${newHeight}` },
MARKER_LINE_ANIM_DUR,
STD_EASING
];
let groupAnim = translate(rectGroup, [0, oldY2], [0, newY2], MARKER_LINE_ANIM_DUR);
return [rectAnim, groupAnim];
}
export function animateBar(bar, x, yTop, width, offset=0, meta={}) {
let [height, y] = getBarHeightAndYAttr(yTop, meta.zeroLine);
y -= offset;
if(bar.nodeName !== 'rect') {
let rect = bar.childNodes[0];
let rectAnim = [
rect,
{width: width, height: height},
UNIT_ANIM_DUR,
STD_EASING
];
let oldCoordStr = bar.getAttribute("transform").split("(")[1].slice(0, -1);
let groupAnim = translate(bar, oldCoordStr, [x, y], MARKER_LINE_ANIM_DUR);
return [rectAnim, groupAnim];
} else {
return [[bar, {width: width, height: height, x: x, y: y}, UNIT_ANIM_DUR, STD_EASING]];
}
// bar.animate({height: args.newHeight, y: yTop}, UNIT_ANIM_DUR, mina.easein);
}
export function animateDot(dot, x, y) {
if(dot.nodeName !== 'circle') {
let oldCoordStr = dot.getAttribute("transform").split("(")[1].slice(0, -1);
let groupAnim = translate(dot, oldCoordStr, [x, y], MARKER_LINE_ANIM_DUR);
return [groupAnim];
} else {
return [[dot, {cx: x, cy: y}, UNIT_ANIM_DUR, STD_EASING]];
}
// dot.animate({cy: yTop}, UNIT_ANIM_DUR, mina.easein);
}
export function animatePath(paths, newXList, newYList, zeroLine, spline) {
let pathComponents = [];
let pointsStr = newYList.map((y, i) => (newXList[i] + ',' + y)).join("L");
if (spline)
pointsStr = getSplineCurvePointsStr(newXList, newYList);
const animPath = [paths.path, {d:"M" + pointsStr}, PATH_ANIM_DUR, STD_EASING];
pathComponents.push(animPath);
if(paths.region) {
let regStartPt = `${newXList[0]},${zeroLine}L`;
let regEndPt = `L${newXList.slice(-1)[0]}, ${zeroLine}`;
const animRegion = [
paths.region,
{d:"M" + regStartPt + pointsStr + regEndPt},
PATH_ANIM_DUR,
STD_EASING
];
pathComponents.push(animRegion);
}
return pathComponents;
}
export function animatePathStr(oldPath, pathStr) {
return [oldPath, {d: pathStr}, UNIT_ANIM_DUR, STD_EASING];
}

View File

@ -1,120 +0,0 @@
// Leveraging SMIL Animations
import { REPLACE_ALL_NEW_DUR } from './animate';
const EASING = {
ease: "0.25 0.1 0.25 1",
linear: "0 0 1 1",
// easein: "0.42 0 1 1",
easein: "0.1 0.8 0.2 1",
easeout: "0 0 0.58 1",
easeinout: "0.42 0 0.58 1"
};
function animateSVGElement(element, props, dur, easingType="linear", type=undefined, oldValues={}) {
let animElement = element.cloneNode(true);
let newElement = element.cloneNode(true);
for(var attributeName in props) {
let animateElement;
if(attributeName === 'transform') {
animateElement = document.createElementNS("http://www.w3.org/2000/svg", "animateTransform");
} else {
animateElement = document.createElementNS("http://www.w3.org/2000/svg", "animate");
}
let currentValue = oldValues[attributeName] || element.getAttribute(attributeName);
let value = props[attributeName];
let animAttr = {
attributeName: attributeName,
from: currentValue,
to: value,
begin: "0s",
dur: dur/1000 + "s",
values: currentValue + ";" + value,
keySplines: EASING[easingType],
keyTimes: "0;1",
calcMode: "spline",
fill: 'freeze'
};
if(type) {
animAttr["type"] = type;
}
for (var i in animAttr) {
animateElement.setAttribute(i, animAttr[i]);
}
animElement.appendChild(animateElement);
if(type) {
newElement.setAttribute(attributeName, `translate(${value})`);
} else {
newElement.setAttribute(attributeName, value);
}
}
return [animElement, newElement];
}
export function transform(element, style) { // eslint-disable-line no-unused-vars
element.style.transform = style;
element.style.webkitTransform = style;
element.style.msTransform = style;
element.style.mozTransform = style;
element.style.oTransform = style;
}
function animateSVG(svgContainer, elements) {
let newElements = [];
let animElements = [];
elements.map(element => {
let unit = element[0];
let parent = unit.parentNode;
let animElement, newElement;
element[0] = unit;
[animElement, newElement] = animateSVGElement(...element);
newElements.push(newElement);
animElements.push([animElement, parent]);
if (parent) {
parent.replaceChild(animElement, unit);
}
});
let animSvg = svgContainer.cloneNode(true);
animElements.map((animElement, i) => {
if (animElement[1]) {
animElement[1].replaceChild(newElements[i], animElement[0]);
elements[i][0] = newElements[i];
}
});
return animSvg;
}
export function runSMILAnimation(parent, svgElement, elementsToAnimate) {
if(elementsToAnimate.length === 0) return;
let animSvgElement = animateSVG(svgElement, elementsToAnimate);
if(svgElement.parentNode == parent) {
parent.removeChild(svgElement);
parent.appendChild(animSvgElement);
}
// Replace the new svgElement (data has already been replaced)
setTimeout(() => {
if(animSvgElement.parentNode == parent) {
parent.removeChild(animSvgElement);
parent.appendChild(svgElement);
}
}, REPLACE_ALL_NEW_DUR);
}

View File

@ -1,129 +0,0 @@
import { fillArray } from '../utils/helpers';
import { DEFAULT_AXIS_CHART_TYPE, AXIS_DATASET_CHART_TYPES, DEFAULT_CHAR_WIDTH } from '../utils/constants';
export function dataPrep(data, type) {
data.labels = data.labels || [];
let datasetLength = data.labels.length;
// Datasets
let datasets = data.datasets;
let zeroArray = new Array(datasetLength).fill(0);
if(!datasets) {
// default
datasets = [{
values: zeroArray
}];
}
datasets.map(d=> {
// Set values
if(!d.values) {
d.values = zeroArray;
} else {
// Check for non values
let vals = d.values;
vals = vals.map(val => (!isNaN(val) ? val : 0));
// Trim or extend
if(vals.length > datasetLength) {
vals = vals.slice(0, datasetLength);
} else {
vals = fillArray(vals, datasetLength - vals.length, 0);
}
d.values = vals;
}
// Set type
if(!d.chartType ) {
if(!AXIS_DATASET_CHART_TYPES.includes(type)) type === DEFAULT_AXIS_CHART_TYPE;
d.chartType = type;
}
});
// Markers
// Regions
// data.yRegions = data.yRegions || [];
if(data.yRegions) {
data.yRegions.map(d => {
if(d.end < d.start) {
[d.start, d.end] = [d.end, d.start];
}
});
}
return data;
}
export function zeroDataPrep(realData) {
let datasetLength = realData.labels.length;
let zeroArray = new Array(datasetLength).fill(0);
let zeroData = {
labels: realData.labels.slice(0, -1),
datasets: realData.datasets.map(d => {
return {
name: '',
values: zeroArray.slice(0, -1),
chartType: d.chartType
};
}),
};
if(realData.yMarkers) {
zeroData.yMarkers = [
{
value: 0,
label: ''
}
];
}
if(realData.yRegions) {
zeroData.yRegions = [
{
start: 0,
end: 0,
label: ''
}
];
}
return zeroData;
}
export function getShortenedLabels(chartWidth, labels=[], isSeries=true) {
let allowedSpace = chartWidth / labels.length;
if(allowedSpace <= 0) allowedSpace = 1;
let allowedLetters = allowedSpace / DEFAULT_CHAR_WIDTH;
let seriesMultiple;
if(isSeries) {
// Find the maximum label length for spacing calculations
let maxLabelLength = Math.max(...labels.map(label => label.length));
seriesMultiple = Math.ceil(maxLabelLength/allowedLetters);
}
let calcLabels = labels.map((label, i) => {
label += "";
if(label.length > allowedLetters) {
if(!isSeries) {
if(allowedLetters-3 > 0) {
label = label.slice(0, allowedLetters-3) + " ...";
} else {
label = label.slice(0, allowedLetters) + '..';
}
} else {
if(i % seriesMultiple !== 0) {
label = "";
}
}
}
return label;
});
return calcLabels;
}

View File

@ -1,53 +0,0 @@
const PRESET_COLOR_MAP = {
'light-blue': '#7cd6fd',
'blue': '#5e64ff',
'violet': '#743ee2',
'red': '#ff5858',
'orange': '#ffa00a',
'yellow': '#feef72',
'green': '#28a745',
'light-green': '#98d85b',
'purple': '#b554ff',
'magenta': '#ffa3ef',
'black': '#36114C',
'grey': '#bdd3e6',
'light-grey': '#f0f4f7',
'dark-grey': '#b8c2cc'
};
function limitColor(r){
if (r > 255) return 255;
else if (r < 0) return 0;
return r;
}
export function lightenDarkenColor(color, amt) {
let col = getColor(color);
let usePound = false;
if (col[0] == "#") {
col = col.slice(1);
usePound = true;
}
let num = parseInt(col,16);
let r = limitColor((num >> 16) + amt);
let b = limitColor(((num >> 8) & 0x00FF) + amt);
let g = limitColor((num & 0x0000FF) + amt);
return (usePound?"#":"") + (g | (b << 8) | (r << 16)).toString(16);
}
export function isValidColor(string) {
// https://stackoverflow.com/a/32685393
let HEX_RE = /(^\s*)(#)((?:[A-Fa-f0-9]{3}){1,2})$/i;
let RGB_RE = /(^\s*)(rgb|hsl)(a?)[(]\s*([\d.]+\s*%?)\s*,\s*([\d.]+\s*%?)\s*,\s*([\d.]+\s*%?)\s*(?:,\s*([\d.]+)\s*)?[)]$/i;
return HEX_RE.test(string) || RGB_RE.test(string);
}
export const getColor = (color) => {
// When RGB color, convert to hexadecimal (alpha value is omitted)
if((/rgb[a]{0,1}\([\d, ]+\)/gim).test(color)) {
return (/\D+(\d*)\D+(\d*)\D+(\d*)/gim).exec(color)
.map((x, i) => (i !== 0 ? Number(x).toString(16) : '#'))
.reduce((c, ch) => `${c}${ch}`);
}
return PRESET_COLOR_MAP[color] || color;
};

View File

@ -1,107 +0,0 @@
export const ALL_CHART_TYPES = ['line', 'scatter', 'bar', 'percentage', 'heatmap', 'pie'];
export const COMPATIBLE_CHARTS = {
bar: ['line', 'scatter', 'percentage', 'pie'],
line: ['scatter', 'bar', 'percentage', 'pie'],
pie: ['line', 'scatter', 'percentage', 'bar'],
percentage: ['bar', 'line', 'scatter', 'pie'],
heatmap: []
};
export const DATA_COLOR_DIVISIONS = {
bar: 'datasets',
line: 'datasets',
pie: 'labels',
percentage: 'labels',
heatmap: HEATMAP_DISTRIBUTION_SIZE
};
export const BASE_MEASURES = {
margins: {
top: 10,
bottom: 10,
left: 20,
right: 20
},
paddings: {
top: 20,
bottom: 40,
left: 30,
right: 10
},
baseHeight: 240,
titleHeight: 20,
legendHeight: 30,
titleFontSize: 12,
};
export function getTopOffset(m) {
return m.titleHeight + m.margins.top + m.paddings.top;
}
export function getLeftOffset(m) {
return m.margins.left + m.paddings.left;
}
export function getExtraHeight(m) {
let totalExtraHeight = m.margins.top + m.margins.bottom
+ m.paddings.top + m.paddings.bottom
+ m.titleHeight + m.legendHeight;
return totalExtraHeight;
}
export function getExtraWidth(m) {
let totalExtraWidth = m.margins.left + m.margins.right
+ m.paddings.left + m.paddings.right;
return totalExtraWidth;
}
export const INIT_CHART_UPDATE_TIMEOUT = 700;
export const CHART_POST_ANIMATE_TIMEOUT = 400;
export const DEFAULT_AXIS_CHART_TYPE = 'line';
export const AXIS_DATASET_CHART_TYPES = ['line', 'bar'];
export const AXIS_LEGEND_BAR_SIZE = 100;
export const BAR_CHART_SPACE_RATIO = 0.5;
export const MIN_BAR_PERCENT_HEIGHT = 0.00;
export const LINE_CHART_DOT_SIZE = 4;
export const DOT_OVERLAY_SIZE_INCR = 4;
export const PERCENTAGE_BAR_DEFAULT_HEIGHT = 20;
export const PERCENTAGE_BAR_DEFAULT_DEPTH = 2;
// Fixed 5-color theme,
// More colors are difficult to parse visually
export const HEATMAP_DISTRIBUTION_SIZE = 5;
export const HEATMAP_SQUARE_SIZE = 10;
export const HEATMAP_GUTTER_SIZE = 2;
export const DEFAULT_CHAR_WIDTH = 7;
export const TOOLTIP_POINTER_TRIANGLE_HEIGHT = 5;
const DEFAULT_CHART_COLORS = ['light-blue', 'blue', 'violet', 'red', 'orange',
'yellow', 'green', 'light-green', 'purple', 'magenta', 'light-grey', 'dark-grey'];
const HEATMAP_COLORS_GREEN = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127'];
export const HEATMAP_COLORS_BLUE = ['#ebedf0', '#c0ddf9', '#73b3f3', '#3886e1', '#17459e'];
export const HEATMAP_COLORS_YELLOW = ['#ebedf0', '#fdf436', '#ffc700', '#ff9100', '#06001c'];
export const DEFAULT_COLORS = {
bar: DEFAULT_CHART_COLORS,
line: DEFAULT_CHART_COLORS,
pie: DEFAULT_CHART_COLORS,
percentage: DEFAULT_CHART_COLORS,
heatmap: HEATMAP_COLORS_GREEN,
donut: DEFAULT_CHART_COLORS
};
// Universal constants
export const ANGLE_RATIO = Math.PI / 180;
export const FULL_ANGLE = 360;

View File

@ -1,90 +0,0 @@
// Playing around with dates
export const NO_OF_YEAR_MONTHS = 12;
export const NO_OF_DAYS_IN_WEEK = 7;
export const DAYS_IN_YEAR = 375;
export const NO_OF_MILLIS = 1000;
export const SEC_IN_DAY = 86400;
export const MONTH_NAMES = ["January", "February", "March", "April", "May",
"June", "July", "August", "September", "October", "November", "December"];
export const MONTH_NAMES_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
export const DAY_NAMES_SHORT = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
export const DAY_NAMES = ["Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"];
// https://stackoverflow.com/a/11252167/6495043
function treatAsUtc(date) {
let result = new Date(date);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}
export function getYyyyMmDd(date) {
let dd = date.getDate();
let mm = date.getMonth() + 1; // getMonth() is zero-based
return [
date.getFullYear(),
(mm>9 ? '' : '0') + mm,
(dd>9 ? '' : '0') + dd
].join('-');
}
export function clone(date) {
return new Date(date.getTime());
}
export function timestampSec(date) {
return date.getTime()/NO_OF_MILLIS;
}
export function timestampToMidnight(timestamp, roundAhead = false) {
let midnightTs = Math.floor(timestamp - (timestamp % SEC_IN_DAY));
if(roundAhead) {
return midnightTs + SEC_IN_DAY;
}
return midnightTs;
}
// export function getMonthsBetween(startDate, endDate) {}
export function getWeeksBetween(startDate, endDate) {
let weekStartDate = setDayToSunday(startDate);
return Math.ceil(getDaysBetween(weekStartDate, endDate) / NO_OF_DAYS_IN_WEEK);
}
export function getDaysBetween(startDate, endDate) {
let millisecondsPerDay = SEC_IN_DAY * NO_OF_MILLIS;
return (treatAsUtc(endDate) - treatAsUtc(startDate)) / millisecondsPerDay;
}
export function areInSameMonth(startDate, endDate) {
return startDate.getMonth() === endDate.getMonth()
&& startDate.getFullYear() === endDate.getFullYear();
}
export function getMonthName(i, short=false) {
let monthName = MONTH_NAMES[i];
return short ? monthName.slice(0, 3) : monthName;
}
export function getLastDateInMonth (month, year) {
return new Date(year, month + 1, 0); // 0: last day in previous month
}
// mutates
export function setDayToSunday(date) {
let newDate = clone(date);
const day = newDate.getDay();
if(day !== 0) {
addDays(newDate, (-1) * day);
}
return newDate;
}
// mutates
export function addDays(date, numberOfDays) {
date.setDate(date.getDate() + numberOfDays);
}

View File

@ -1,137 +0,0 @@
export function $(expr, con) {
return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
}
export function findNodeIndex(node)
{
var i = 0;
while (node.previousSibling) {
node = node.previousSibling;
i++;
}
return i;
}
$.create = (tag, o) => {
var element = document.createElement(tag);
for (var i in o) {
var val = o[i];
if (i === "inside") {
$(val).appendChild(element);
}
else if (i === "around") {
var ref = $(val);
ref.parentNode.insertBefore(element, ref);
element.appendChild(ref);
} else if (i === "styles") {
if(typeof val === "object") {
Object.keys(val).map(prop => {
element.style[prop] = val[prop];
});
}
} else if (i in element ) {
element[i] = val;
}
else {
element.setAttribute(i, val);
}
}
return element;
};
export function getOffset(element) {
let rect = element.getBoundingClientRect();
return {
// https://stackoverflow.com/a/7436602/6495043
// rect.top varies with scroll, so we add whatever has been
// scrolled to it to get absolute distance from actual page top
top: rect.top + (document.documentElement.scrollTop || document.body.scrollTop),
left: rect.left + (document.documentElement.scrollLeft || document.body.scrollLeft)
};
}
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent
// an element's offsetParent property will return null whenever it, or any of its parents,
// is hidden via the display style property.
export function isHidden(el) {
return (el.offsetParent === null);
}
export function isElementInViewport(el) {
// Although straightforward: https://stackoverflow.com/a/7557433/6495043
var rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
);
}
export function getElementContentWidth(element) {
var styles = window.getComputedStyle(element);
var padding = parseFloat(styles.paddingLeft) +
parseFloat(styles.paddingRight);
return element.clientWidth - padding;
}
export function bind(element, o){
if (element) {
for (var event in o) {
var callback = o[event];
event.split(/\s+/).forEach(function (event) {
element.addEventListener(event, callback);
});
}
}
}
export function unbind(element, o){
if (element) {
for (var event in o) {
var callback = o[event];
event.split(/\s+/).forEach(function(event) {
element.removeEventListener(event, callback);
});
}
}
}
export function fire(target, type, properties) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent(type, true, true );
for (var j in properties) {
evt[j] = properties[j];
}
return target.dispatchEvent(evt);
}
// https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/
export function forEachNode(nodeList, callback, scope) {
if(!nodeList) return;
for (var i = 0; i < nodeList.length; i++) {
callback.call(scope, nodeList[i], i);
}
}
export function activate($parent, $child, commonClass, activeClass='active', index = -1) {
let $children = $parent.querySelectorAll(`.${commonClass}.${activeClass}`);
forEachNode($children, (node, i) => {
if(index >= 0 && i <= index) return;
node.classList.remove(activeClass);
});
$child.classList.add(activeClass);
}

View File

@ -1,99 +0,0 @@
import { fillArray } from './helpers';
export function getBarHeightAndYAttr(yTop, zeroLine) {
let height, y;
if (yTop <= zeroLine) {
height = zeroLine - yTop;
y = yTop;
} else {
height = yTop - zeroLine;
y = zeroLine;
}
return [height, y];
}
export function equilizeNoOfElements(array1, array2,
extraCount = array2.length - array1.length) {
// Doesn't work if either has zero elements.
if(extraCount > 0) {
array1 = fillArray(array1, extraCount);
} else {
array2 = fillArray(array2, extraCount);
}
return [array1, array2];
}
export function truncateString(txt, len) {
if (!txt) {
return;
}
if (txt.length > len) {
return txt.slice(0, len-3) + '...';
} else {
return txt;
}
}
export function shortenLargeNumber(label) {
let number;
if (typeof label === 'number') number = label;
else if (typeof label === 'string') {
number = Number(label);
if (Number.isNaN(number)) return label;
}
// Using absolute since log wont work for negative numbers
let p = Math.floor(Math.log10(Math.abs(number)));
if (p <= 2) return number; // Return as is for a 3 digit number of less
let l = Math.floor(p / 3);
let shortened = (Math.pow(10, p - l * 3) * +(number / Math.pow(10, p)).toFixed(1));
// Correct for floating point error upto 2 decimal places
return Math.round(shortened*100)/100 + ' ' + ['', 'K', 'M', 'B', 'T'][l];
}
// cubic bezier curve calculation (from example by François Romain)
export function getSplineCurvePointsStr(xList, yList) {
let points=[];
for(let i=0;i<xList.length;i++){
points.push([xList[i], yList[i]]);
}
let smoothing = 0.2;
let line = (pointA, pointB) => {
let lengthX = pointB[0] - pointA[0];
let lengthY = pointB[1] - pointA[1];
return {
length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
angle: Math.atan2(lengthY, lengthX)
};
};
let controlPoint = (current, previous, next, reverse) => {
let p = previous || current;
let n = next || current;
let o = line(p, n);
let angle = o.angle + (reverse ? Math.PI : 0);
let length = o.length * smoothing;
let x = current[0] + Math.cos(angle) * length;
let y = current[1] + Math.sin(angle) * length;
return [x, y];
};
let bezierCommand = (point, i, a) => {
let cps = controlPoint(a[i - 1], a[i - 2], point);
let cpe = controlPoint(point, a[i - 1], a[i + 1], true);
return `C ${cps[0]},${cps[1]} ${cpe[0]},${cpe[1]} ${point[0]},${point[1]}`;
};
let pointStr = (points, command) => {
return points.reduce((acc, point, i, a) => i === 0
? `${point[0]},${point[1]}`
: `${acc} ${command(point, i, a)}`, '');
};
return pointStr(points, bezierCommand);
}

View File

@ -1,731 +0,0 @@
import { getBarHeightAndYAttr, truncateString, shortenLargeNumber, getSplineCurvePointsStr } from './draw-utils';
import { getStringWidth, isValidNumber } from './helpers';
import { DOT_OVERLAY_SIZE_INCR, PERCENTAGE_BAR_DEFAULT_DEPTH } from './constants';
import { lightenDarkenColor } from './colors';
export const AXIS_TICK_LENGTH = 6;
const LABEL_MARGIN = 4;
const LABEL_MAX_CHARS = 15;
export const FONT_SIZE = 10;
const BASE_LINE_COLOR = '#dadada';
const FONT_FILL = '#555b51';
function $(expr, con) {
return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
}
export function createSVG(tag, o) {
var element = document.createElementNS("http://www.w3.org/2000/svg", tag);
for (var i in o) {
var val = o[i];
if (i === "inside") {
$(val).appendChild(element);
}
else if (i === "around") {
var ref = $(val);
ref.parentNode.insertBefore(element, ref);
element.appendChild(ref);
} else if (i === "styles") {
if(typeof val === "object") {
Object.keys(val).map(prop => {
element.style[prop] = val[prop];
});
}
} else {
if(i === "className") { i = "class"; }
if(i === "innerHTML") {
element['textContent'] = val;
} else {
element.setAttribute(i, val);
}
}
}
return element;
}
function renderVerticalGradient(svgDefElem, gradientId) {
return createSVG('linearGradient', {
inside: svgDefElem,
id: gradientId,
x1: 0,
x2: 0,
y1: 0,
y2: 1
});
}
function setGradientStop(gradElem, offset, color, opacity) {
return createSVG('stop', {
'inside': gradElem,
'style': `stop-color: ${color}`,
'offset': offset,
'stop-opacity': opacity
});
}
export function makeSVGContainer(parent, className, width, height) {
return createSVG('svg', {
className: className,
inside: parent,
width: width,
height: height
});
}
export function makeSVGDefs(svgContainer) {
return createSVG('defs', {
inside: svgContainer,
});
}
export function makeSVGGroup(className, transform='', parent=undefined) {
let args = {
className: className,
transform: transform
};
if(parent) args.inside = parent;
return createSVG('g', args);
}
export function wrapInSVGGroup(elements, className='') {
let g = createSVG('g', {
className: className
});
elements.forEach(e => g.appendChild(e));
return g;
}
export function makePath(pathStr, className='', stroke='none', fill='none', strokeWidth=2) {
return createSVG('path', {
className: className,
d: pathStr,
styles: {
stroke: stroke,
fill: fill,
'stroke-width': strokeWidth
}
});
}
export function makeArcPathStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){
let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];
let [arcEndX, arcEndY] = [center.x + endPosition.x, center.y + endPosition.y];
return `M${center.x} ${center.y}
L${arcStartX} ${arcStartY}
A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${arcEndY} z`;
}
export function makeCircleStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){
let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];
let [arcEndX, midArc, arcEndY] = [center.x + endPosition.x, center.y * 2, center.y + endPosition.y];
return `M${center.x} ${center.y}
L${arcStartX} ${arcStartY}
A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${midArc} z
L${arcStartX} ${midArc}
A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${arcEndY} z`;
}
export function makeArcStrokePathStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){
let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];
let [arcEndX, arcEndY] = [center.x + endPosition.x, center.y + endPosition.y];
return `M${arcStartX} ${arcStartY}
A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${arcEndY}`;
}
export function makeStrokeCircleStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){
let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];
let [arcEndX, midArc, arcEndY] = [center.x + endPosition.x, radius * 2 + arcStartY, center.y + startPosition.y];
return `M${arcStartX} ${arcStartY}
A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${midArc}
M${arcStartX} ${midArc}
A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${arcEndY}`;
}
export function makeGradient(svgDefElem, color, lighter = false) {
let gradientId ='path-fill-gradient' + '-' + color + '-' +(lighter ? 'lighter' : 'default');
let gradientDef = renderVerticalGradient(svgDefElem, gradientId);
let opacities = [1, 0.6, 0.2];
if(lighter) {
opacities = [0.4, 0.2, 0];
}
setGradientStop(gradientDef, "0%", color, opacities[0]);
setGradientStop(gradientDef, "50%", color, opacities[1]);
setGradientStop(gradientDef, "100%", color, opacities[2]);
return gradientId;
}
export function percentageBar(x, y, width, height,
depth=PERCENTAGE_BAR_DEFAULT_DEPTH, fill='none') {
let args = {
className: 'percentage-bar',
x: x,
y: y,
width: width,
height: height,
fill: fill,
styles: {
'stroke': lightenDarkenColor(fill, -25),
// Diabolically good: https://stackoverflow.com/a/9000859
// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray
'stroke-dasharray': `0, ${height + width}, ${width}, ${height}`,
'stroke-width': depth
},
};
return createSVG("rect", args);
}
export function heatSquare(className, x, y, size, radius, fill='none', data={}) {
let args = {
className: className,
x: x,
y: y,
width: size,
height: size,
rx: radius,
fill: fill
};
Object.keys(data).map(key => {
args[key] = data[key];
});
return createSVG("rect", args);
}
export function legendBar(x, y, size, fill='none', label, truncate=false) {
label = truncate ? truncateString(label, LABEL_MAX_CHARS) : label;
let args = {
className: 'legend-bar',
x: 0,
y: 0,
width: size,
height: '2px',
fill: fill
};
let text = createSVG('text', {
className: 'legend-dataset-text',
x: 0,
y: 0,
dy: (FONT_SIZE * 2) + 'px',
'font-size': (FONT_SIZE * 1.2) + 'px',
'text-anchor': 'start',
fill: FONT_FILL,
innerHTML: label
});
let group = createSVG('g', {
transform: `translate(${x}, ${y})`
});
group.appendChild(createSVG("rect", args));
group.appendChild(text);
return group;
}
export function legendDot(x, y, size, fill='none', label, truncate=false) {
label = truncate ? truncateString(label, LABEL_MAX_CHARS) : label;
let args = {
className: 'legend-dot',
cx: 0,
cy: 0,
r: size,
fill: fill
};
let text = createSVG('text', {
className: 'legend-dataset-text',
x: 0,
y: 0,
dx: (FONT_SIZE) + 'px',
dy: (FONT_SIZE/3) + 'px',
'font-size': (FONT_SIZE * 1.2) + 'px',
'text-anchor': 'start',
fill: FONT_FILL,
innerHTML: label
});
let group = createSVG('g', {
transform: `translate(${x}, ${y})`
});
group.appendChild(createSVG("circle", args));
group.appendChild(text);
return group;
}
export function makeText(className, x, y, content, options = {}) {
let fontSize = options.fontSize || FONT_SIZE;
let dy = options.dy !== undefined ? options.dy : (fontSize / 2);
let fill = options.fill || FONT_FILL;
let textAnchor = options.textAnchor || 'start';
return createSVG('text', {
className: className,
x: x,
y: y,
dy: dy + 'px',
'font-size': fontSize + 'px',
fill: fill,
'text-anchor': textAnchor,
innerHTML: content
});
}
function makeVertLine(x, label, y1, y2, options={}) {
if(!options.stroke) options.stroke = BASE_LINE_COLOR;
let l = createSVG('line', {
className: 'line-vertical ' + options.className,
x1: 0,
x2: 0,
y1: y1,
y2: y2,
styles: {
stroke: options.stroke
}
});
let text = createSVG('text', {
x: 0,
y: y1 > y2 ? y1 + LABEL_MARGIN : y1 - LABEL_MARGIN - FONT_SIZE,
dy: FONT_SIZE + 'px',
'font-size': FONT_SIZE + 'px',
'text-anchor': 'middle',
innerHTML: label + ""
});
let line = createSVG('g', {
transform: `translate(${ x }, 0)`
});
line.appendChild(l);
line.appendChild(text);
return line;
}
function makeHoriLine(y, label, x1, x2, options={}) {
if(!options.stroke) options.stroke = BASE_LINE_COLOR;
if(!options.lineType) options.lineType = '';
if (options.shortenNumbers) label = shortenLargeNumber(label);
let className = 'line-horizontal ' + options.className +
(options.lineType === "dashed" ? "dashed": "");
let l = createSVG('line', {
className: className,
x1: x1,
x2: x2,
y1: 0,
y2: 0,
styles: {
stroke: options.stroke
}
});
let text = createSVG('text', {
x: x1 < x2 ? x1 - LABEL_MARGIN : x1 + LABEL_MARGIN,
y: 0,
dy: (FONT_SIZE / 2 - 2) + 'px',
'font-size': FONT_SIZE + 'px',
'text-anchor': x1 < x2 ? 'end' : 'start',
innerHTML: label+""
});
let line = createSVG('g', {
transform: `translate(0, ${y})`,
'stroke-opacity': 1
});
if(text === 0 || text === '0') {
line.style.stroke = "rgba(27, 31, 35, 0.6)";
}
line.appendChild(l);
line.appendChild(text);
return line;
}
export function yLine(y, label, width, options={}) {
if (!isValidNumber(y)) y = 0;
if(!options.pos) options.pos = 'left';
if(!options.offset) options.offset = 0;
if(!options.mode) options.mode = 'span';
if(!options.stroke) options.stroke = BASE_LINE_COLOR;
if(!options.className) options.className = '';
let x1 = -1 * AXIS_TICK_LENGTH;
let x2 = options.mode === 'span' ? width + AXIS_TICK_LENGTH : 0;
if(options.mode === 'tick' && options.pos === 'right') {
x1 = width + AXIS_TICK_LENGTH;
x2 = width;
}
// let offset = options.pos === 'left' ? -1 * options.offset : options.offset;
x1 += options.offset;
x2 += options.offset;
return makeHoriLine(y, label, x1, x2, {
stroke: options.stroke,
className: options.className,
lineType: options.lineType,
shortenNumbers: options.shortenNumbers
});
}
export function xLine(x, label, height, options={}) {
if (!isValidNumber(x)) x = 0;
if(!options.pos) options.pos = 'bottom';
if(!options.offset) options.offset = 0;
if(!options.mode) options.mode = 'span';
if(!options.stroke) options.stroke = BASE_LINE_COLOR;
if(!options.className) options.className = '';
// Draw X axis line in span/tick mode with optional label
// y2(span)
// |
// |
// x line |
// |
// |
// ---------------------+-- y2(tick)
// |
// y1
let y1 = height + AXIS_TICK_LENGTH;
let y2 = options.mode === 'span' ? -1 * AXIS_TICK_LENGTH : height;
if(options.mode === 'tick' && options.pos === 'top') {
// top axis ticks
y1 = -1 * AXIS_TICK_LENGTH;
y2 = 0;
}
return makeVertLine(x, label, y1, y2, {
stroke: options.stroke,
className: options.className,
lineType: options.lineType
});
}
export function yMarker(y, label, width, options={}) {
if(!options.labelPos) options.labelPos = 'right';
let x = options.labelPos === 'left' ? LABEL_MARGIN
: width - getStringWidth(label, 5) - LABEL_MARGIN;
let labelSvg = createSVG('text', {
className: 'chart-label',
x: x,
y: 0,
dy: (FONT_SIZE / -2) + 'px',
'font-size': FONT_SIZE + 'px',
'text-anchor': 'start',
innerHTML: label+""
});
let line = makeHoriLine(y, '', 0, width, {
stroke: options.stroke || BASE_LINE_COLOR,
className: options.className || '',
lineType: options.lineType
});
line.appendChild(labelSvg);
return line;
}
export function yRegion(y1, y2, width, label, options={}) {
// return a group
let height = y1 - y2;
let rect = createSVG('rect', {
className: `bar mini`, // remove class
styles: {
fill: `rgba(228, 234, 239, 0.49)`,
stroke: BASE_LINE_COLOR,
'stroke-dasharray': `${width}, ${height}`
},
// 'data-point-index': index,
x: 0,
y: 0,
width: width,
height: height
});
if(!options.labelPos) options.labelPos = 'right';
let x = options.labelPos === 'left' ? LABEL_MARGIN
: width - getStringWidth(label+"", 4.5) - LABEL_MARGIN;
let labelSvg = createSVG('text', {
className: 'chart-label',
x: x,
y: 0,
dy: (FONT_SIZE / -2) + 'px',
'font-size': FONT_SIZE + 'px',
'text-anchor': 'start',
innerHTML: label+""
});
let region = createSVG('g', {
transform: `translate(0, ${y2})`
});
region.appendChild(rect);
region.appendChild(labelSvg);
return region;
}
export function datasetBar(x, yTop, width, color, label='', index=0, offset=0, meta={}) {
let [height, y] = getBarHeightAndYAttr(yTop, meta.zeroLine);
y -= offset;
if(height === 0) {
height = meta.minHeight;
y -= meta.minHeight;
}
// Preprocess numbers to avoid svg building errors
if (!isValidNumber(x)) x = 0;
if (!isValidNumber(y)) y = 0;
if (!isValidNumber(height, true)) height = 0;
if (!isValidNumber(width, true)) width = 0;
let rect = createSVG('rect', {
className: `bar mini`,
style: `fill: ${color}`,
'data-point-index': index,
x: x,
y: y,
width: width,
height: height
});
label += "";
if(!label && !label.length) {
return rect;
} else {
rect.setAttribute('y', 0);
rect.setAttribute('x', 0);
let text = createSVG('text', {
className: 'data-point-value',
x: width/2,
y: 0,
dy: (FONT_SIZE / 2 * -1) + 'px',
'font-size': FONT_SIZE + 'px',
'text-anchor': 'middle',
innerHTML: label
});
let group = createSVG('g', {
'data-point-index': index,
transform: `translate(${x}, ${y})`
});
group.appendChild(rect);
group.appendChild(text);
return group;
}
}
export function datasetDot(x, y, radius, color, label='', index=0) {
let dot = createSVG('circle', {
style: `fill: ${color}`,
'data-point-index': index,
cx: x,
cy: y,
r: radius
});
label += "";
if(!label && !label.length) {
return dot;
} else {
dot.setAttribute('cy', 0);
dot.setAttribute('cx', 0);
let text = createSVG('text', {
className: 'data-point-value',
x: 0,
y: 0,
dy: (FONT_SIZE / 2 * -1 - radius) + 'px',
'font-size': FONT_SIZE + 'px',
'text-anchor': 'middle',
innerHTML: label
});
let group = createSVG('g', {
'data-point-index': index,
transform: `translate(${x}, ${y})`
});
group.appendChild(dot);
group.appendChild(text);
return group;
}
}
export function getPaths(xList, yList, color, options={}, meta={}) {
let pointsList = yList.map((y, i) => (xList[i] + ',' + y));
let pointsStr = pointsList.join("L");
// Spline
if (options.spline)
pointsStr = getSplineCurvePointsStr(xList, yList);
let path = makePath("M"+pointsStr, 'line-graph-path', color);
// HeatLine
if(options.heatline) {
let gradient_id = makeGradient(meta.svgDefs, color);
path.style.stroke = `url(#${gradient_id})`;
}
let paths = {
path: path
};
// Region
if(options.regionFill) {
let gradient_id_region = makeGradient(meta.svgDefs, color, true);
let pathStr = "M" + `${xList[0]},${meta.zeroLine}L` + pointsStr + `L${xList.slice(-1)[0]},${meta.zeroLine}`;
paths.region = makePath(pathStr, `region-fill`, 'none', `url(#${gradient_id_region})`);
}
return paths;
}
export let makeOverlay = {
'bar': (unit) => {
let transformValue;
if(unit.nodeName !== 'rect') {
transformValue = unit.getAttribute('transform');
unit = unit.childNodes[0];
}
let overlay = unit.cloneNode();
overlay.style.fill = '#000000';
overlay.style.opacity = '0.4';
if(transformValue) {
overlay.setAttribute('transform', transformValue);
}
return overlay;
},
'dot': (unit) => {
let transformValue;
if(unit.nodeName !== 'circle') {
transformValue = unit.getAttribute('transform');
unit = unit.childNodes[0];
}
let overlay = unit.cloneNode();
let radius = unit.getAttribute('r');
let fill = unit.getAttribute('fill');
overlay.setAttribute('r', parseInt(radius) + DOT_OVERLAY_SIZE_INCR);
overlay.setAttribute('fill', fill);
overlay.style.opacity = '0.6';
if(transformValue) {
overlay.setAttribute('transform', transformValue);
}
return overlay;
},
'heat_square': (unit) => {
let transformValue;
if(unit.nodeName !== 'circle') {
transformValue = unit.getAttribute('transform');
unit = unit.childNodes[0];
}
let overlay = unit.cloneNode();
let radius = unit.getAttribute('r');
let fill = unit.getAttribute('fill');
overlay.setAttribute('r', parseInt(radius) + DOT_OVERLAY_SIZE_INCR);
overlay.setAttribute('fill', fill);
overlay.style.opacity = '0.6';
if(transformValue) {
overlay.setAttribute('transform', transformValue);
}
return overlay;
}
};
export let updateOverlay = {
'bar': (unit, overlay) => {
let transformValue;
if(unit.nodeName !== 'rect') {
transformValue = unit.getAttribute('transform');
unit = unit.childNodes[0];
}
let attributes = ['x', 'y', 'width', 'height'];
Object.values(unit.attributes)
.filter(attr => attributes.includes(attr.name) && attr.specified)
.map(attr => {
overlay.setAttribute(attr.name, attr.nodeValue);
});
if(transformValue) {
overlay.setAttribute('transform', transformValue);
}
},
'dot': (unit, overlay) => {
let transformValue;
if(unit.nodeName !== 'circle') {
transformValue = unit.getAttribute('transform');
unit = unit.childNodes[0];
}
let attributes = ['cx', 'cy'];
Object.values(unit.attributes)
.filter(attr => attributes.includes(attr.name) && attr.specified)
.map(attr => {
overlay.setAttribute(attr.name, attr.nodeValue);
});
if(transformValue) {
overlay.setAttribute('transform', transformValue);
}
},
'heat_square': (unit, overlay) => {
let transformValue;
if(unit.nodeName !== 'circle') {
transformValue = unit.getAttribute('transform');
unit = unit.childNodes[0];
}
let attributes = ['cx', 'cy'];
Object.values(unit.attributes)
.filter(attr => attributes.includes(attr.name) && attr.specified)
.map(attr => {
overlay.setAttribute(attr.name, attr.nodeValue);
});
if(transformValue) {
overlay.setAttribute('transform', transformValue);
}
},
};

View File

@ -1,33 +0,0 @@
import { $ } from '../utils/dom';
import { CSSTEXT } from '../../css/chartsCss';
export function downloadFile(filename, data) {
var a = document.createElement('a');
a.style = "display: none";
var blob = new Blob(data, {type: "image/svg+xml; charset=utf-8"});
var url = window.URL.createObjectURL(blob);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function(){
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 300);
}
export function prepareForExport(svg) {
let clone = svg.cloneNode(true);
clone.classList.add('chart-container');
clone.setAttribute('xmlns', "http://www.w3.org/2000/svg");
clone.setAttribute('xmlns:xlink', "http://www.w3.org/1999/xlink");
let styleEl = $.create('style', {
'innerHTML': CSSTEXT
});
clone.insertBefore(styleEl, clone.firstChild);
let container = $.create('div');
container.appendChild(clone);
return container.innerHTML;
}

View File

@ -1,143 +0,0 @@
import { ANGLE_RATIO } from './constants';
/**
* Returns the value of a number upto 2 decimal places.
* @param {Number} d Any number
*/
export function floatTwo(d) {
return parseFloat(d.toFixed(2));
}
/**
* Returns whether or not two given arrays are equal.
* @param {Array} arr1 First array
* @param {Array} arr2 Second array
*/
export function arraysEqual(arr1, arr2) {
if(arr1.length !== arr2.length) return false;
let areEqual = true;
arr1.map((d, i) => {
if(arr2[i] !== d) areEqual = false;
});
return areEqual;
}
/**
* Shuffles array in place. ES6 version
* @param {Array} array An array containing the items.
*/
export function shuffle(array) {
// Awesomeness: https://bost.ocks.org/mike/shuffle/
// https://stackoverflow.com/a/2450976/6495043
// https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array?noredirect=1&lq=1
for (let i = array.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
/**
* Fill an array with extra points
* @param {Array} array Array
* @param {Number} count number of filler elements
* @param {Object} element element to fill with
* @param {Boolean} start fill at start?
*/
export function fillArray(array, count, element, start=false) {
if(!element) {
element = start ? array[0] : array[array.length - 1];
}
let fillerArray = new Array(Math.abs(count)).fill(element);
array = start ? fillerArray.concat(array) : array.concat(fillerArray);
return array;
}
/**
* Returns pixel width of string.
* @param {String} string
* @param {Number} charWidth Width of single char in pixels
*/
export function getStringWidth(string, charWidth) {
return (string+"").length * charWidth;
}
export function bindChange(obj, getFn, setFn) {
return new Proxy(obj, {
set: function(target, prop, value) {
setFn();
return Reflect.set(target, prop, value);
},
get: function(target, prop) {
getFn();
return Reflect.get(target, prop);
}
});
}
// https://stackoverflow.com/a/29325222
export function getRandomBias(min, max, bias, influence) {
const range = max - min;
const biasValue = range * bias + min;
var rnd = Math.random() * range + min, // random in range
mix = Math.random() * influence; // random mixer
return rnd * (1 - mix) + biasValue * mix; // mix full range and bias
}
export function getPositionByAngle(angle, radius) {
return {
x: Math.sin(angle * ANGLE_RATIO) * radius,
y: Math.cos(angle * ANGLE_RATIO) * radius,
};
}
/**
* Check if a number is valid for svg attributes
* @param {object} candidate Candidate to test
* @param {Boolean} nonNegative flag to treat negative number as invalid
*/
export function isValidNumber(candidate, nonNegative=false) {
if (Number.isNaN(candidate)) return false;
else if (candidate === undefined) return false;
else if (!Number.isFinite(candidate)) return false;
else if (nonNegative && candidate < 0) return false;
else return true;
}
/**
* Round a number to the closes precision, max max precision 4
* @param {Number} d Any Number
*/
export function round(d) {
// https://floating-point-gui.de/
// https://www.jacklmoore.com/notes/rounding-in-javascript/
return Number(Math.round(d + 'e4') + 'e-4');
}
/**
* Creates a deep clone of an object
* @param {Object} candidate Any Object
*/
export function deepClone(candidate) {
let cloned, value, key;
if (candidate instanceof Date) {
return new Date(candidate.getTime());
}
if (typeof candidate !== "object" || candidate === null) {
return candidate;
}
cloned = Array.isArray(candidate) ? [] : {};
for (key in candidate) {
value = candidate[key];
cloned[key] = deepClone(value);
}
return cloned;
}

View File

@ -1,239 +0,0 @@
import { floatTwo } from './helpers';
function normalize(x) {
// Calculates mantissa and exponent of a number
// Returns normalized number and exponent
// https://stackoverflow.com/q/9383593/6495043
if(x===0) {
return [0, 0];
}
if(isNaN(x)) {
return {mantissa: -6755399441055744, exponent: 972};
}
var sig = x > 0 ? 1 : -1;
if(!isFinite(x)) {
return {mantissa: sig * 4503599627370496, exponent: 972};
}
x = Math.abs(x);
var exp = Math.floor(Math.log10(x));
var man = x/Math.pow(10, exp);
return [sig * man, exp];
}
function getChartRangeIntervals(max, min=0) {
let upperBound = Math.ceil(max);
let lowerBound = Math.floor(min);
let range = upperBound - lowerBound;
let noOfParts = range;
let partSize = 1;
// To avoid too many partitions
if(range > 5) {
if(range % 2 !== 0) {
upperBound++;
// Recalc range
range = upperBound - lowerBound;
}
noOfParts = range/2;
partSize = 2;
}
// Special case: 1 and 2
if(range <= 2) {
noOfParts = 4;
partSize = range/noOfParts;
}
// Special case: 0
if(range === 0) {
noOfParts = 5;
partSize = 1;
}
let intervals = [];
for(var i = 0; i <= noOfParts; i++){
intervals.push(lowerBound + partSize * i);
}
return intervals;
}
function getChartIntervals(maxValue, minValue=0) {
let [normalMaxValue, exponent] = normalize(maxValue);
let normalMinValue = minValue ? minValue/Math.pow(10, exponent): 0;
// Allow only 7 significant digits
normalMaxValue = normalMaxValue.toFixed(6);
let intervals = getChartRangeIntervals(normalMaxValue, normalMinValue);
intervals = intervals.map(value => value * Math.pow(10, exponent));
return intervals;
}
export function calcChartIntervals(values, withMinimum=false) {
//*** Where the magic happens ***
// Calculates best-fit y intervals from given values
// and returns the interval array
let maxValue = Math.max(...values);
let minValue = Math.min(...values);
// Exponent to be used for pretty print
let exponent = 0, intervals = []; // eslint-disable-line no-unused-vars
function getPositiveFirstIntervals(maxValue, absMinValue) {
let intervals = getChartIntervals(maxValue);
let intervalSize = intervals[1] - intervals[0];
// Then unshift the negative values
let value = 0;
for(var i = 1; value < absMinValue; i++) {
value += intervalSize;
intervals.unshift((-1) * value);
}
return intervals;
}
// CASE I: Both non-negative
if(maxValue >= 0 && minValue >= 0) {
exponent = normalize(maxValue)[1];
if(!withMinimum) {
intervals = getChartIntervals(maxValue);
} else {
intervals = getChartIntervals(maxValue, minValue);
}
}
// CASE II: Only minValue negative
else if(maxValue > 0 && minValue < 0) {
// `withMinimum` irrelevant in this case,
// We'll be handling both sides of zero separately
// (both starting from zero)
// Because ceil() and floor() behave differently
// in those two regions
let absMinValue = Math.abs(minValue);
if(maxValue >= absMinValue) {
exponent = normalize(maxValue)[1];
intervals = getPositiveFirstIntervals(maxValue, absMinValue);
} else {
// Mirror: maxValue => absMinValue, then change sign
exponent = normalize(absMinValue)[1];
let posIntervals = getPositiveFirstIntervals(absMinValue, maxValue);
intervals = posIntervals.reverse().map(d => d * (-1));
}
}
// CASE III: Both non-positive
else if(maxValue <= 0 && minValue <= 0) {
// Mirrored Case I:
// Work with positives, then reverse the sign and array
let pseudoMaxValue = Math.abs(minValue);
let pseudoMinValue = Math.abs(maxValue);
exponent = normalize(pseudoMaxValue)[1];
if(!withMinimum) {
intervals = getChartIntervals(pseudoMaxValue);
} else {
intervals = getChartIntervals(pseudoMaxValue, pseudoMinValue);
}
intervals = intervals.reverse().map(d => d * (-1));
}
return intervals;
}
export function getZeroIndex(yPts) {
let zeroIndex;
let interval = getIntervalSize(yPts);
if(yPts.indexOf(0) >= 0) {
// the range has a given zero
// zero-line on the chart
zeroIndex = yPts.indexOf(0);
} else if(yPts[0] > 0) {
// Minimum value is positive
// zero-line is off the chart: below
let min = yPts[0];
zeroIndex = (-1) * min / interval;
} else {
// Maximum value is negative
// zero-line is off the chart: above
let max = yPts[yPts.length - 1];
zeroIndex = (-1) * max / interval + (yPts.length - 1);
}
return zeroIndex;
}
export function getRealIntervals(max, noOfIntervals, min = 0, asc = 1) {
let range = max - min;
let part = range * 1.0 / noOfIntervals;
let intervals = [];
for(var i = 0; i <= noOfIntervals; i++) {
intervals.push(min + part * i);
}
return asc ? intervals : intervals.reverse();
}
export function getIntervalSize(orderedArray) {
return orderedArray[1] - orderedArray[0];
}
export function getValueRange(orderedArray) {
return orderedArray[orderedArray.length-1] - orderedArray[0];
}
export function scale(val, yAxis) {
return floatTwo(yAxis.zeroLine - val * yAxis.scaleMultiplier);
}
export function isInRange(val, min, max) {
return val > min && val < max;
}
export function isInRange2D(coord, minCoord, maxCoord) {
return isInRange(coord[0], minCoord[0], maxCoord[0])
&& isInRange(coord[1], minCoord[1], maxCoord[1]);
}
export function getClosestInArray(goal, arr, index = false) {
let closest = arr.reduce(function(prev, curr) {
return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
}, []);
return index ? arr.indexOf(closest) : closest;
}
export function calcDistribution(values, distributionSize) {
// Assume non-negative values,
// implying distribution minimum at zero
let dataMaxValue = Math.max(...values);
let distributionStep = 1 / (distributionSize - 1);
let distribution = [];
for(var i = 0; i < distributionSize; i++) {
let checkpoint = dataMaxValue * (distributionStep * i);
distribution.push(checkpoint);
}
return distribution;
}
export function getMaxCheckpoint(value, distribution) {
return distribution.filter(d => d < value).length;
}

View File

@ -1,14 +0,0 @@
const assert = require('assert');
const colors = require('../colors');
describe('utils.colors', () => {
it('should return #aaabac for RGB()', () => {
assert.equal(colors.getColor('rgb(170, 171, 172)'), '#aaabac');
});
it('should return #ff5858 for the named color red', () => {
assert.equal(colors.getColor('red'), '#ff5858d');
});
it('should return #1a5c29 for the hex color #1a5c29', () => {
assert.equal(colors.getColor('#1a5c29'), '#1a5c29');
});
});

View File

@ -1,10 +0,0 @@
const assert = require('assert');
const helpers = require('../helpers');
describe('utils.helpers', () => {
it('should return a value fixed upto 2 decimals', () => {
assert.equal(helpers.floatTwo(1.234), 1.23);
assert.equal(helpers.floatTwo(1.456), 1.46);
assert.equal(helpers.floatTwo(1), 1.00);
});
});

View File

@ -1,20 +0,0 @@
root = true
[*]
indent_style = tab
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 120
[CHANGELOG.md]
indent_style = space
indent_size = 2
[*.json]
max_line_length = off
[Makefile]
max_line_length = off

15
node_modules/function-bind/.eslintrc generated vendored
View File

@ -1,15 +0,0 @@
{
"root": true,
"extends": "@ljharb",
"rules": {
"func-name-matching": 0,
"indent": [2, 4],
"max-nested-callbacks": [2, 3],
"max-params": [2, 3],
"max-statements": [2, 20],
"no-new-func": [1],
"strict": [0]
}
}

176
node_modules/function-bind/.jscs.json generated vendored
View File

@ -1,176 +0,0 @@
{
"es3": true,
"additionalRules": [],
"requireSemicolons": true,
"disallowMultipleSpaces": true,
"disallowIdentifierNames": [],
"requireCurlyBraces": {
"allExcept": [],
"keywords": ["if", "else", "for", "while", "do", "try", "catch"]
},
"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch", "function"],
"disallowSpaceAfterKeywords": [],
"disallowSpaceBeforeComma": true,
"disallowSpaceAfterComma": false,
"disallowSpaceBeforeSemicolon": true,
"disallowNodeTypes": [
"DebuggerStatement",
"ForInStatement",
"LabeledStatement",
"SwitchCase",
"SwitchStatement",
"WithStatement"
],
"requireObjectKeysOnNewLine": { "allExcept": ["sameLine"] },
"requireSpacesInAnonymousFunctionExpression": { "beforeOpeningRoundBrace": true, "beforeOpeningCurlyBrace": true },
"requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true },
"disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true },
"requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true },
"disallowSpacesInFunctionDeclaration": { "beforeOpeningRoundBrace": true },
"requireSpaceBetweenArguments": true,
"disallowSpacesInsideParentheses": true,
"disallowSpacesInsideArrayBrackets": true,
"disallowQuotedKeysInObjects": { "allExcept": ["reserved"] },
"disallowSpaceAfterObjectKeys": true,
"requireCommaBeforeLineBreak": true,
"disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
"requireSpaceAfterPrefixUnaryOperators": [],
"disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
"requireSpaceBeforePostfixUnaryOperators": [],
"disallowSpaceBeforeBinaryOperators": [],
"requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
"requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
"disallowSpaceAfterBinaryOperators": [],
"disallowImplicitTypeConversion": ["binary", "string"],
"disallowKeywords": ["with", "eval"],
"requireKeywordsOnNewLine": [],
"disallowKeywordsOnNewLine": ["else"],
"requireLineFeedAtFileEnd": true,
"disallowTrailingWhitespace": true,
"disallowTrailingComma": true,
"excludeFiles": ["node_modules/**", "vendor/**"],
"disallowMultipleLineStrings": true,
"requireDotNotation": { "allExcept": ["keywords"] },
"requireParenthesesAroundIIFE": true,
"validateLineBreaks": "LF",
"validateQuoteMarks": {
"escape": true,
"mark": "'"
},
"disallowOperatorBeforeLineBreak": [],
"requireSpaceBeforeKeywords": [
"do",
"for",
"if",
"else",
"switch",
"case",
"try",
"catch",
"finally",
"while",
"with",
"return"
],
"validateAlignedFunctionParameters": {
"lineBreakAfterOpeningBraces": true,
"lineBreakBeforeClosingBraces": true
},
"requirePaddingNewLinesBeforeExport": true,
"validateNewlineAfterArrayElements": {
"maximum": 8
},
"requirePaddingNewLinesAfterUseStrict": true,
"disallowArrowFunctions": true,
"disallowMultiLineTernary": true,
"validateOrderInObjectKeys": "asc-insensitive",
"disallowIdenticalDestructuringNames": true,
"disallowNestedTernaries": { "maxLevel": 1 },
"requireSpaceAfterComma": { "allExcept": ["trailing"] },
"requireAlignedMultilineParams": false,
"requireSpacesInGenerator": {
"afterStar": true
},
"disallowSpacesInGenerator": {
"beforeStar": true
},
"disallowVar": false,
"requireArrayDestructuring": false,
"requireEnhancedObjectLiterals": false,
"requireObjectDestructuring": false,
"requireEarlyReturn": false,
"requireCapitalizedConstructorsNew": {
"allExcept": ["Function", "String", "Object", "Symbol", "Number", "Date", "RegExp", "Error", "Boolean", "Array"]
},
"requireImportAlphabetized": false,
"requireSpaceBeforeObjectValues": true,
"requireSpaceBeforeDestructuredValues": true,
"disallowSpacesInsideTemplateStringPlaceholders": true,
"disallowArrayDestructuringReturn": false,
"requireNewlineBeforeSingleStatementsInIf": false,
"disallowUnusedVariables": true,
"requireSpacesInsideImportedObjectBraces": true,
"requireUseStrict": true
}

View File

@ -1,22 +0,0 @@
# gitignore
.DS_Store
.monitor
.*.swp
.nodemonignore
releases
*.log
*.err
fleet.json
public/browserify
bin/*.json
.bin
build
compile
.lock-wscript
coverage
node_modules
# Only apps should have lockfiles
npm-shrinkwrap.json
package-lock.json
yarn.lock

View File

@ -1,168 +0,0 @@
language: node_js
os:
- linux
node_js:
- "8.4"
- "7.10"
- "6.11"
- "5.12"
- "4.8"
- "iojs-v3.3"
- "iojs-v2.5"
- "iojs-v1.8"
- "0.12"
- "0.10"
- "0.8"
before_install:
- 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ]; then npm install -g npm@1.3 ; elif [ "${TRAVIS_NODE_VERSION}" != "0.9" ]; then case "$(npm --version)" in 1.*) npm install -g npm@1.4.28 ;; 2.*) npm install -g npm@2 ;; esac ; fi'
- 'if [ "${TRAVIS_NODE_VERSION}" != "0.6" ] && [ "${TRAVIS_NODE_VERSION}" != "0.9" ]; then if [ "${TRAVIS_NODE_VERSION%${TRAVIS_NODE_VERSION#[0-9]}}" = "0" ] || [ "${TRAVIS_NODE_VERSION:0:4}" = "iojs" ]; then npm install -g npm@4.5 ; else npm install -g npm; fi; fi'
install:
- 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ]; then nvm install 0.8 && npm install -g npm@1.3 && npm install -g npm@1.4.28 && npm install -g npm@2 && npm install && nvm use "${TRAVIS_NODE_VERSION}"; else npm install; fi;'
script:
- 'if [ -n "${PRETEST-}" ]; then npm run pretest ; fi'
- 'if [ -n "${POSTTEST-}" ]; then npm run posttest ; fi'
- 'if [ -n "${COVERAGE-}" ]; then npm run coverage ; fi'
- 'if [ -n "${TEST-}" ]; then npm run tests-only ; fi'
sudo: false
env:
- TEST=true
matrix:
fast_finish: true
include:
- node_js: "node"
env: PRETEST=true
- node_js: "4"
env: COVERAGE=true
- node_js: "8.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.9"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.8"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.10"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.9"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.8"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.11"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.10"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.9"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.8"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v3.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v3.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v3.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "0.11"
env: TEST=true ALLOW_FAILURE=true
- node_js: "0.9"
env: TEST=true ALLOW_FAILURE=true
- node_js: "0.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "0.4"
env: TEST=true ALLOW_FAILURE=true
allow_failures:
- os: osx
- env: TEST=true ALLOW_FAILURE=true

20
node_modules/function-bind/LICENSE generated vendored
View File

@ -1,20 +0,0 @@
Copyright (c) 2013 Raynos.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

48
node_modules/function-bind/README.md generated vendored
View File

@ -1,48 +0,0 @@
# function-bind
<!--
[![build status][travis-svg]][travis-url]
[![NPM version][npm-badge-svg]][npm-url]
[![Coverage Status][5]][6]
[![gemnasium Dependency Status][7]][8]
[![Dependency status][deps-svg]][deps-url]
[![Dev Dependency status][dev-deps-svg]][dev-deps-url]
-->
<!-- [![browser support][11]][12] -->
Implementation of function.prototype.bind
## Example
I mainly do this for unit tests I run on phantomjs.
PhantomJS does not have Function.prototype.bind :(
```js
Function.prototype.bind = require("function-bind")
```
## Installation
`npm install function-bind`
## Contributors
- Raynos
## MIT Licenced
[travis-svg]: https://travis-ci.org/Raynos/function-bind.svg
[travis-url]: https://travis-ci.org/Raynos/function-bind
[npm-badge-svg]: https://badge.fury.io/js/function-bind.svg
[npm-url]: https://npmjs.org/package/function-bind
[5]: https://coveralls.io/repos/Raynos/function-bind/badge.png
[6]: https://coveralls.io/r/Raynos/function-bind
[7]: https://gemnasium.com/Raynos/function-bind.png
[8]: https://gemnasium.com/Raynos/function-bind
[deps-svg]: https://david-dm.org/Raynos/function-bind.svg
[deps-url]: https://david-dm.org/Raynos/function-bind
[dev-deps-svg]: https://david-dm.org/Raynos/function-bind/dev-status.svg
[dev-deps-url]: https://david-dm.org/Raynos/function-bind#info=devDependencies
[11]: https://ci.testling.com/Raynos/function-bind.png
[12]: https://ci.testling.com/Raynos/function-bind

View File

@ -1,52 +0,0 @@
'use strict';
/* eslint no-invalid-this: 1 */
var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
var slice = Array.prototype.slice;
var toStr = Object.prototype.toString;
var funcType = '[object Function]';
module.exports = function bind(that) {
var target = this;
if (typeof target !== 'function' || toStr.call(target) !== funcType) {
throw new TypeError(ERROR_MESSAGE + target);
}
var args = slice.call(arguments, 1);
var bound;
var binder = function () {
if (this instanceof bound) {
var result = target.apply(
this,
args.concat(slice.call(arguments))
);
if (Object(result) === result) {
return result;
}
return this;
} else {
return target.apply(
that,
args.concat(slice.call(arguments))
);
}
};
var boundLength = Math.max(0, target.length - args.length);
var boundArgs = [];
for (var i = 0; i < boundLength; i++) {
boundArgs.push('$' + i);
}
bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);
if (target.prototype) {
var Empty = function Empty() {};
Empty.prototype = target.prototype;
bound.prototype = new Empty();
Empty.prototype = null;
}
return bound;
};

View File

@ -1,5 +0,0 @@
'use strict';
var implementation = require('./implementation');
module.exports = Function.prototype.bind || implementation;

View File

@ -1,63 +0,0 @@
{
"name": "function-bind",
"version": "1.1.1",
"description": "Implementation of Function.prototype.bind",
"keywords": [
"function",
"bind",
"shim",
"es5"
],
"author": "Raynos <raynos2@gmail.com>",
"repository": "git://github.com/Raynos/function-bind.git",
"main": "index",
"homepage": "https://github.com/Raynos/function-bind",
"contributors": [
{
"name": "Raynos"
},
{
"name": "Jordan Harband",
"url": "https://github.com/ljharb"
}
],
"bugs": {
"url": "https://github.com/Raynos/function-bind/issues",
"email": "raynos2@gmail.com"
},
"dependencies": {},
"devDependencies": {
"@ljharb/eslint-config": "^12.2.1",
"covert": "^1.1.0",
"eslint": "^4.5.0",
"jscs": "^3.0.7",
"tape": "^4.8.0"
},
"license": "MIT",
"scripts": {
"pretest": "npm run lint",
"test": "npm run tests-only",
"posttest": "npm run coverage -- --quiet",
"tests-only": "node test",
"coverage": "covert test/*.js",
"lint": "npm run jscs && npm run eslint",
"jscs": "jscs *.js */*.js",
"eslint": "eslint *.js */*.js"
},
"testling": {
"files": "test/index.js",
"browsers": [
"ie/8..latest",
"firefox/16..latest",
"firefox/nightly",
"chrome/22..latest",
"chrome/canary",
"opera/12..latest",
"opera/next",
"safari/5.1..latest",
"ipad/6.0..latest",
"iphone/6.0..latest",
"android-browser/4.2..latest"
]
}
}

View File

@ -1,9 +0,0 @@
{
"rules": {
"array-bracket-newline": 0,
"array-element-newline": 0,
"max-statements-per-line": [2, { "max": 2 }],
"no-invalid-this": 0,
"no-magic-numbers": 0,
}
}

View File

@ -1,252 +0,0 @@
// jscs:disable requireUseStrict
var test = require('tape');
var functionBind = require('../implementation');
var getCurrentContext = function () { return this; };
test('functionBind is a function', function (t) {
t.equal(typeof functionBind, 'function');
t.end();
});
test('non-functions', function (t) {
var nonFunctions = [true, false, [], {}, 42, 'foo', NaN, /a/g];
t.plan(nonFunctions.length);
for (var i = 0; i < nonFunctions.length; ++i) {
try { functionBind.call(nonFunctions[i]); } catch (ex) {
t.ok(ex instanceof TypeError, 'throws when given ' + String(nonFunctions[i]));
}
}
t.end();
});
test('without a context', function (t) {
t.test('binds properly', function (st) {
var args, context;
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
context = this;
})
};
namespace.func(1, 2, 3);
st.deepEqual(args, [1, 2, 3]);
st.equal(context, getCurrentContext.call());
st.end();
});
t.test('binds properly, and still supplies bound arguments', function (st) {
var args, context;
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
context = this;
}, undefined, 1, 2, 3)
};
namespace.func(4, 5, 6);
st.deepEqual(args, [1, 2, 3, 4, 5, 6]);
st.equal(context, getCurrentContext.call());
st.end();
});
t.test('returns properly', function (st) {
var args;
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
return this;
}, null)
};
var context = namespace.func(1, 2, 3);
st.equal(context, getCurrentContext.call(), 'returned context is namespaced context');
st.deepEqual(args, [1, 2, 3], 'passed arguments are correct');
st.end();
});
t.test('returns properly with bound arguments', function (st) {
var args;
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
return this;
}, null, 1, 2, 3)
};
var context = namespace.func(4, 5, 6);
st.equal(context, getCurrentContext.call(), 'returned context is namespaced context');
st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'passed arguments are correct');
st.end();
});
t.test('called as a constructor', function (st) {
var thunkify = function (value) {
return function () { return value; };
};
st.test('returns object value', function (sst) {
var expectedReturnValue = [1, 2, 3];
var Constructor = functionBind.call(thunkify(expectedReturnValue), null);
var result = new Constructor();
sst.equal(result, expectedReturnValue);
sst.end();
});
st.test('does not return primitive value', function (sst) {
var Constructor = functionBind.call(thunkify(42), null);
var result = new Constructor();
sst.notEqual(result, 42);
sst.end();
});
st.test('object from bound constructor is instance of original and bound constructor', function (sst) {
var A = function (x) {
this.name = x || 'A';
};
var B = functionBind.call(A, null, 'B');
var result = new B();
sst.ok(result instanceof B, 'result is instance of bound constructor');
sst.ok(result instanceof A, 'result is instance of original constructor');
sst.end();
});
st.end();
});
t.end();
});
test('with a context', function (t) {
t.test('with no bound arguments', function (st) {
var args, context;
var boundContext = {};
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
context = this;
}, boundContext)
};
namespace.func(1, 2, 3);
st.equal(context, boundContext, 'binds a context properly');
st.deepEqual(args, [1, 2, 3], 'supplies passed arguments');
st.end();
});
t.test('with bound arguments', function (st) {
var args, context;
var boundContext = {};
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
context = this;
}, boundContext, 1, 2, 3)
};
namespace.func(4, 5, 6);
st.equal(context, boundContext, 'binds a context properly');
st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'supplies bound and passed arguments');
st.end();
});
t.test('returns properly', function (st) {
var boundContext = {};
var args;
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
return this;
}, boundContext)
};
var context = namespace.func(1, 2, 3);
st.equal(context, boundContext, 'returned context is bound context');
st.notEqual(context, getCurrentContext.call(), 'returned context is not lexical context');
st.deepEqual(args, [1, 2, 3], 'passed arguments are correct');
st.end();
});
t.test('returns properly with bound arguments', function (st) {
var boundContext = {};
var args;
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
return this;
}, boundContext, 1, 2, 3)
};
var context = namespace.func(4, 5, 6);
st.equal(context, boundContext, 'returned context is bound context');
st.notEqual(context, getCurrentContext.call(), 'returned context is not lexical context');
st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'passed arguments are correct');
st.end();
});
t.test('passes the correct arguments when called as a constructor', function (st) {
var expected = { name: 'Correct' };
var namespace = {
Func: functionBind.call(function (arg) {
return arg;
}, { name: 'Incorrect' })
};
var returned = new namespace.Func(expected);
st.equal(returned, expected, 'returns the right arg when called as a constructor');
st.end();
});
t.test('has the new instance\'s context when called as a constructor', function (st) {
var actualContext;
var expectedContext = { foo: 'bar' };
var namespace = {
Func: functionBind.call(function () {
actualContext = this;
}, expectedContext)
};
var result = new namespace.Func();
st.equal(result instanceof namespace.Func, true);
st.notEqual(actualContext, expectedContext);
st.end();
});
t.end();
});
test('bound function length', function (t) {
t.test('sets a correct length without thisArg', function (st) {
var subject = functionBind.call(function (a, b, c) { return a + b + c; });
st.equal(subject.length, 3);
st.equal(subject(1, 2, 3), 6);
st.end();
});
t.test('sets a correct length with thisArg', function (st) {
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {});
st.equal(subject.length, 3);
st.equal(subject(1, 2, 3), 6);
st.end();
});
t.test('sets a correct length without thisArg and first argument', function (st) {
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, undefined, 1);
st.equal(subject.length, 2);
st.equal(subject(2, 3), 6);
st.end();
});
t.test('sets a correct length with thisArg and first argument', function (st) {
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}, 1);
st.equal(subject.length, 2);
st.equal(subject(2, 3), 6);
st.end();
});
t.test('sets a correct length without thisArg and too many arguments', function (st) {
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, undefined, 1, 2, 3, 4);
st.equal(subject.length, 0);
st.equal(subject(), 6);
st.end();
});
t.test('sets a correct length with thisArg and too many arguments', function (st) {
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}, 1, 2, 3, 4);
st.equal(subject.length, 0);
st.equal(subject(), 6);
st.end();
});
});

22
node_modules/has/LICENSE-MIT generated vendored
View File

@ -1,22 +0,0 @@
Copyright (c) 2013 Thiago de Arruda
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

18
node_modules/has/README.md generated vendored
View File

@ -1,18 +0,0 @@
# has
> Object.prototype.hasOwnProperty.call shortcut
## Installation
```sh
npm install --save has
```
## Usage
```js
var has = require('has');
has({}, 'hasOwnProperty'); // false
has(Object.prototype, 'hasOwnProperty'); // true
```

48
node_modules/has/package.json generated vendored
View File

@ -1,48 +0,0 @@
{
"name": "has",
"description": "Object.prototype.hasOwnProperty.call shortcut",
"version": "1.0.3",
"homepage": "https://github.com/tarruda/has",
"author": {
"name": "Thiago de Arruda",
"email": "tpadilha84@gmail.com"
},
"contributors": [
{
"name": "Jordan Harband",
"email": "ljharb@gmail.com",
"url": "http://ljharb.codes"
}
],
"repository": {
"type": "git",
"url": "git://github.com/tarruda/has.git"
},
"bugs": {
"url": "https://github.com/tarruda/has/issues"
},
"license": "MIT",
"licenses": [
{
"type": "MIT",
"url": "https://github.com/tarruda/has/blob/master/LICENSE-MIT"
}
],
"main": "./src",
"dependencies": {
"function-bind": "^1.1.1"
},
"devDependencies": {
"@ljharb/eslint-config": "^12.2.1",
"eslint": "^4.19.1",
"tape": "^4.9.0"
},
"engines": {
"node": ">= 0.4.0"
},
"scripts": {
"lint": "eslint .",
"pretest": "npm run lint",
"test": "tape test"
}
}

5
node_modules/has/src/index.js generated vendored
View File

@ -1,5 +0,0 @@
'use strict';
var bind = require('function-bind');
module.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);

10
node_modules/has/test/index.js generated vendored
View File

@ -1,10 +0,0 @@
'use strict';
var test = require('tape');
var has = require('../');
test('has', function (t) {
t.equal(has({}, 'hasOwnProperty'), false, 'object literal does not have own property "hasOwnProperty"');
t.equal(has(Object.prototype, 'hasOwnProperty'), true, 'Object.prototype has own property "hasOwnProperty"');
t.end();
});

View File

@ -1 +0,0 @@
coverage/

View File

@ -1,18 +0,0 @@
{
"extends": "@ljharb",
"root": true,
"rules": {
"func-style": 1,
"operator-linebreak": [2, "before"],
},
"overrides": [
{
"files": "test/**",
"rules": {
"global-require": 0,
"max-lines-per-function": 0,
"no-negated-condition": 0,
},
},
],
}

9
node_modules/is-core-module/.nycrc generated vendored
View File

@ -1,9 +0,0 @@
{
"all": true,
"check-coverage": false,
"reporter": ["text-summary", "text", "html", "json"],
"exclude": [
"coverage",
"test"
]
}

View File

@ -1,117 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v2.8.0](https://github.com/inspect-js/is-core-module/compare/v2.7.0...v2.8.0) - 2021-10-14
### Commits
- [actions] update codecov uploader [`0cfe94e`](https://github.com/inspect-js/is-core-module/commit/0cfe94e106a7d005ea03e008c0a21dec13a77904)
- [New] add `readline/promises` to node v17+ [`4f78c30`](https://github.com/inspect-js/is-core-module/commit/4f78c3008b1b58b4db6dc91d99610b1bc859da7e)
- [Tests] node ^14.18 supports `node:` prefixes for CJS [`43e2f17`](https://github.com/inspect-js/is-core-module/commit/43e2f177452cea2f0eaf34f61b5407217bbdb6f4)
## [v2.7.0](https://github.com/inspect-js/is-core-module/compare/v2.6.0...v2.7.0) - 2021-09-27
### Commits
- [New] node `v14.18` added `node:`-prefixed core modules to `require` [`6d943ab`](https://github.com/inspect-js/is-core-module/commit/6d943abe81382b9bbe344384d80fbfebe1cc0526)
- [Tests] add coverage for Object.prototype pollution [`c6baf5f`](https://github.com/inspect-js/is-core-module/commit/c6baf5f942311a1945c1af41167bb80b84df2af7)
- [Dev Deps] update `@ljharb/eslint-config` [`6717f00`](https://github.com/inspect-js/is-core-module/commit/6717f000d063ea57beb772bded36c2f056ac404c)
- [eslint] fix linter warning [`594c10b`](https://github.com/inspect-js/is-core-module/commit/594c10bb7d39d7eb00925c90924199ff596184b2)
- [meta] add `sideEffects` flag [`c32cfa5`](https://github.com/inspect-js/is-core-module/commit/c32cfa5195632944c4dd4284a142b8476e75be13)
## [v2.6.0](https://github.com/inspect-js/is-core-module/compare/v2.5.0...v2.6.0) - 2021-08-17
### Commits
- [Dev Deps] update `eslint`, `tape` [`6cc928f`](https://github.com/inspect-js/is-core-module/commit/6cc928f8a4bba66aeeccc4f6beeac736d4bd3081)
- [New] add `stream/consumers` to node `&gt;= 16.7` [`a1a423e`](https://github.com/inspect-js/is-core-module/commit/a1a423e467e4cc27df180234fad5bab45943e67d)
- [Refactor] Remove duplicated `&&` operand [`86faea7`](https://github.com/inspect-js/is-core-module/commit/86faea738213a2433c62d1098488dc9314dca832)
- [Tests] include prereleases [`a4da7a6`](https://github.com/inspect-js/is-core-module/commit/a4da7a6abf7568e2aa4fd98e69452179f1850963)
## [v2.5.0](https://github.com/inspect-js/is-core-module/compare/v2.4.0...v2.5.0) - 2021-07-12
### Commits
- [Dev Deps] update `auto-changelog`, `eslint` [`6334cc9`](https://github.com/inspect-js/is-core-module/commit/6334cc94f3af7469685bd8f236740991baaf2705)
- [New] add `stream/web` to node v16.5+ [`17ac59b`](https://github.com/inspect-js/is-core-module/commit/17ac59b662d63e220a2e5728625f005c24f177b2)
## [v2.4.0](https://github.com/inspect-js/is-core-module/compare/v2.3.0...v2.4.0) - 2021-05-09
### Commits
- [readme] add actions and codecov badges [`82b7faa`](https://github.com/inspect-js/is-core-module/commit/82b7faa12b56dbe47fbea67e1a5b9e447027ba40)
- [Dev Deps] update `@ljharb/eslint-config`, `aud` [`8096868`](https://github.com/inspect-js/is-core-module/commit/8096868c024a161ccd4d44110b136763e92eace8)
- [Dev Deps] update `eslint` [`6726824`](https://github.com/inspect-js/is-core-module/commit/67268249b88230018c510f6532a8046d7326346f)
- [New] add `diagnostics_channel` to node `^14.17` [`86c6563`](https://github.com/inspect-js/is-core-module/commit/86c65634201b8ff9b3e48a9a782594579c7f5c3c)
- [meta] fix prepublish script [`697a01e`](https://github.com/inspect-js/is-core-module/commit/697a01e3c9c0be074066520954f30fb28532ec57)
## [v2.3.0](https://github.com/inspect-js/is-core-module/compare/v2.2.0...v2.3.0) - 2021-04-24
### Commits
- [meta] do not publish github action workflow files [`060d4bb`](https://github.com/inspect-js/is-core-module/commit/060d4bb971a29451c19ff336eb56bee27f9fa95a)
- [New] add support for `node:` prefix, in node 16+ [`7341223`](https://github.com/inspect-js/is-core-module/commit/73412230a769f6e81c05eea50b6520cebf54ed2f)
- [actions] use `node/install` instead of `node/run`; use `codecov` action [`016269a`](https://github.com/inspect-js/is-core-module/commit/016269abae9f6657a5254adfbb813f09a05067f9)
- [patch] remove unneeded `.0` in version ranges [`cb466a6`](https://github.com/inspect-js/is-core-module/commit/cb466a6d89e52b8389e5c12715efcd550c41cea3)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `tape` [`c9f9c39`](https://github.com/inspect-js/is-core-module/commit/c9f9c396ace60ef81906f98059c064e6452473ed)
- [actions] update workflows [`3ee4a89`](https://github.com/inspect-js/is-core-module/commit/3ee4a89fd5a02fccd43882d905448ea6a98e9a3c)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config` [`dee4fed`](https://github.com/inspect-js/is-core-module/commit/dee4fed79690c1d43a22f7fa9426abebdc6d727f)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config` [`7d046ba`](https://github.com/inspect-js/is-core-module/commit/7d046ba07ae8c9292e43652694ca808d7b309de8)
- [meta] use `prepublishOnly` script for npm 7+ [`149e677`](https://github.com/inspect-js/is-core-module/commit/149e6771a5ede6d097e71785b467a9c4b4977cc7)
- [readme] remove travis badge [`903b51d`](https://github.com/inspect-js/is-core-module/commit/903b51d6b69b98abeabfbc3695c345b02646f19c)
## [v2.2.0](https://github.com/inspect-js/is-core-module/compare/v2.1.0...v2.2.0) - 2020-11-26
### Commits
- [Tests] migrate tests to Github Actions [`c919f57`](https://github.com/inspect-js/is-core-module/commit/c919f573c0a92d10a0acad0b650b5aecb033d426)
- [patch] `core.json`: %s/ /\t/g [`db3f685`](https://github.com/inspect-js/is-core-module/commit/db3f68581f53e73cc09cd675955eb1bdd6a5a39b)
- [Tests] run `nyc` on all tests [`b2f925f`](https://github.com/inspect-js/is-core-module/commit/b2f925f8866f210ef441f39fcc8cc42692ab89b1)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`; add `safe-publish-latest` [`89f02a2`](https://github.com/inspect-js/is-core-module/commit/89f02a2b4162246dea303a6ee31bb9a550b05c72)
- [New] add `path/posix`, `path/win32`, `util/types` [`77f94f1`](https://github.com/inspect-js/is-core-module/commit/77f94f1e90ffd7c0be2a3f1aa8574ebf7fd981b3)
## [v2.1.0](https://github.com/inspect-js/is-core-module/compare/v2.0.0...v2.1.0) - 2020-11-04
### Commits
- [Dev Deps] update `eslint` [`5e0034e`](https://github.com/inspect-js/is-core-module/commit/5e0034eae57c09c8f1bd769f502486a00f56c6e4)
- [New] Add `diagnostics_channel` [`c2d83d0`](https://github.com/inspect-js/is-core-module/commit/c2d83d0a0225a1a658945d9bab7036ea347d29ec)
## [v2.0.0](https://github.com/inspect-js/is-core-module/compare/v1.0.2...v2.0.0) - 2020-09-29
### Commits
- v2 implementation [`865aeb5`](https://github.com/inspect-js/is-core-module/commit/865aeb5ca0e90248a3dfff5d7622e4751fdeb9cd)
- Only apps should have lockfiles [`5a5e660`](https://github.com/inspect-js/is-core-module/commit/5a5e660d568e37eb44e17fb1ebb12a105205fc2b)
- Initial commit for v2 [`5a51524`](https://github.com/inspect-js/is-core-module/commit/5a51524e06f92adece5fbb138c69b7b9748a2348)
- Tests [`116eae4`](https://github.com/inspect-js/is-core-module/commit/116eae4fccd01bc72c1fd3cc4b7561c387afc496)
- [meta] add `auto-changelog` [`c24388b`](https://github.com/inspect-js/is-core-module/commit/c24388bee828d223040519d1f5b226ca35beee63)
- [actions] add "Automatic Rebase" and "require allow edits" actions [`34292db`](https://github.com/inspect-js/is-core-module/commit/34292dbcbadae0868aff03c22dbd8b7b8a11558a)
- [Tests] add `npm run lint` [`4f9eeee`](https://github.com/inspect-js/is-core-module/commit/4f9eeee7ddff10698bbf528620f4dc8d4fa3e697)
- [readme] fix travis badges, https all URLs [`e516a73`](https://github.com/inspect-js/is-core-module/commit/e516a73b0dccce20938c432b1ba512eae8eff9e9)
- [meta] create FUNDING.yml [`1aabebc`](https://github.com/inspect-js/is-core-module/commit/1aabebca98d01f8a04e46bc2e2520fa93cf21ac6)
- [Fix] `domain`: domain landed sometime &gt; v0.7.7 and &lt;= v0.7.12 [`2df7d37`](https://github.com/inspect-js/is-core-module/commit/2df7d37595d41b15eeada732b706b926c2771655)
- [Fix] `sys`: worked in 0.6, not 0.7, and 0.8+ [`a75c134`](https://github.com/inspect-js/is-core-module/commit/a75c134229e1e9441801f6b73f6a52489346eb65)
## [v1.0.2](https://github.com/inspect-js/is-core-module/compare/v1.0.1...v1.0.2) - 2014-09-28
### Commits
- simpler [`66fe90f`](https://github.com/inspect-js/is-core-module/commit/66fe90f9771581b9adc0c3900baa52c21b5baea2)
## [v1.0.1](https://github.com/inspect-js/is-core-module/compare/v1.0.0...v1.0.1) - 2014-09-28
### Commits
- remove stupid [`f21f906`](https://github.com/inspect-js/is-core-module/commit/f21f906f882c2bd656a5fc5ed6fbe48ddaffb2ac)
- update readme [`1eff0ec`](https://github.com/inspect-js/is-core-module/commit/1eff0ec69798d1ec65771552d1562911e90a8027)
## v1.0.0 - 2014-09-28
### Commits
- init [`48e5e76`](https://github.com/inspect-js/is-core-module/commit/48e5e76cac378fddb8c1f7d4055b8dfc943d6b96)

20
node_modules/is-core-module/LICENSE generated vendored
View File

@ -1,20 +0,0 @@
The MIT License (MIT)
Copyright (c) 2014 Dave Justice
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,40 +0,0 @@
# is-core-module <sup>[![Version Badge][2]][1]</sup>
[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![dependency status][5]][6]
[![dev dependency status][7]][8]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]
[![npm badge][11]][1]
Is this specifier a node.js core module? Optionally provide a node version to check; defaults to the current node version.
## Example
```js
var isCore = require('is-core-module');
var assert = require('assert');
assert(isCore('fs'));
assert(!isCore('butts'));
```
## Tests
Clone the repo, `npm install`, and run `npm test`
[1]: https://npmjs.org/package/is-core-module
[2]: https://versionbadg.es/inspect-js/is-core-module.svg
[5]: https://david-dm.org/inspect-js/is-core-module.svg
[6]: https://david-dm.org/inspect-js/is-core-module
[7]: https://david-dm.org/inspect-js/is-core-module/dev-status.svg
[8]: https://david-dm.org/inspect-js/is-core-module#info=devDependencies
[11]: https://nodei.co/npm/is-core-module.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/is-core-module.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/is-core-module.svg
[downloads-url]: https://npm-stat.com/charts.html?package=is-core-module
[codecov-image]: https://codecov.io/gh/inspect-js/is-core-module/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/inspect-js/is-core-module/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/inspect-js/is-core-module
[actions-url]: https://github.com/inspect-js/is-core-module/actions

152
node_modules/is-core-module/core.json generated vendored
View File

@ -1,152 +0,0 @@
{
"assert": true,
"node:assert": [">= 14.18 && < 15", ">= 16"],
"assert/strict": ">= 15",
"node:assert/strict": ">= 16",
"async_hooks": ">= 8",
"node:async_hooks": [">= 14.18 && < 15", ">= 16"],
"buffer_ieee754": "< 0.9.7",
"buffer": true,
"node:buffer": [">= 14.18 && < 15", ">= 16"],
"child_process": true,
"node:child_process": [">= 14.18 && < 15", ">= 16"],
"cluster": true,
"node:cluster": [">= 14.18 && < 15", ">= 16"],
"console": true,
"node:console": [">= 14.18 && < 15", ">= 16"],
"constants": true,
"node:constants": [">= 14.18 && < 15", ">= 16"],
"crypto": true,
"node:crypto": [">= 14.18 && < 15", ">= 16"],
"_debug_agent": ">= 1 && < 8",
"_debugger": "< 8",
"dgram": true,
"node:dgram": [">= 14.18 && < 15", ">= 16"],
"diagnostics_channel": [">= 14.17 && < 15", ">= 15.1"],
"node:diagnostics_channel": [">= 14.18 && < 15", ">= 16"],
"dns": true,
"node:dns": [">= 14.18 && < 15", ">= 16"],
"dns/promises": ">= 15",
"node:dns/promises": ">= 16",
"domain": ">= 0.7.12",
"node:domain": [">= 14.18 && < 15", ">= 16"],
"events": true,
"node:events": [">= 14.18 && < 15", ">= 16"],
"freelist": "< 6",
"fs": true,
"node:fs": [">= 14.18 && < 15", ">= 16"],
"fs/promises": [">= 10 && < 10.1", ">= 14"],
"node:fs/promises": [">= 14.18 && < 15", ">= 16"],
"_http_agent": ">= 0.11.1",
"node:_http_agent": [">= 14.18 && < 15", ">= 16"],
"_http_client": ">= 0.11.1",
"node:_http_client": [">= 14.18 && < 15", ">= 16"],
"_http_common": ">= 0.11.1",
"node:_http_common": [">= 14.18 && < 15", ">= 16"],
"_http_incoming": ">= 0.11.1",
"node:_http_incoming": [">= 14.18 && < 15", ">= 16"],
"_http_outgoing": ">= 0.11.1",
"node:_http_outgoing": [">= 14.18 && < 15", ">= 16"],
"_http_server": ">= 0.11.1",
"node:_http_server": [">= 14.18 && < 15", ">= 16"],
"http": true,
"node:http": [">= 14.18 && < 15", ">= 16"],
"http2": ">= 8.8",
"node:http2": [">= 14.18 && < 15", ">= 16"],
"https": true,
"node:https": [">= 14.18 && < 15", ">= 16"],
"inspector": ">= 8",
"node:inspector": [">= 14.18 && < 15", ">= 16"],
"_linklist": "< 8",
"module": true,
"node:module": [">= 14.18 && < 15", ">= 16"],
"net": true,
"node:net": [">= 14.18 && < 15", ">= 16"],
"node-inspect/lib/_inspect": ">= 7.6 && < 12",
"node-inspect/lib/internal/inspect_client": ">= 7.6 && < 12",
"node-inspect/lib/internal/inspect_repl": ">= 7.6 && < 12",
"os": true,
"node:os": [">= 14.18 && < 15", ">= 16"],
"path": true,
"node:path": [">= 14.18 && < 15", ">= 16"],
"path/posix": ">= 15.3",
"node:path/posix": ">= 16",
"path/win32": ">= 15.3",
"node:path/win32": ">= 16",
"perf_hooks": ">= 8.5",
"node:perf_hooks": [">= 14.18 && < 15", ">= 16"],
"process": ">= 1",
"node:process": [">= 14.18 && < 15", ">= 16"],
"punycode": true,
"node:punycode": [">= 14.18 && < 15", ">= 16"],
"querystring": true,
"node:querystring": [">= 14.18 && < 15", ">= 16"],
"readline": true,
"node:readline": [">= 14.18 && < 15", ">= 16"],
"readline/promises": ">= 17",
"node:readline/promises": ">= 17",
"repl": true,
"node:repl": [">= 14.18 && < 15", ">= 16"],
"smalloc": ">= 0.11.5 && < 3",
"_stream_duplex": ">= 0.9.4",
"node:_stream_duplex": [">= 14.18 && < 15", ">= 16"],
"_stream_transform": ">= 0.9.4",
"node:_stream_transform": [">= 14.18 && < 15", ">= 16"],
"_stream_wrap": ">= 1.4.1",
"node:_stream_wrap": [">= 14.18 && < 15", ">= 16"],
"_stream_passthrough": ">= 0.9.4",
"node:_stream_passthrough": [">= 14.18 && < 15", ">= 16"],
"_stream_readable": ">= 0.9.4",
"node:_stream_readable": [">= 14.18 && < 15", ">= 16"],
"_stream_writable": ">= 0.9.4",
"node:_stream_writable": [">= 14.18 && < 15", ">= 16"],
"stream": true,
"node:stream": [">= 14.18 && < 15", ">= 16"],
"stream/consumers": ">= 16.7",
"node:stream/consumers": ">= 16.7",
"stream/promises": ">= 15",
"node:stream/promises": ">= 16",
"stream/web": ">= 16.5",
"node:stream/web": ">= 16.5",
"string_decoder": true,
"node:string_decoder": [">= 14.18 && < 15", ">= 16"],
"sys": [">= 0.6 && < 0.7", ">= 0.8"],
"node:sys": [">= 14.18 && < 15", ">= 16"],
"timers": true,
"node:timers": [">= 14.18 && < 15", ">= 16"],
"timers/promises": ">= 15",
"node:timers/promises": ">= 16",
"_tls_common": ">= 0.11.13",
"node:_tls_common": [">= 14.18 && < 15", ">= 16"],
"_tls_legacy": ">= 0.11.3 && < 10",
"_tls_wrap": ">= 0.11.3",
"node:_tls_wrap": [">= 14.18 && < 15", ">= 16"],
"tls": true,
"node:tls": [">= 14.18 && < 15", ">= 16"],
"trace_events": ">= 10",
"node:trace_events": [">= 14.18 && < 15", ">= 16"],
"tty": true,
"node:tty": [">= 14.18 && < 15", ">= 16"],
"url": true,
"node:url": [">= 14.18 && < 15", ">= 16"],
"util": true,
"node:util": [">= 14.18 && < 15", ">= 16"],
"util/types": ">= 15.3",
"node:util/types": ">= 16",
"v8/tools/arguments": ">= 10 && < 12",
"v8/tools/codemap": [">= 4.4 && < 5", ">= 5.2 && < 12"],
"v8/tools/consarray": [">= 4.4 && < 5", ">= 5.2 && < 12"],
"v8/tools/csvparser": [">= 4.4 && < 5", ">= 5.2 && < 12"],
"v8/tools/logreader": [">= 4.4 && < 5", ">= 5.2 && < 12"],
"v8/tools/profile_view": [">= 4.4 && < 5", ">= 5.2 && < 12"],
"v8/tools/splaytree": [">= 4.4 && < 5", ">= 5.2 && < 12"],
"v8": ">= 1",
"node:v8": [">= 14.18 && < 15", ">= 16"],
"vm": true,
"node:vm": [">= 14.18 && < 15", ">= 16"],
"wasi": ">= 13.4 && < 13.5",
"worker_threads": ">= 11.7",
"node:worker_threads": [">= 14.18 && < 15", ">= 16"],
"zlib": true,
"node:zlib": [">= 14.18 && < 15", ">= 16"]
}

69
node_modules/is-core-module/index.js generated vendored
View File

@ -1,69 +0,0 @@
'use strict';
var has = require('has');
function specifierIncluded(current, specifier) {
var nodeParts = current.split('.');
var parts = specifier.split(' ');
var op = parts.length > 1 ? parts[0] : '=';
var versionParts = (parts.length > 1 ? parts[1] : parts[0]).split('.');
for (var i = 0; i < 3; ++i) {
var cur = parseInt(nodeParts[i] || 0, 10);
var ver = parseInt(versionParts[i] || 0, 10);
if (cur === ver) {
continue; // eslint-disable-line no-restricted-syntax, no-continue
}
if (op === '<') {
return cur < ver;
}
if (op === '>=') {
return cur >= ver;
}
return false;
}
return op === '>=';
}
function matchesRange(current, range) {
var specifiers = range.split(/ ?&& ?/);
if (specifiers.length === 0) {
return false;
}
for (var i = 0; i < specifiers.length; ++i) {
if (!specifierIncluded(current, specifiers[i])) {
return false;
}
}
return true;
}
function versionIncluded(nodeVersion, specifierValue) {
if (typeof specifierValue === 'boolean') {
return specifierValue;
}
var current = typeof nodeVersion === 'undefined'
? process.versions && process.versions.node
: nodeVersion;
if (typeof current !== 'string') {
throw new TypeError(typeof nodeVersion === 'undefined' ? 'Unable to determine current node version' : 'If provided, a valid node version is required');
}
if (specifierValue && typeof specifierValue === 'object') {
for (var i = 0; i < specifierValue.length; ++i) {
if (matchesRange(current, specifierValue[i])) {
return true;
}
}
return false;
}
return matchesRange(current, specifierValue);
}
var data = require('./core.json');
module.exports = function isCore(x, nodeVersion) {
return has(data, x) && versionIncluded(nodeVersion, data[x]);
};

View File

@ -1,69 +0,0 @@
{
"name": "is-core-module",
"version": "2.8.0",
"description": "Is this specifier a node.js core module?",
"main": "index.js",
"sideEffects": false,
"exports": {
".": [
{
"default": "./index.js"
},
"./index.js"
],
"./package.json": "./package.json"
},
"scripts": {
"prepublish": "not-in-publish || npm run prepublishOnly",
"prepublishOnly": "safe-publish-latest",
"lint": "eslint .",
"pretest": "npm run lint",
"tests-only": "tape 'test/**/*.js'",
"test": "nyc npm run tests-only",
"posttest": "aud --production",
"version": "auto-changelog && git add CHANGELOG.md",
"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
},
"repository": {
"type": "git",
"url": "git+https://github.com/inspect-js/is-core-module.git"
},
"keywords": [
"core",
"modules",
"module",
"npm",
"node",
"dependencies"
],
"author": "Jordan Harband <ljharb@gmail.com>",
"funding": {
"url": "https://github.com/sponsors/ljharb"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/inspect-js/is-core-module/issues"
},
"homepage": "https://github.com/inspect-js/is-core-module",
"dependencies": {
"has": "^1.0.3"
},
"devDependencies": {
"@ljharb/eslint-config": "^18.0.0",
"aud": "^1.1.5",
"auto-changelog": "^2.3.0",
"eslint": "^7.32.0",
"nyc": "^10.3.2",
"safe-publish-latest": "^1.1.4",
"semver": "^6.3.0",
"tape": "^5.3.1"
},
"auto-changelog": {
"output": "CHANGELOG.md",
"template": "keepachangelog",
"unreleased": false,
"commitLimit": false,
"backfillLimit": false,
"hideCredit": true
}
}

View File

@ -1,130 +0,0 @@
'use strict';
var test = require('tape');
var keys = require('object-keys');
var semver = require('semver');
var isCore = require('../');
var data = require('../core.json');
var supportsNodePrefix = semver.satisfies(process.versions.node, '^14.18 || >= 16', { includePrerelease: true });
test('core modules', function (t) {
t.test('isCore()', function (st) {
st.ok(isCore('fs'));
st.ok(isCore('net'));
st.ok(isCore('http'));
st.ok(!isCore('seq'));
st.ok(!isCore('../'));
st.ok(!isCore('toString'));
st.end();
});
t.test('core list', function (st) {
var cores = keys(data);
st.plan(cores.length);
for (var i = 0; i < cores.length; ++i) {
var mod = cores[i];
var requireFunc = function () { require(mod); }; // eslint-disable-line no-loop-func
if (isCore(mod)) {
st.doesNotThrow(requireFunc, mod + ' supported; requiring does not throw');
} else {
st['throws'](requireFunc, mod + ' not supported; requiring throws');
}
}
st.end();
});
t.test('core via repl module', { skip: !data.repl }, function (st) {
var libs = require('repl')._builtinLibs; // eslint-disable-line no-underscore-dangle
if (!libs) {
st.skip('module.builtinModules does not exist');
} else {
for (var i = 0; i < libs.length; ++i) {
var mod = libs[i];
st.ok(data[mod], mod + ' is a core module');
st.doesNotThrow(
function () { require(mod); }, // eslint-disable-line no-loop-func
'requiring ' + mod + ' does not throw'
);
if (supportsNodePrefix) {
st.doesNotThrow(
function () { require('node:' + mod); }, // eslint-disable-line no-loop-func
'requiring node:' + mod + ' does not throw'
);
} else {
st['throws'](
function () { require('node:' + mod); }, // eslint-disable-line no-loop-func
'requiring node:' + mod + ' throws'
);
}
}
}
st.end();
});
t.test('core via builtinModules list', { skip: !data.module }, function (st) {
var libs = require('module').builtinModules;
if (!libs) {
st.skip('module.builtinModules does not exist');
} else {
var excludeList = [
'_debug_agent',
'v8/tools/tickprocessor-driver',
'v8/tools/SourceMap',
'v8/tools/tickprocessor',
'v8/tools/profile'
];
for (var i = 0; i < libs.length; ++i) {
var mod = libs[i];
if (excludeList.indexOf(mod) === -1) {
st.ok(data[mod], mod + ' is a core module');
st.doesNotThrow(
function () { require(mod); }, // eslint-disable-line no-loop-func
'requiring ' + mod + ' does not throw'
);
if (supportsNodePrefix) {
st.doesNotThrow(
function () { require('node:' + mod); }, // eslint-disable-line no-loop-func
'requiring node:' + mod + ' does not throw'
);
} else {
st['throws'](
function () { require('node:' + mod); }, // eslint-disable-line no-loop-func
'requiring node:' + mod + ' throws'
);
}
}
}
}
st.end();
});
t.test('Object.prototype pollution', function (st) {
/* eslint no-extend-native: 1 */
var nonKey = 'not a core module';
st.teardown(function () {
delete Object.prototype.fs;
delete Object.prototype.path;
delete Object.prototype.http;
delete Object.prototype[nonKey];
});
Object.prototype.fs = false;
Object.prototype.path = '>= 999999999';
Object.prototype.http = data.http;
Object.prototype[nonKey] = true;
st.equal(isCore('fs'), true, 'fs is a core module even if Object.prototype lies');
st.equal(isCore('path'), true, 'path is a core module even if Object.prototype lies');
st.equal(isCore('http'), true, 'path is a core module even if Object.prototype matches data');
st.equal(isCore(nonKey), false, '"' + nonKey + '" is not a core module even if Object.prototype lies');
st.end();
});
t.end();
});

20
node_modules/nanoid/LICENSE generated vendored
View File

@ -1,20 +0,0 @@
The MIT License (MIT)
Copyright 2017 Andrey Sitnik <andrey@sitnik.ru>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

39
node_modules/nanoid/README.md generated vendored
View File

@ -1,39 +0,0 @@
# Nano ID
<img src="https://ai.github.io/nanoid/logo.svg" align="right"
alt="Nano ID logo by Anton Lovchikov" width="180" height="94">
**English** | [Русский](./README.ru.md) | [简体中文](./README.zh-CN.md)
A tiny, secure, URL-friendly, unique string ID generator for JavaScript.
> “An amazing level of senseless perfectionism,
> which is simply impossible not to respect.”
* **Small.** 130 bytes (minified and gzipped). No dependencies.
[Size Limit] controls the size.
* **Fast.** It is 2 times faster than UUID.
* **Safe.** It uses hardware random generator. Can be used in clusters.
* **Short IDs.** It uses a larger alphabet than UUID (`A-Za-z0-9_-`).
So ID size was reduced from 36 to 21 symbols.
* **Portable.** Nano ID was ported
to [19 programming languages](#other-programming-languages).
```js
import { nanoid } from 'nanoid'
model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT"
```
Supports modern browsers, IE [with Babel], Node.js and React Native.
[online tool]: https://gitpod.io/#https://github.com/ai/nanoid/
[with Babel]: https://developer.epages.com/blog/coding/how-to-transpile-node-modules-with-babel-and-webpack-in-a-monorepo/
[Size Limit]: https://github.com/ai/size-limit
<a href="https://evilmartians.com/?utm_source=nanoid">
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg"
alt="Sponsored by Evil Martians" width="236" height="54">
</a>
## Docs
Read **[full docs](https://github.com/ai/nanoid#readme)** on GitHub.

View File

@ -1,35 +0,0 @@
let random = bytes =>
Promise.resolve(crypto.getRandomValues(new Uint8Array(bytes)))
let customAlphabet = (alphabet, size) => {
let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1
let step = -~((1.6 * mask * size) / alphabet.length)
return () => {
let id = ''
while (true) {
let bytes = crypto.getRandomValues(new Uint8Array(step))
let i = step
while (i--) {
id += alphabet[bytes[i] & mask] || ''
if (id.length === size) return Promise.resolve(id)
}
}
}
}
let nanoid = (size = 21) => {
let id = ''
let bytes = crypto.getRandomValues(new Uint8Array(size))
while (size--) {
let byte = bytes[size] & 63
if (byte < 36) {
id += byte.toString(36)
} else if (byte < 62) {
id += (byte - 26).toString(36).toUpperCase()
} else if (byte < 63) {
id += '_'
} else {
id += '-'
}
}
return Promise.resolve(id)
}
module.exports = { nanoid, customAlphabet, random }

View File

@ -1,35 +0,0 @@
let random = bytes =>
Promise.resolve(crypto.getRandomValues(new Uint8Array(bytes)))
let customAlphabet = (alphabet, size) => {
let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1
let step = -~((1.6 * mask * size) / alphabet.length)
return () => {
let id = ''
while (true) {
let bytes = crypto.getRandomValues(new Uint8Array(step))
let i = step
while (i--) {
id += alphabet[bytes[i] & mask] || ''
if (id.length === size) return Promise.resolve(id)
}
}
}
}
let nanoid = (size = 21) => {
let id = ''
let bytes = crypto.getRandomValues(new Uint8Array(size))
while (size--) {
let byte = bytes[size] & 63
if (byte < 36) {
id += byte.toString(36)
} else if (byte < 62) {
id += (byte - 26).toString(36).toUpperCase()
} else if (byte < 63) {
id += '_'
} else {
id += '-'
}
}
return Promise.resolve(id)
}
export { nanoid, customAlphabet, random }

35
node_modules/nanoid/async/index.cjs generated vendored
View File

@ -1,35 +0,0 @@
let crypto = require('crypto')
let { urlAlphabet } = require('../url-alphabet/index.cjs')
let random = bytes =>
new Promise((resolve, reject) => {
crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => {
if (err) {
reject(err)
} else {
resolve(buf)
}
})
})
let customAlphabet = (alphabet, size) => {
let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
let step = Math.ceil((1.6 * mask * size) / alphabet.length)
let tick = id =>
random(step).then(bytes => {
let i = step
while (i--) {
id += alphabet[bytes[i] & mask] || ''
if (id.length === size) return id
}
return tick(id)
})
return () => tick('')
}
let nanoid = (size = 21) =>
random(size).then(bytes => {
let id = ''
while (size--) {
id += urlAlphabet[bytes[size] & 63]
}
return id
})
module.exports = { nanoid, customAlphabet, random }

56
node_modules/nanoid/async/index.d.ts generated vendored
View File

@ -1,56 +0,0 @@
/**
* Generate secure URL-friendly unique ID. The non-blocking version.
*
* By default, the ID will have 21 symbols to have a collision probability
* similar to UUID v4.
*
* ```js
* import { nanoid } from 'nanoid/async'
* nanoid().then(id => {
* model.id = id
* })
* ```
*
* @param size Size of the ID. The default size is 21.
* @returns A promise with a random string.
*/
export function nanoid(size?: number): Promise<string>
/**
* A low-level function.
* Generate secure unique ID with custom alphabet. The non-blocking version.
*
* Alphabet must contain 256 symbols or less. Otherwise, the generator
* will not be secure.
*
* @param alphabet Alphabet used to generate the ID.
* @param size Size of the ID.
* @returns A promise with a random string.
*
* ```js
* import { customAlphabet } from 'nanoid/async'
* const nanoid = customAlphabet('0123456789абвгдеё', 5)
* nanoid().then(id => {
* model.id = id //=> "8ё56а"
* })
* ```
*/
export function customAlphabet(
alphabet: string,
size: number
): () => Promise<string>
/**
* Generate an array of random bytes collected from hardware noise.
*
* ```js
* import { random } from 'nanoid/async'
* random(5).then(bytes => {
* bytes //=> [10, 67, 212, 67, 89]
* })
* ```
*
* @param bytes Size of the array.
* @returns A promise with a random bytes array.
*/
export function random(bytes: number): Promise<Uint8Array>

35
node_modules/nanoid/async/index.js generated vendored
View File

@ -1,35 +0,0 @@
import crypto from 'crypto'
import { urlAlphabet } from '../url-alphabet/index.js'
let random = bytes =>
new Promise((resolve, reject) => {
crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => {
if (err) {
reject(err)
} else {
resolve(buf)
}
})
})
let customAlphabet = (alphabet, size) => {
let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
let step = Math.ceil((1.6 * mask * size) / alphabet.length)
let tick = id =>
random(step).then(bytes => {
let i = step
while (i--) {
id += alphabet[bytes[i] & mask] || ''
if (id.length === size) return id
}
return tick(id)
})
return () => tick('')
}
let nanoid = (size = 21) =>
random(size).then(bytes => {
let id = ''
while (size--) {
id += urlAlphabet[bytes[size] & 63]
}
return id
})
export { nanoid, customAlphabet, random }

View File

@ -1,26 +0,0 @@
import { getRandomBytesAsync } from 'expo-random'
import { urlAlphabet } from '../url-alphabet/index.js'
let random = getRandomBytesAsync
let customAlphabet = (alphabet, size) => {
let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
let step = Math.ceil((1.6 * mask * size) / alphabet.length)
let tick = id =>
random(step).then(bytes => {
let i = step
while (i--) {
id += alphabet[bytes[i] & mask] || ''
if (id.length === size) return id
}
return tick(id)
})
return () => tick('')
}
let nanoid = (size = 21) =>
random(size).then(bytes => {
let id = ''
while (size--) {
id += urlAlphabet[bytes[size] & 63]
}
return id
})
export { nanoid, customAlphabet, random }

View File

@ -1,12 +0,0 @@
{
"type": "module",
"main": "index.cjs",
"module": "index.js",
"react-native": {
"./index.js": "./index.native.js"
},
"browser": {
"./index.js": "./index.browser.js",
"./index.cjs": "./index.browser.cjs"
}
}

5
node_modules/nanoid/bin/nanoid.cjs generated vendored
View File

@ -1,5 +0,0 @@
#!/usr/bin/env node
let { nanoid } = require('..')
process.stdout.write(nanoid() + '\n')

View File

@ -1,62 +0,0 @@
let { urlAlphabet } = require('./url-alphabet/index.cjs')
if (process.env.NODE_ENV !== 'production') {
if (
typeof navigator !== 'undefined' &&
navigator.product === 'ReactNative' &&
typeof crypto === 'undefined'
) {
throw new Error(
'React Native does not have a built-in secure random generator. ' +
'If you dont need unpredictable IDs use `nanoid/non-secure`. ' +
'For secure IDs, import `react-native-get-random-values` ' +
'before Nano ID.'
)
}
if (typeof msCrypto !== 'undefined' && typeof crypto === 'undefined') {
throw new Error(
'Import file with `if (!window.crypto) window.crypto = window.msCrypto`' +
' before importing Nano ID to fix IE 11 support'
)
}
if (typeof crypto === 'undefined') {
throw new Error(
'Your browser does not have secure random generator. ' +
'If you dont need unpredictable IDs, you can use nanoid/non-secure.'
)
}
}
let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))
let customRandom = (alphabet, size, getRandom) => {
let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1
let step = -~((1.6 * mask * size) / alphabet.length)
return () => {
let id = ''
while (true) {
let bytes = getRandom(step)
let j = step
while (j--) {
id += alphabet[bytes[j] & mask] || ''
if (id.length === size) return id
}
}
}
}
let customAlphabet = (alphabet, size) => customRandom(alphabet, size, random)
let nanoid = (size = 21) => {
let id = ''
let bytes = crypto.getRandomValues(new Uint8Array(size))
while (size--) {
let byte = bytes[size] & 63
if (byte < 36) {
id += byte.toString(36)
} else if (byte < 62) {
id += (byte - 26).toString(36).toUpperCase()
} else if (byte < 63) {
id += '_'
} else {
id += '-'
}
}
return id
}
module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random }

Some files were not shown because too many files have changed in this diff Show More