整理桌面
This commit is contained in:
parent
82e3f2623f
commit
e25c8bb318
29
README.md
29
README.md
@ -1,21 +1,18 @@
|
||||
# sakuya
|
||||
你的智慧分身
|
||||
|
||||
必要具有特性:
|
||||
1. 全操作系统或不依赖操作系统运行
|
||||
2. 必要具备底层能力
|
||||
3. 智能化
|
||||
4. 无中断渐进迭代
|
||||
1. 确立目标本质
|
||||
2. 模拟环境与规则
|
||||
3. 基本条件
|
||||
|
||||
开放性:
|
||||
1. 可扩展易扩展
|
||||
|
||||
|
||||
### 功能效用
|
||||
1. 管理资产
|
||||
2. 接驳外部服务
|
||||
3. 简化过程
|
||||
4. 辅助工作
|
||||
5. 辅助认知
|
||||
6. 屏蔽干扰及排除干扰源
|
||||
实施:
|
||||
1. 智力问题通用方案基础
|
||||
2. 工具使用控制规则
|
||||
3. 修正控制
|
||||
4. 逻辑判断
|
||||
|
||||
例:
|
||||
1. 要求实现某行为结果
|
||||
2. 实施逻辑的组构
|
||||
3. 实施条件的采集
|
||||
4. 实施过程的模拟
|
||||
|
15
favicon.svg
Normal file
15
favicon.svg
Normal file
@ -0,0 +1,15 @@
|
||||
<svg width="410" height="404" viewBox="0 0 410 404" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M399.641 59.5246L215.643 388.545C211.844 395.338 202.084 395.378 198.228 388.618L10.5817 59.5563C6.38087 52.1896 12.6802 43.2665 21.0281 44.7586L205.223 77.6824C206.398 77.8924 207.601 77.8904 208.776 77.6763L389.119 44.8058C397.439 43.2894 403.768 52.1434 399.641 59.5246Z" fill="url(#paint0_linear)"/>
|
||||
<path d="M292.965 1.5744L156.801 28.2552C154.563 28.6937 152.906 30.5903 152.771 32.8664L144.395 174.33C144.198 177.662 147.258 180.248 150.51 179.498L188.42 170.749C191.967 169.931 195.172 173.055 194.443 176.622L183.18 231.775C182.422 235.487 185.907 238.661 189.532 237.56L212.947 230.446C216.577 229.344 220.065 232.527 219.297 236.242L201.398 322.875C200.278 328.294 207.486 331.249 210.492 326.603L212.5 323.5L323.454 102.072C325.312 98.3645 322.108 94.137 318.036 94.9228L279.014 102.454C275.347 103.161 272.227 99.746 273.262 96.1583L298.731 7.86689C299.767 4.27314 296.636 0.855181 292.965 1.5744Z" fill="url(#paint1_linear)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="6.00017" y1="32.9999" x2="235" y2="344" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#41D1FF"/>
|
||||
<stop offset="1" stop-color="#BD34FE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear" x1="194.651" y1="8.81818" x2="236.076" y2="292.989" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFEA83"/>
|
||||
<stop offset="0.0833333" stop-color="#FFDD35"/>
|
||||
<stop offset="1" stop-color="#FFA800"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
BIN
img/img.jpeg
Executable file
BIN
img/img.jpeg
Executable file
Binary file not shown.
After Width: | Height: | Size: 589 KiB |
58
index.html
Normal file
58
index.html
Normal file
@ -0,0 +1,58 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no" />
|
||||
<title>Sakuya</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ul>
|
||||
<li>不必自动补全的变数</li>
|
||||
<li>布局基本形式</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>自动拦截A标签</li>
|
||||
<li></li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>按照指令移动</li>
|
||||
<li>监测状态变化幅度</li>
|
||||
<li>预备触发</li>
|
||||
<li>触发执行动作</li>
|
||||
<li>触发后修正执行偏差</li>
|
||||
<li>检测物体或表面方案</li>
|
||||
<li>方案规划逻辑</li>
|
||||
<li>目标接纳逻辑</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>库模型:</li>
|
||||
<li>根模型</li>
|
||||
<li>链模型</li>
|
||||
<li>模型是模拟信号声明文件, 与编码语言无关, 也与数字运算无关, 数字运算是采样摘要</li>
|
||||
<li>元件库: 通过元件组合实现高级元件</li>
|
||||
<li>结构库: 通过元件占用特性进行排组, 实现结构合理化自动化, 将器件合并</li>
|
||||
<li>数字工厂: 使用材料建模, 并在微观细节声明特征效用</li>
|
||||
<li>设计模型过程亦使用声明文件</li>
|
||||
<li>方形桶/基座/安装结构, 力能势, 在线模拟? 或远程工厂视频?</li>
|
||||
<li>材料强化</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>元件列表: 通常是固体或柔性体</li>
|
||||
<li>材料列表: 可被塑造的, 或是有限被塑造, 或是不固定特征区域可以被有限塑造</li>
|
||||
<li>期望创造一种事物或对现有事物进行改造时</li>
|
||||
<li>命名事物并将之组合调整</li>
|
||||
<li>由于非手动建模, 只能声明特征并对特征的特定点挂载模型</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>声明过程:</li>
|
||||
<li>自动辅助: 空间中只有一个特征时, 视角转向特征中心点, 视场包含特征整体</li>
|
||||
<li>声明锚点精度可以无限大, (但制造工艺未必满足)</li>
|
||||
<li>可以声明虚拟参照模型, 仅用于挂载点和标示, 而不在实际生产中出现</li>
|
||||
</ul>
|
||||
<!--script type="module" src="/main.js"></script-->
|
||||
</body>
|
||||
|
||||
</html>
|
136
main.js
Normal file
136
main.js
Normal file
@ -0,0 +1,136 @@
|
||||
import Matrix from './widgets/matrix.js'
|
||||
import convolutionMatrix from './tools/convolutionMatrix.js'
|
||||
|
||||
let matrix = new Matrix(32, 32)
|
||||
document.body.appendChild(matrix.element)
|
||||
|
||||
// DEMO
|
||||
var canvas = document.createElement("canvas"), //获取Canvas画布对象
|
||||
context = canvas.getContext('2d'); //获取2D上下文对象,大多数Canvas API均为此对象方法
|
||||
var image = new Image(); //定义一个图片对象
|
||||
image.src = 'img/img.jpeg';
|
||||
image.onload = function () { //此处必须注意!后面所有操作均需在图片加载成功后执行,否则图片将处理无效
|
||||
context.drawImage(image, 0, 0); //将图片从Canvas画布的左上角(0,0)位置开始绘制,大小默认为图片实际大小
|
||||
var handle = document.createElement("button");
|
||||
var create = document.createElement("button");
|
||||
document.body.appendChild(handle)
|
||||
document.body.appendChild(create)
|
||||
handle.innerText = "处理图片"
|
||||
create.innerText = "生成图片"
|
||||
handle.onclick = function () { // 单击“处理图片”按钮,处理图片
|
||||
var imgData = context.getImageData(0, 0, canvas.width, canvas.height); //获取图片数据对象
|
||||
var average = 0; //获取图片数据数组,该数组中每个像素用4个元素来保存,分别表示红、绿、蓝和透明度值
|
||||
|
||||
// 灰度处理
|
||||
//for (var i = 0; i < imgData.data.length; i += 4) {
|
||||
// average = Math.floor((imgData.data[i] + imgData.data[i + 1] + imgData.data[i + 2]) / 3); //将红、绿、蓝色值求平均值后得到灰度值
|
||||
// imgData.data[i] = imgData.data[i + 1] = imgData.data[i + 2] = average; //将每个像素点的色值重写
|
||||
// //matrix.setItem(i, 1, 125)
|
||||
// //console.log(imgData.data[i])
|
||||
// //matrix.setIndex(i / 4, imgData.data[i])
|
||||
//}
|
||||
//context.putImageData(imgData, 0, 0); //将处理后的图像数据重写至Canvas画布,此时画布中图像变为黑白色
|
||||
|
||||
};
|
||||
|
||||
//create.onclick = function () { // 单击“生成图片”按钮,导出图片
|
||||
// var imgSrc = canvas.toDataURL(); //获取图片的DataURL
|
||||
// var newImg = new Image();
|
||||
// var result = document.createElement("div");
|
||||
// document.body.appendChild(result)
|
||||
// newImg.src = imgSrc; //将图片路径赋值给src
|
||||
// result.innerHTML = '';
|
||||
// result.appendChild(newImg);
|
||||
// //matrix.setItem(2, 0, 125)
|
||||
//};
|
||||
|
||||
let imgData = context.getImageData(0, 0, canvas.width, canvas.height); //获取图片数据对象
|
||||
|
||||
// 分离通道
|
||||
let R = []
|
||||
let G = []
|
||||
let B = []
|
||||
for (var i = 0; i < imgData.data.length; i += 4) {
|
||||
R.push(imgData.data[i])
|
||||
G.push(imgData.data[i + 1])
|
||||
B.push(imgData.data[i + 2])
|
||||
}
|
||||
|
||||
// 使用单通道
|
||||
for (var i = 0; i < imgData.data.length; i += 4) {
|
||||
imgData.data[i + 1] = 0
|
||||
imgData.data[i + 2] = 0
|
||||
}
|
||||
context.putImageData(imgData, 0, 0);
|
||||
|
||||
// 10 层神经网络
|
||||
for (let i = 0; i < 10; i++) {
|
||||
// 滤波器
|
||||
context.putImageData(convolutionMatrix(imgData, [
|
||||
//-1, -1, 0,
|
||||
//-1, 1, 1,
|
||||
//0, 1, 1,
|
||||
-2, -1, 0,
|
||||
1, -1, 1,
|
||||
8, 0, -4
|
||||
]), 0, 0)
|
||||
}
|
||||
|
||||
//let ctx = this
|
||||
//for (var i = 0; i < imgData.data.length; i += 4) {
|
||||
// imgData.data[i + 1] = 128
|
||||
// imgData.data[i + 2] = 128
|
||||
//}
|
||||
//context.putImageData(imgData, 0, 0);
|
||||
|
||||
// /*
|
||||
// * 参数中的 kernel 就是卷积核方阵,不过顺着排列成了一个九位的数组
|
||||
// * 像是这样 [-1, -1, -1, -1, 8, -1, -1, -1, -1]
|
||||
// * offset 对RGBA数值直接增加,表现为提高亮度
|
||||
// * 下面的for循环
|
||||
// * y 代表行,x 代表列,c 代表RGBA
|
||||
// */
|
||||
//convolutionMatrix(input, kernel, offset = 0) {
|
||||
// let ctx = this.outputCtx
|
||||
// let output = ctx.createImageData(input)
|
||||
// let w = input.width,
|
||||
// h = input.height
|
||||
// let iD = input.data,
|
||||
// oD = output.data
|
||||
// for (let y = 1; y < h - 1; y += 1) {
|
||||
// for (let x = 1; x < w - 1; x += 1) {
|
||||
// for (let c = 0; c < 3; c += 1) {
|
||||
// let i = (y * w + x) * 4 + c
|
||||
// oD[i] =
|
||||
// offset +
|
||||
// (kernel[0] * iD[i - w * 4 - 4] +
|
||||
// kernel[1] * iD[i - w * 4] +
|
||||
// kernel[2] * iD[i - w * 4 + 4] +
|
||||
// kernel[3] * iD[i - 4] +
|
||||
// kernel[4] * iD[i] +
|
||||
// kernel[5] * iD[i + 4] +
|
||||
// kernel[6] * iD[i + w * 4 - 4] +
|
||||
// kernel[7] * iD[i + w * 4] +
|
||||
// kernel[8] * iD[i + w * 4 + 4]) /
|
||||
// this.divisor
|
||||
// }
|
||||
// oD[(y * w + x) * 4 + 3] = 255
|
||||
// }
|
||||
// }
|
||||
// ctx.putImageData(output, 0, 0)
|
||||
//}
|
||||
|
||||
|
||||
};
|
||||
|
||||
document.body.appendChild(canvas)
|
||||
|
||||
// 第一层输入层数量固定 32*32
|
||||
// 通过 滤波器 保留特征, 到输出合并层时,
|
||||
// 网络深度有限, 因而特征规模有限(但非常大)
|
||||
// 如何作关键特征映射?
|
||||
// 1. 存储常见特征, 如果符合, 滤波器将一组特征保留, 因而最后一层滤波器输出结果就是// 卷积结果为激活值, 算子为特征
|
||||
// 2. 输入一张图像, 设定此图像输出结果
|
||||
// 3. 输入另一张图, 设定此图像输出结果
|
||||
|
||||
// 4. 输入另一张图, 排除所有不同激活的
|
1
node_modules/.bin/esbuild
generated
vendored
Symbolic link
1
node_modules/.bin/esbuild
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../esbuild/bin/esbuild
|
1
node_modules/.bin/nanoid
generated
vendored
Symbolic link
1
node_modules/.bin/nanoid
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../nanoid/bin/nanoid.cjs
|
1
node_modules/.bin/rollup
generated
vendored
Symbolic link
1
node_modules/.bin/rollup
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../rollup/dist/bin/rollup
|
1
node_modules/.bin/vite
generated
vendored
Symbolic link
1
node_modules/.bin/vite
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../vite/bin/vite.js
|
21
node_modules/.vite/_metadata.json
generated
vendored
Normal file
21
node_modules/.vite/_metadata.json
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"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
Normal file
28
node_modules/.vite/chunk-ELXAK55F.js
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
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
|
7
node_modules/.vite/chunk-ELXAK55F.js.map
generated
vendored
Normal file
7
node_modules/.vite/chunk-ELXAK55F.js.map
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sourcesContent": [],
|
||||
"mappings": "",
|
||||
"names": []
|
||||
}
|
1988
node_modules/.vite/frappe-charts.js
generated
vendored
Normal file
1988
node_modules/.vite/frappe-charts.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
node_modules/.vite/frappe-charts.js.map
generated
vendored
Normal file
7
node_modules/.vite/frappe-charts.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
3032
node_modules/.vite/neataptic.js
generated
vendored
Normal file
3032
node_modules/.vite/neataptic.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
node_modules/.vite/neataptic.js.map
generated
vendored
Normal file
7
node_modules/.vite/neataptic.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
17062
node_modules/.vite/p5.js
generated
vendored
Normal file
17062
node_modules/.vite/p5.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
7
node_modules/.vite/p5.js.map
generated
vendored
Normal file
7
node_modules/.vite/p5.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
node_modules/.vite/package.json
generated
vendored
Normal file
1
node_modules/.vite/package.json
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"type":"module"}
|
53
node_modules/.yarn-integrity
generated
vendored
Normal file
53
node_modules/.yarn-integrity
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
{
|
||||
"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": {}
|
||||
}
|
3
node_modules/esbuild-linux-64/README.md
generated
vendored
Normal file
3
node_modules/esbuild-linux-64/README.md
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# esbuild
|
||||
|
||||
This is the Linux 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.
|
BIN
node_modules/esbuild-linux-64/bin/esbuild
generated
vendored
Executable file
BIN
node_modules/esbuild-linux-64/bin/esbuild
generated
vendored
Executable file
Binary file not shown.
14
node_modules/esbuild-linux-64/package.json
generated
vendored
Normal file
14
node_modules/esbuild-linux-64/package.json
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"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
Normal file
3
node_modules/esbuild/README.md
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# 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
Executable file
108
node_modules/esbuild/bin/esbuild
generated
vendored
Executable file
@ -0,0 +1,108 @@
|
||||
#!/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
Normal file
244
node_modules/esbuild/install.js
generated
vendored
Normal file
@ -0,0 +1,244 @@
|
||||
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
Normal file
524
node_modules/esbuild/lib/main.d.ts
generated
vendored
Normal file
@ -0,0 +1,524 @@
|
||||
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
Normal file
2108
node_modules/esbuild/lib/main.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
34
node_modules/esbuild/package.json
generated
vendored
Normal file
34
node_modules/esbuild/package.json
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"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
Normal file
21
node_modules/frappe-charts/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
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
Normal file
121
node_modules/frappe-charts/README.md
generated
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
<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).
|
4108
node_modules/frappe-charts/dist/frappe-charts.esm.js
generated
vendored
Normal file
4108
node_modules/frappe-charts/dist/frappe-charts.esm.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2
node_modules/frappe-charts/dist/frappe-charts.min.cjs.js
generated
vendored
Normal file
2
node_modules/frappe-charts/dist/frappe-charts.min.cjs.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
node_modules/frappe-charts/dist/frappe-charts.min.cjs.js.map
generated
vendored
Normal file
1
node_modules/frappe-charts/dist/frappe-charts.min.cjs.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
2
node_modules/frappe-charts/dist/frappe-charts.min.esm.js
generated
vendored
Normal file
2
node_modules/frappe-charts/dist/frappe-charts.min.esm.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
node_modules/frappe-charts/dist/frappe-charts.min.esm.js.map
generated
vendored
Normal file
1
node_modules/frappe-charts/dist/frappe-charts.min.esm.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
2
node_modules/frappe-charts/dist/frappe-charts.min.umd.js
generated
vendored
Normal file
2
node_modules/frappe-charts/dist/frappe-charts.min.umd.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
node_modules/frappe-charts/dist/frappe-charts.min.umd.js.map
generated
vendored
Normal file
1
node_modules/frappe-charts/dist/frappe-charts.min.umd.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
68
node_modules/frappe-charts/package.json
generated
vendored
Normal file
68
node_modules/frappe-charts/package.json
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
{
|
||||
"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": {}
|
||||
}
|
116
node_modules/frappe-charts/src/css/charts.scss
generated
vendored
Normal file
116
node_modules/frappe-charts/src/css/charts.scss
generated
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
1
node_modules/frappe-charts/src/css/chartsCss.js
generated
vendored
Normal file
1
node_modules/frappe-charts/src/css/chartsCss.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
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}";
|
40
node_modules/frappe-charts/src/js/chart.js
generated
vendored
Normal file
40
node_modules/frappe-charts/src/js/chart.js
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
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 };
|
95
node_modules/frappe-charts/src/js/charts/AggregationChart.js
generated
vendored
Normal file
95
node_modules/frappe-charts/src/js/charts/AggregationChart.js
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
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++;
|
||||
});
|
||||
}
|
||||
}
|
590
node_modules/frappe-charts/src/js/charts/AxisChart.js
generated
vendored
Normal file
590
node_modules/frappe-charts/src/js/charts/AxisChart.js
generated
vendored
Normal file
@ -0,0 +1,590 @@
|
||||
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 == '&' ? '&' : char == '<' ? '<' : '>'),
|
||||
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) {}
|
||||
}
|
324
node_modules/frappe-charts/src/js/charts/BaseChart.js
generated
vendored
Normal file
324
node_modules/frappe-charts/src/js/charts/BaseChart.js
generated
vendored
Normal file
@ -0,0 +1,324 @@
|
||||
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]);
|
||||
}
|
||||
}
|
161
node_modules/frappe-charts/src/js/charts/DonutChart.js
generated
vendored
Normal file
161
node_modules/frappe-charts/src/js/charts/DonutChart.js
generated
vendored
Normal file
@ -0,0 +1,161 @@
|
||||
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);
|
||||
}
|
||||
}
|
296
node_modules/frappe-charts/src/js/charts/Heatmap.js
generated
vendored
Normal file
296
node_modules/frappe-charts/src/js/charts/Heatmap.js
generated
vendored
Normal file
@ -0,0 +1,296 @@
|
||||
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;
|
||||
}
|
||||
}
|
173
node_modules/frappe-charts/src/js/charts/MultiAxisChart.js
generated
vendored
Normal file
173
node_modules/frappe-charts/src/js/charts/MultiAxisChart.js
generated
vendored
Normal file
@ -0,0 +1,173 @@
|
||||
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
|
||||
));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
92
node_modules/frappe-charts/src/js/charts/PercentageChart.js
generated
vendored
Normal file
92
node_modules/frappe-charts/src/js/charts/PercentageChart.js
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
155
node_modules/frappe-charts/src/js/charts/PieChart.js
generated
vendored
Normal file
155
node_modules/frappe-charts/src/js/charts/PieChart.js
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
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);
|
||||
}
|
||||
}
|
10
node_modules/frappe-charts/src/js/index.js
generated
vendored
Normal file
10
node_modules/frappe-charts/src/js/index.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
import * as Charts from './chart';
|
||||
|
||||
let frappe = { };
|
||||
|
||||
frappe.NAME = 'Frappe Charts';
|
||||
frappe.VERSION = '1.6.2';
|
||||
|
||||
frappe = Object.assign({ }, frappe, Charts);
|
||||
|
||||
export default frappe;
|
446
node_modules/frappe-charts/src/js/objects/ChartComponents.js
generated
vendored
Normal file
446
node_modules/frappe-charts/src/js/objects/ChartComponents.js
generated
vendored
Normal file
@ -0,0 +1,446 @@
|
||||
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);
|
||||
}
|
127
node_modules/frappe-charts/src/js/objects/SvgTip.js
generated
vendored
Normal file
127
node_modules/frappe-charts/src/js/objects/SvgTip.js
generated
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
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';
|
||||
}
|
||||
}
|
105
node_modules/frappe-charts/src/js/utils/animate.js
generated
vendored
Normal file
105
node_modules/frappe-charts/src/js/utils/animate.js
generated
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
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];
|
||||
}
|
120
node_modules/frappe-charts/src/js/utils/animation.js
generated
vendored
Normal file
120
node_modules/frappe-charts/src/js/utils/animation.js
generated
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
// 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);
|
||||
}
|
129
node_modules/frappe-charts/src/js/utils/axis-chart-utils.js
generated
vendored
Normal file
129
node_modules/frappe-charts/src/js/utils/axis-chart-utils.js
generated
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
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;
|
||||
}
|
53
node_modules/frappe-charts/src/js/utils/colors.js
generated
vendored
Normal file
53
node_modules/frappe-charts/src/js/utils/colors.js
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
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;
|
||||
};
|
107
node_modules/frappe-charts/src/js/utils/constants.js
generated
vendored
Normal file
107
node_modules/frappe-charts/src/js/utils/constants.js
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
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;
|
90
node_modules/frappe-charts/src/js/utils/date-utils.js
generated
vendored
Normal file
90
node_modules/frappe-charts/src/js/utils/date-utils.js
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
// 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);
|
||||
}
|
137
node_modules/frappe-charts/src/js/utils/dom.js
generated
vendored
Normal file
137
node_modules/frappe-charts/src/js/utils/dom.js
generated
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
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);
|
||||
}
|
99
node_modules/frappe-charts/src/js/utils/draw-utils.js
generated
vendored
Normal file
99
node_modules/frappe-charts/src/js/utils/draw-utils.js
generated
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
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);
|
||||
}
|
731
node_modules/frappe-charts/src/js/utils/draw.js
generated
vendored
Normal file
731
node_modules/frappe-charts/src/js/utils/draw.js
generated
vendored
Normal file
@ -0,0 +1,731 @@
|
||||
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);
|
||||
}
|
||||
},
|
||||
};
|
33
node_modules/frappe-charts/src/js/utils/export.js
generated
vendored
Normal file
33
node_modules/frappe-charts/src/js/utils/export.js
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
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;
|
||||
}
|
143
node_modules/frappe-charts/src/js/utils/helpers.js
generated
vendored
Normal file
143
node_modules/frappe-charts/src/js/utils/helpers.js
generated
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
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;
|
||||
}
|
239
node_modules/frappe-charts/src/js/utils/intervals.js
generated
vendored
Normal file
239
node_modules/frappe-charts/src/js/utils/intervals.js
generated
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
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;
|
||||
}
|
14
node_modules/frappe-charts/src/js/utils/test/colors.test.js
generated
vendored
Normal file
14
node_modules/frappe-charts/src/js/utils/test/colors.test.js
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
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');
|
||||
});
|
||||
});
|
10
node_modules/frappe-charts/src/js/utils/test/helpers.test.js
generated
vendored
Normal file
10
node_modules/frappe-charts/src/js/utils/test/helpers.test.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
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);
|
||||
});
|
||||
});
|
20
node_modules/function-bind/.editorconfig
generated
vendored
Normal file
20
node_modules/function-bind/.editorconfig
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
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
Normal file
15
node_modules/function-bind/.eslintrc
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"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
Normal file
176
node_modules/function-bind/.jscs.json
generated
vendored
Normal file
@ -0,0 +1,176 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
|
22
node_modules/function-bind/.npmignore
generated
vendored
Normal file
22
node_modules/function-bind/.npmignore
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
# 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
|
168
node_modules/function-bind/.travis.yml
generated
vendored
Normal file
168
node_modules/function-bind/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,168 @@
|
||||
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
Normal file
20
node_modules/function-bind/LICENSE
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
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
Normal file
48
node_modules/function-bind/README.md
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
# 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
|
52
node_modules/function-bind/implementation.js
generated
vendored
Normal file
52
node_modules/function-bind/implementation.js
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
'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;
|
||||
};
|
5
node_modules/function-bind/index.js
generated
vendored
Normal file
5
node_modules/function-bind/index.js
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var implementation = require('./implementation');
|
||||
|
||||
module.exports = Function.prototype.bind || implementation;
|
63
node_modules/function-bind/package.json
generated
vendored
Normal file
63
node_modules/function-bind/package.json
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
{
|
||||
"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"
|
||||
]
|
||||
}
|
||||
}
|
9
node_modules/function-bind/test/.eslintrc
generated
vendored
Normal file
9
node_modules/function-bind/test/.eslintrc
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"rules": {
|
||||
"array-bracket-newline": 0,
|
||||
"array-element-newline": 0,
|
||||
"max-statements-per-line": [2, { "max": 2 }],
|
||||
"no-invalid-this": 0,
|
||||
"no-magic-numbers": 0,
|
||||
}
|
||||
}
|
252
node_modules/function-bind/test/index.js
generated
vendored
Normal file
252
node_modules/function-bind/test/index.js
generated
vendored
Normal file
@ -0,0 +1,252 @@
|
||||
// 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
Normal file
22
node_modules/has/LICENSE-MIT
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
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
Normal file
18
node_modules/has/README.md
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
# 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
Normal file
48
node_modules/has/package.json
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"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
Normal file
5
node_modules/has/src/index.js
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
'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
Normal file
10
node_modules/has/test/index.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
'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();
|
||||
});
|
1
node_modules/is-core-module/.eslintignore
generated
vendored
Normal file
1
node_modules/is-core-module/.eslintignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
coverage/
|
18
node_modules/is-core-module/.eslintrc
generated
vendored
Normal file
18
node_modules/is-core-module/.eslintrc
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"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
Normal file
9
node_modules/is-core-module/.nycrc
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"all": true,
|
||||
"check-coverage": false,
|
||||
"reporter": ["text-summary", "text", "html", "json"],
|
||||
"exclude": [
|
||||
"coverage",
|
||||
"test"
|
||||
]
|
||||
}
|
117
node_modules/is-core-module/CHANGELOG.md
generated
vendored
Normal file
117
node_modules/is-core-module/CHANGELOG.md
generated
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
# 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 `>= 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 > v0.7.7 and <= 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
Normal file
20
node_modules/is-core-module/LICENSE
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
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.
|
40
node_modules/is-core-module/README.md
generated
vendored
Normal file
40
node_modules/is-core-module/README.md
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
# 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
Normal file
152
node_modules/is-core-module/core.json
generated
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
{
|
||||
"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
Normal file
69
node_modules/is-core-module/index.js
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
'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]);
|
||||
};
|
69
node_modules/is-core-module/package.json
generated
vendored
Normal file
69
node_modules/is-core-module/package.json
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
130
node_modules/is-core-module/test/index.js
generated
vendored
Normal file
130
node_modules/is-core-module/test/index.js
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
'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
Normal file
20
node_modules/nanoid/LICENSE
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
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
Normal file
39
node_modules/nanoid/README.md
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
# 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.
|
35
node_modules/nanoid/async/index.browser.cjs
generated
vendored
Normal file
35
node_modules/nanoid/async/index.browser.cjs
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
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 }
|
35
node_modules/nanoid/async/index.browser.js
generated
vendored
Normal file
35
node_modules/nanoid/async/index.browser.js
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
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
Normal file
35
node_modules/nanoid/async/index.cjs
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
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
Normal file
56
node_modules/nanoid/async/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* 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>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user