simview 3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. simview/__init__.py +69 -0
  2. simview/__main__.py +174 -0
  3. simview/launcher.py +109 -0
  4. simview/live.py +204 -0
  5. simview/merge.py +593 -0
  6. simview/model.py +690 -0
  7. simview/py.typed +0 -0
  8. simview/scene.py +603 -0
  9. simview/server.py +739 -0
  10. simview/state.py +190 -0
  11. simview/static/css/controls.css +36 -0
  12. simview/static/js/SimView.js +601 -0
  13. simview/static/js/components/AnimationController.js +654 -0
  14. simview/static/js/components/BatchManager.js +198 -0
  15. simview/static/js/components/InteractionController.js +446 -0
  16. simview/static/js/components/InteractionControls.js +116 -0
  17. simview/static/js/components/Scene.js +166 -0
  18. simview/static/js/components/StateStore.js +188 -0
  19. simview/static/js/config.js +233 -0
  20. simview/static/js/main.js +3 -0
  21. simview/static/js/objects/Body.js +616 -0
  22. simview/static/js/objects/StaticObject.js +181 -0
  23. simview/static/js/objects/Terrain.js +514 -0
  24. simview/static/js/objects/utils.js +378 -0
  25. simview/static/js/ui/AnalysisPanel.js +233 -0
  26. simview/static/js/ui/BatchLegend.js +207 -0
  27. simview/static/js/ui/BodyStateWindow.js +521 -0
  28. simview/static/js/ui/Controls.js +586 -0
  29. simview/static/js/ui/ErrorMetrics.js +664 -0
  30. simview/static/js/ui/Legend.js +87 -0
  31. simview/static/js/ui/PlaybackControls.js +314 -0
  32. simview/static/js/ui/ScalarPlotter.js +575 -0
  33. simview/static/js/utils/blobCodec.js +73 -0
  34. simview/static/js/utils/bodyTransforms.js +151 -0
  35. simview/static/js/utils/csv.js +46 -0
  36. simview/static/js/utils/errorMath.js +69 -0
  37. simview/static/js/utils/injectStyles.js +16 -0
  38. simview/static/js/utils/interpolate.js +65 -0
  39. simview/static/js/utils/liveFollow.js +17 -0
  40. simview/static/js/utils/loadRecordingLibs.js +34 -0
  41. simview/static/js/utils/viewState.js +226 -0
  42. simview/static/lib/chroma-js-3.1.2/index.min.js +8 -0
  43. simview/static/lib/chroma-js-3.1.2/src/Color.js +49 -0
  44. simview/static/lib/chroma-js-3.1.2/src/chroma.js +10 -0
  45. simview/static/lib/chroma-js-3.1.2/src/colors/colorbrewer.js +81 -0
  46. simview/static/lib/chroma-js-3.1.2/src/colors/w3cx11.js +164 -0
  47. simview/static/lib/chroma-js-3.1.2/src/generator/average.js +88 -0
  48. simview/static/lib/chroma-js-3.1.2/src/generator/bezier.js +86 -0
  49. simview/static/lib/chroma-js-3.1.2/src/generator/blend.js +57 -0
  50. simview/static/lib/chroma-js-3.1.2/src/generator/cubehelix.js +87 -0
  51. simview/static/lib/chroma-js-3.1.2/src/generator/mix.js +19 -0
  52. simview/static/lib/chroma-js-3.1.2/src/generator/random.js +12 -0
  53. simview/static/lib/chroma-js-3.1.2/src/generator/scale.js +394 -0
  54. simview/static/lib/chroma-js-3.1.2/src/interpolator/_hsx.js +59 -0
  55. simview/static/lib/chroma-js-3.1.2/src/interpolator/hcg.js +12 -0
  56. simview/static/lib/chroma-js-3.1.2/src/interpolator/hsi.js +12 -0
  57. simview/static/lib/chroma-js-3.1.2/src/interpolator/hsl.js +12 -0
  58. simview/static/lib/chroma-js-3.1.2/src/interpolator/hsv.js +12 -0
  59. simview/static/lib/chroma-js-3.1.2/src/interpolator/index.js +1 -0
  60. simview/static/lib/chroma-js-3.1.2/src/interpolator/lab.js +19 -0
  61. simview/static/lib/chroma-js-3.1.2/src/interpolator/lch.js +13 -0
  62. simview/static/lib/chroma-js-3.1.2/src/interpolator/lrgb.js +19 -0
  63. simview/static/lib/chroma-js-3.1.2/src/interpolator/num.js +15 -0
  64. simview/static/lib/chroma-js-3.1.2/src/interpolator/oklab.js +19 -0
  65. simview/static/lib/chroma-js-3.1.2/src/interpolator/oklch.js +12 -0
  66. simview/static/lib/chroma-js-3.1.2/src/interpolator/rgb.js +18 -0
  67. simview/static/lib/chroma-js-3.1.2/src/io/cmyk/cmyk2rgb.js +16 -0
  68. simview/static/lib/chroma-js-3.1.2/src/io/cmyk/index.js +27 -0
  69. simview/static/lib/chroma-js-3.1.2/src/io/cmyk/rgb2cmyk.js +17 -0
  70. simview/static/lib/chroma-js-3.1.2/src/io/css/css2rgb.js +238 -0
  71. simview/static/lib/chroma-js-3.1.2/src/io/css/hsl2css.js +26 -0
  72. simview/static/lib/chroma-js-3.1.2/src/io/css/index.js +27 -0
  73. simview/static/lib/chroma-js-3.1.2/src/io/css/lab2css.js +24 -0
  74. simview/static/lib/chroma-js-3.1.2/src/io/css/lch2css.js +24 -0
  75. simview/static/lib/chroma-js-3.1.2/src/io/css/oklab2css.js +16 -0
  76. simview/static/lib/chroma-js-3.1.2/src/io/css/oklch2css.js +16 -0
  77. simview/static/lib/chroma-js-3.1.2/src/io/css/rgb2css.js +61 -0
  78. simview/static/lib/chroma-js-3.1.2/src/io/gl/index.js +22 -0
  79. simview/static/lib/chroma-js-3.1.2/src/io/hcg/hcg2rgb.js +55 -0
  80. simview/static/lib/chroma-js-3.1.2/src/io/hcg/index.js +27 -0
  81. simview/static/lib/chroma-js-3.1.2/src/io/hcg/rgb2hcg.js +23 -0
  82. simview/static/lib/chroma-js-3.1.2/src/io/hex/hex2rgb.js +56 -0
  83. simview/static/lib/chroma-js-3.1.2/src/io/hex/index.js +29 -0
  84. simview/static/lib/chroma-js-3.1.2/src/io/hex/rgb2hex.js +29 -0
  85. simview/static/lib/chroma-js-3.1.2/src/io/hsi/hsi2rgb.js +45 -0
  86. simview/static/lib/chroma-js-3.1.2/src/io/hsi/index.js +27 -0
  87. simview/static/lib/chroma-js-3.1.2/src/io/hsi/rgb2hsi.js +31 -0
  88. simview/static/lib/chroma-js-3.1.2/src/io/hsl/hsl2rgb.js +35 -0
  89. simview/static/lib/chroma-js-3.1.2/src/io/hsl/index.js +27 -0
  90. simview/static/lib/chroma-js-3.1.2/src/io/hsl/rgb2hsl.js +45 -0
  91. simview/static/lib/chroma-js-3.1.2/src/io/hsv/hsv2rgb.js +47 -0
  92. simview/static/lib/chroma-js-3.1.2/src/io/hsv/index.js +27 -0
  93. simview/static/lib/chroma-js-3.1.2/src/io/hsv/rgb2hsv.js +32 -0
  94. simview/static/lib/chroma-js-3.1.2/src/io/input.js +4 -0
  95. simview/static/lib/chroma-js-3.1.2/src/io/lab/index.js +28 -0
  96. simview/static/lib/chroma-js-3.1.2/src/io/lab/lab-constants.js +120 -0
  97. simview/static/lib/chroma-js-3.1.2/src/io/lab/lab2rgb.js +101 -0
  98. simview/static/lib/chroma-js-3.1.2/src/io/lab/rgb2lab.js +67 -0
  99. simview/static/lib/chroma-js-3.1.2/src/io/lch/hcl2rgb.js +9 -0
  100. simview/static/lib/chroma-js-3.1.2/src/io/lch/index.js +35 -0
  101. simview/static/lib/chroma-js-3.1.2/src/io/lch/lab2lch.js +12 -0
  102. simview/static/lib/chroma-js-3.1.2/src/io/lch/lch2lab.js +18 -0
  103. simview/static/lib/chroma-js-3.1.2/src/io/lch/lch2rgb.js +13 -0
  104. simview/static/lib/chroma-js-3.1.2/src/io/lch/rgb2lch.js +12 -0
  105. simview/static/lib/chroma-js-3.1.2/src/io/named/index.js +30 -0
  106. simview/static/lib/chroma-js-3.1.2/src/io/num/index.js +32 -0
  107. simview/static/lib/chroma-js-3.1.2/src/io/num/num2rgb.js +13 -0
  108. simview/static/lib/chroma-js-3.1.2/src/io/num/rgb2num.js +8 -0
  109. simview/static/lib/chroma-js-3.1.2/src/io/oklab/index.js +27 -0
  110. simview/static/lib/chroma-js-3.1.2/src/io/oklab/oklab2rgb.js +34 -0
  111. simview/static/lib/chroma-js-3.1.2/src/io/oklab/rgb2oklab.js +37 -0
  112. simview/static/lib/chroma-js-3.1.2/src/io/oklch/index.js +27 -0
  113. simview/static/lib/chroma-js-3.1.2/src/io/oklch/oklch2rgb.js +13 -0
  114. simview/static/lib/chroma-js-3.1.2/src/io/oklch/rgb2oklch.js +12 -0
  115. simview/static/lib/chroma-js-3.1.2/src/io/rgb/index.js +44 -0
  116. simview/static/lib/chroma-js-3.1.2/src/io/temp/index.js +22 -0
  117. simview/static/lib/chroma-js-3.1.2/src/io/temp/rgb2temperature.js +30 -0
  118. simview/static/lib/chroma-js-3.1.2/src/io/temp/temperature2rgb.js +39 -0
  119. simview/static/lib/chroma-js-3.1.2/src/ops/alpha.js +13 -0
  120. simview/static/lib/chroma-js-3.1.2/src/ops/clipped.js +5 -0
  121. simview/static/lib/chroma-js-3.1.2/src/ops/darken.js +17 -0
  122. simview/static/lib/chroma-js-3.1.2/src/ops/get.js +13 -0
  123. simview/static/lib/chroma-js-3.1.2/src/ops/luminance.js +54 -0
  124. simview/static/lib/chroma-js-3.1.2/src/ops/mix.js +10 -0
  125. simview/static/lib/chroma-js-3.1.2/src/ops/premultiply.js +12 -0
  126. simview/static/lib/chroma-js-3.1.2/src/ops/saturate.js +15 -0
  127. simview/static/lib/chroma-js-3.1.2/src/ops/set.js +43 -0
  128. simview/static/lib/chroma-js-3.1.2/src/ops/shade.js +11 -0
  129. simview/static/lib/chroma-js-3.1.2/src/utils/analyze.js +191 -0
  130. simview/static/lib/chroma-js-3.1.2/src/utils/clip_rgb.js +15 -0
  131. simview/static/lib/chroma-js-3.1.2/src/utils/contrast.js +12 -0
  132. simview/static/lib/chroma-js-3.1.2/src/utils/contrastAPCA.js +68 -0
  133. simview/static/lib/chroma-js-3.1.2/src/utils/delta-e.js +62 -0
  134. simview/static/lib/chroma-js-3.1.2/src/utils/distance.js +17 -0
  135. simview/static/lib/chroma-js-3.1.2/src/utils/index.js +27 -0
  136. simview/static/lib/chroma-js-3.1.2/src/utils/last.js +8 -0
  137. simview/static/lib/chroma-js-3.1.2/src/utils/limit.js +5 -0
  138. simview/static/lib/chroma-js-3.1.2/src/utils/multiply-matrices.js +36 -0
  139. simview/static/lib/chroma-js-3.1.2/src/utils/scales.js +15 -0
  140. simview/static/lib/chroma-js-3.1.2/src/utils/type.js +18 -0
  141. simview/static/lib/chroma-js-3.1.2/src/utils/unpack.js +17 -0
  142. simview/static/lib/chroma-js-3.1.2/src/utils/valid.js +11 -0
  143. simview/static/lib/chroma-js-3.1.2/src/version.js +2 -0
  144. simview/static/lib/download.js +132 -0
  145. simview/static/lib/js-colormaps.js +19335 -0
  146. simview/static/lib/tar.js +334 -0
  147. simview/static/lib/three-0.174.0/addons/controls/OrbitControls.js +1556 -0
  148. simview/static/lib/three-0.174.0/addons/libs/lil-gui.module.min.js +8 -0
  149. simview/static/lib/three-0.174.0/three.core.js +48830 -0
  150. simview/static/lib/three-0.174.0/three.module.js +17313 -0
  151. simview/static/lib/uPlot.esm.js +6140 -0
  152. simview/static/lib/uPlot.min.css +2 -0
  153. simview/static/textures/contacts/red-cross0.png +0 -0
  154. simview/static/textures/points/ball0.png +0 -0
  155. simview/static/textures/points/ball1.png +0 -0
  156. simview/templates/index.html +81 -0
  157. simview/utils.py +41 -0
  158. simview-3.2.dist-info/METADATA +552 -0
  159. simview-3.2.dist-info/RECORD +163 -0
  160. simview-3.2.dist-info/WHEEL +5 -0
  161. simview-3.2.dist-info/entry_points.txt +2 -0
  162. simview-3.2.dist-info/licenses/LICENSE +28 -0
  163. simview-3.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,191 @@
1
+ import type from './type.js';
2
+
3
+ const { log, pow, floor, abs } = Math;
4
+
5
+ export function analyze(data, key = null) {
6
+ const r = {
7
+ min: Number.MAX_VALUE,
8
+ max: Number.MAX_VALUE * -1,
9
+ sum: 0,
10
+ values: [],
11
+ count: 0
12
+ };
13
+ if (type(data) === 'object') {
14
+ data = Object.values(data);
15
+ }
16
+ data.forEach((val) => {
17
+ if (key && type(val) === 'object') val = val[key];
18
+ if (val !== undefined && val !== null && !isNaN(val)) {
19
+ r.values.push(val);
20
+ r.sum += val;
21
+ if (val < r.min) r.min = val;
22
+ if (val > r.max) r.max = val;
23
+ r.count += 1;
24
+ }
25
+ });
26
+
27
+ r.domain = [r.min, r.max];
28
+
29
+ r.limits = (mode, num) => limits(r, mode, num);
30
+
31
+ return r;
32
+ }
33
+
34
+ export function limits(data, mode = 'equal', num = 7) {
35
+ if (type(data) == 'array') {
36
+ data = analyze(data);
37
+ }
38
+ const { min, max } = data;
39
+ const values = data.values.sort((a, b) => a - b);
40
+
41
+ if (num === 1) {
42
+ return [min, max];
43
+ }
44
+
45
+ const limits = [];
46
+
47
+ if (mode.substr(0, 1) === 'c') {
48
+ // continuous
49
+ limits.push(min);
50
+ limits.push(max);
51
+ }
52
+
53
+ if (mode.substr(0, 1) === 'e') {
54
+ // equal interval
55
+ limits.push(min);
56
+ for (let i = 1; i < num; i++) {
57
+ limits.push(min + (i / num) * (max - min));
58
+ }
59
+ limits.push(max);
60
+ } else if (mode.substr(0, 1) === 'l') {
61
+ // log scale
62
+ if (min <= 0) {
63
+ throw new Error(
64
+ 'Logarithmic scales are only possible for values > 0'
65
+ );
66
+ }
67
+ const min_log = Math.LOG10E * log(min);
68
+ const max_log = Math.LOG10E * log(max);
69
+ limits.push(min);
70
+ for (let i = 1; i < num; i++) {
71
+ limits.push(pow(10, min_log + (i / num) * (max_log - min_log)));
72
+ }
73
+ limits.push(max);
74
+ } else if (mode.substr(0, 1) === 'q') {
75
+ // quantile scale
76
+ limits.push(min);
77
+ for (let i = 1; i < num; i++) {
78
+ const p = ((values.length - 1) * i) / num;
79
+ const pb = floor(p);
80
+ if (pb === p) {
81
+ limits.push(values[pb]);
82
+ } else {
83
+ // p > pb
84
+ const pr = p - pb;
85
+ limits.push(values[pb] * (1 - pr) + values[pb + 1] * pr);
86
+ }
87
+ }
88
+ limits.push(max);
89
+ } else if (mode.substr(0, 1) === 'k') {
90
+ // k-means clustering
91
+ /*
92
+ implementation based on
93
+ http://code.google.com/p/figue/source/browse/trunk/figue.js#336
94
+ simplified for 1-d input values
95
+ */
96
+ let cluster;
97
+ const n = values.length;
98
+ const assignments = new Array(n);
99
+ const clusterSizes = new Array(num);
100
+ let repeat = true;
101
+ let nb_iters = 0;
102
+ let centroids = null;
103
+
104
+ // get seed values
105
+ centroids = [];
106
+ centroids.push(min);
107
+ for (let i = 1; i < num; i++) {
108
+ centroids.push(min + (i / num) * (max - min));
109
+ }
110
+ centroids.push(max);
111
+
112
+ while (repeat) {
113
+ // assignment step
114
+ for (let j = 0; j < num; j++) {
115
+ clusterSizes[j] = 0;
116
+ }
117
+ for (let i = 0; i < n; i++) {
118
+ const value = values[i];
119
+ let mindist = Number.MAX_VALUE;
120
+ let best;
121
+ for (let j = 0; j < num; j++) {
122
+ const dist = abs(centroids[j] - value);
123
+ if (dist < mindist) {
124
+ mindist = dist;
125
+ best = j;
126
+ }
127
+ clusterSizes[best]++;
128
+ assignments[i] = best;
129
+ }
130
+ }
131
+
132
+ // update centroids step
133
+ const newCentroids = new Array(num);
134
+ for (let j = 0; j < num; j++) {
135
+ newCentroids[j] = null;
136
+ }
137
+ for (let i = 0; i < n; i++) {
138
+ cluster = assignments[i];
139
+ if (newCentroids[cluster] === null) {
140
+ newCentroids[cluster] = values[i];
141
+ } else {
142
+ newCentroids[cluster] += values[i];
143
+ }
144
+ }
145
+ for (let j = 0; j < num; j++) {
146
+ newCentroids[j] *= 1 / clusterSizes[j];
147
+ }
148
+
149
+ // check convergence
150
+ repeat = false;
151
+ for (let j = 0; j < num; j++) {
152
+ if (newCentroids[j] !== centroids[j]) {
153
+ repeat = true;
154
+ break;
155
+ }
156
+ }
157
+
158
+ centroids = newCentroids;
159
+ nb_iters++;
160
+
161
+ if (nb_iters > 200) {
162
+ repeat = false;
163
+ }
164
+ }
165
+
166
+ // finished k-means clustering
167
+ // the next part is borrowed from gabrielflor.it
168
+ const kClusters = {};
169
+ for (let j = 0; j < num; j++) {
170
+ kClusters[j] = [];
171
+ }
172
+ for (let i = 0; i < n; i++) {
173
+ cluster = assignments[i];
174
+ kClusters[cluster].push(values[i]);
175
+ }
176
+ let tmpKMeansBreaks = [];
177
+ for (let j = 0; j < num; j++) {
178
+ tmpKMeansBreaks.push(kClusters[j][0]);
179
+ tmpKMeansBreaks.push(kClusters[j][kClusters[j].length - 1]);
180
+ }
181
+ tmpKMeansBreaks = tmpKMeansBreaks.sort((a, b) => a - b);
182
+ limits.push(tmpKMeansBreaks[0]);
183
+ for (let i = 1; i < tmpKMeansBreaks.length; i += 2) {
184
+ const v = tmpKMeansBreaks[i];
185
+ if (!isNaN(v) && limits.indexOf(v) === -1) {
186
+ limits.push(v);
187
+ }
188
+ }
189
+ }
190
+ return limits;
191
+ }
@@ -0,0 +1,15 @@
1
+ import limit from './limit.js';
2
+
3
+ export default (rgb) => {
4
+ rgb._clipped = false;
5
+ rgb._unclipped = rgb.slice(0);
6
+ for (let i = 0; i <= 3; i++) {
7
+ if (i < 3) {
8
+ if (rgb[i] < 0 || rgb[i] > 255) rgb._clipped = true;
9
+ rgb[i] = limit(rgb[i], 0, 255);
10
+ } else if (i === 3) {
11
+ rgb[i] = limit(rgb[i], 0, 1);
12
+ }
13
+ }
14
+ return rgb;
15
+ };
@@ -0,0 +1,12 @@
1
+ import Color from '../Color.js';
2
+ import '../ops/luminance.js';
3
+
4
+ export default (a, b) => {
5
+ // WCAG contrast ratio
6
+ // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
7
+ a = new Color(a);
8
+ b = new Color(b);
9
+ const l1 = a.luminance();
10
+ const l2 = b.luminance();
11
+ return l1 > l2 ? (l1 + 0.05) / (l2 + 0.05) : (l2 + 0.05) / (l1 + 0.05);
12
+ };
@@ -0,0 +1,68 @@
1
+ import Color from '../Color.js';
2
+ import mix from '../generator/mix.js';
3
+
4
+ /**
5
+ * @license
6
+ *
7
+ * The APCA contrast prediction algorithm is based of the formulas published
8
+ * in the APCA-1.0.98G specification by Myndex. The specification is available at:
9
+ * https://raw.githubusercontent.com/Myndex/apca-w3/master/images/APCAw3_0.1.17_APCA0.0.98G.svg
10
+ *
11
+ * Note that the APCA implementation is still beta, so please update to
12
+ * future versions of chroma.js when they become available.
13
+ *
14
+ * You can read more about the APCA Readability Criterion at
15
+ * https://readtech.org/ARC/
16
+ */
17
+
18
+ // constants
19
+ const W_offset = 0.027;
20
+ const P_in = 0.0005;
21
+ const P_out = 0.1;
22
+ const R_scale = 1.14;
23
+ const B_threshold = 0.022;
24
+ const B_exp = 1.414;
25
+
26
+ export default (text, bg) => {
27
+ // parse input colors
28
+ text = new Color(text);
29
+ bg = new Color(bg);
30
+ // if text color has alpha, blend against background
31
+ if (text.alpha() < 1) {
32
+ text = mix(bg, text, text.alpha(), 'rgb');
33
+ }
34
+ const l_text = lum(...text.rgb());
35
+ const l_bg = lum(...bg.rgb());
36
+
37
+ // soft clamp black levels
38
+ const Y_text =
39
+ l_text >= B_threshold
40
+ ? l_text
41
+ : l_text + Math.pow(B_threshold - l_text, B_exp);
42
+ const Y_bg =
43
+ l_bg >= B_threshold ? l_bg : l_bg + Math.pow(B_threshold - l_bg, B_exp);
44
+
45
+ // normal polarity (dark text on light background)
46
+ const S_norm = Math.pow(Y_bg, 0.56) - Math.pow(Y_text, 0.57);
47
+ // reverse polarity (light text on dark background)
48
+ const S_rev = Math.pow(Y_bg, 0.65) - Math.pow(Y_text, 0.62);
49
+ // clamp noise then scale
50
+ const C =
51
+ Math.abs(Y_bg - Y_text) < P_in
52
+ ? 0
53
+ : Y_text < Y_bg
54
+ ? S_norm * R_scale
55
+ : S_rev * R_scale;
56
+ // clamp minimum contrast then offset
57
+ const S_apc = Math.abs(C) < P_out ? 0 : C > 0 ? C - W_offset : C + W_offset;
58
+ // scale to 100
59
+ return S_apc * 100;
60
+ };
61
+
62
+ function lum(r, g, b) {
63
+ return (
64
+ 0.2126729 * Math.pow(r / 255, 2.4) +
65
+ 0.7151522 * Math.pow(g / 255, 2.4) +
66
+ 0.072175 * Math.pow(b / 255, 2.4)
67
+ );
68
+ }
@@ -0,0 +1,62 @@
1
+ import Color from '../Color.js';
2
+ const { sqrt, pow, min, max, atan2, abs, cos, sin, exp, PI } = Math;
3
+
4
+ export default function (a, b, Kl = 1, Kc = 1, Kh = 1) {
5
+ // Delta E (CIE 2000)
6
+ // see http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CIE2000.html
7
+ var rad2deg = function (rad) {
8
+ return (360 * rad) / (2 * PI);
9
+ };
10
+ var deg2rad = function (deg) {
11
+ return (2 * PI * deg) / 360;
12
+ };
13
+ a = new Color(a);
14
+ b = new Color(b);
15
+ const [L1, a1, b1] = Array.from(a.lab());
16
+ const [L2, a2, b2] = Array.from(b.lab());
17
+ const avgL = (L1 + L2) / 2;
18
+ const C1 = sqrt(pow(a1, 2) + pow(b1, 2));
19
+ const C2 = sqrt(pow(a2, 2) + pow(b2, 2));
20
+ const avgC = (C1 + C2) / 2;
21
+ const G = 0.5 * (1 - sqrt(pow(avgC, 7) / (pow(avgC, 7) + pow(25, 7))));
22
+ const a1p = a1 * (1 + G);
23
+ const a2p = a2 * (1 + G);
24
+ const C1p = sqrt(pow(a1p, 2) + pow(b1, 2));
25
+ const C2p = sqrt(pow(a2p, 2) + pow(b2, 2));
26
+ const avgCp = (C1p + C2p) / 2;
27
+ const arctan1 = rad2deg(atan2(b1, a1p));
28
+ const arctan2 = rad2deg(atan2(b2, a2p));
29
+ const h1p = arctan1 >= 0 ? arctan1 : arctan1 + 360;
30
+ const h2p = arctan2 >= 0 ? arctan2 : arctan2 + 360;
31
+ const avgHp =
32
+ abs(h1p - h2p) > 180 ? (h1p + h2p + 360) / 2 : (h1p + h2p) / 2;
33
+ const T =
34
+ 1 -
35
+ 0.17 * cos(deg2rad(avgHp - 30)) +
36
+ 0.24 * cos(deg2rad(2 * avgHp)) +
37
+ 0.32 * cos(deg2rad(3 * avgHp + 6)) -
38
+ 0.2 * cos(deg2rad(4 * avgHp - 63));
39
+ let deltaHp = h2p - h1p;
40
+ deltaHp =
41
+ abs(deltaHp) <= 180
42
+ ? deltaHp
43
+ : h2p <= h1p
44
+ ? deltaHp + 360
45
+ : deltaHp - 360;
46
+ deltaHp = 2 * sqrt(C1p * C2p) * sin(deg2rad(deltaHp) / 2);
47
+ const deltaL = L2 - L1;
48
+ const deltaCp = C2p - C1p;
49
+ const sl = 1 + (0.015 * pow(avgL - 50, 2)) / sqrt(20 + pow(avgL - 50, 2));
50
+ const sc = 1 + 0.045 * avgCp;
51
+ const sh = 1 + 0.015 * avgCp * T;
52
+ const deltaTheta = 30 * exp(-pow((avgHp - 275) / 25, 2));
53
+ const Rc = 2 * sqrt(pow(avgCp, 7) / (pow(avgCp, 7) + pow(25, 7)));
54
+ const Rt = -Rc * sin(2 * deg2rad(deltaTheta));
55
+ const result = sqrt(
56
+ pow(deltaL / (Kl * sl), 2) +
57
+ pow(deltaCp / (Kc * sc), 2) +
58
+ pow(deltaHp / (Kh * sh), 2) +
59
+ Rt * (deltaCp / (Kc * sc)) * (deltaHp / (Kh * sh))
60
+ );
61
+ return max(0, min(100, result));
62
+ }
@@ -0,0 +1,17 @@
1
+ import Color from '../Color.js';
2
+
3
+ // simple Euclidean distance
4
+ export default function (a, b, mode = 'lab') {
5
+ // Delta E (CIE 1976)
6
+ // see http://www.brucelindbloom.com/index.html?Equations.html
7
+ a = new Color(a);
8
+ b = new Color(b);
9
+ const l1 = a.get(mode);
10
+ const l2 = b.get(mode);
11
+ let sum_sq = 0;
12
+ for (let i in l1) {
13
+ const d = (l1[i] || 0) - (l2[i] || 0);
14
+ sum_sq += d * d;
15
+ }
16
+ return Math.sqrt(sum_sq);
17
+ }
@@ -0,0 +1,27 @@
1
+ const { PI, min, max } = Math;
2
+
3
+ const rnd2 = (a) => Math.round(a * 100) / 100;
4
+ const rnd3 = (a) => Math.round(a * 100) / 100;
5
+
6
+ export { default as clip_rgb } from './clip_rgb.js';
7
+ export { default as limit } from './limit.js';
8
+ export { default as type } from './type.js';
9
+ export { default as unpack } from './unpack.js';
10
+ export { default as last } from './last.js';
11
+
12
+ const TWOPI = PI * 2;
13
+ const PITHIRD = PI / 3;
14
+ const DEG2RAD = PI / 180;
15
+ const RAD2DEG = 180 / PI;
16
+
17
+ /**
18
+ * Reverse the first three elements of an array
19
+ *
20
+ * @param {any[]} arr
21
+ * @returns {any[]}
22
+ */
23
+ function reverse3(arr) {
24
+ return [...arr.slice(0, 3).reverse(), ...arr.slice(3)];
25
+ }
26
+
27
+ export { PI, TWOPI, PITHIRD, DEG2RAD, RAD2DEG, min, max, rnd2, rnd3, reverse3 };
@@ -0,0 +1,8 @@
1
+ import type from './type.js';
2
+
3
+ export default (args) => {
4
+ if (args.length < 2) return null;
5
+ const l = args.length - 1;
6
+ if (type(args[l]) == 'string') return args[l].toLowerCase();
7
+ return null;
8
+ };
@@ -0,0 +1,5 @@
1
+ const { min, max } = Math;
2
+
3
+ export default (x, low = 0, high = 1) => {
4
+ return min(max(low, x), high);
5
+ };
@@ -0,0 +1,36 @@
1
+ // from https://www.w3.org/TR/css-color-4/multiply-matrices.js
2
+ export default function multiplyMatrices(A, B) {
3
+ let m = A.length;
4
+
5
+ if (!Array.isArray(A[0])) {
6
+ // A is vector, convert to [[a, b, c, ...]]
7
+ A = [A];
8
+ }
9
+
10
+ if (!Array.isArray(B[0])) {
11
+ // B is vector, convert to [[a], [b], [c], ...]]
12
+ B = B.map((x) => [x]);
13
+ }
14
+
15
+ let p = B[0].length;
16
+ let B_cols = B[0].map((_, i) => B.map((x) => x[i])); // transpose B
17
+ let product = A.map((row) =>
18
+ B_cols.map((col) => {
19
+ if (!Array.isArray(row)) {
20
+ return col.reduce((a, c) => a + c * row, 0);
21
+ }
22
+
23
+ return row.reduce((a, c, i) => a + c * (col[i] || 0), 0);
24
+ })
25
+ );
26
+
27
+ if (m === 1) {
28
+ product = product[0]; // Avoid [[a, b, c, ...]]
29
+ }
30
+
31
+ if (p === 1) {
32
+ return product.map((x) => x[0]); // Avoid [[a], [b], [c], ...]]
33
+ }
34
+
35
+ return product;
36
+ }
@@ -0,0 +1,15 @@
1
+ // some pre-defined color scales:
2
+ import chroma from '../chroma.js';
3
+ import '../io/hsl/index.js';
4
+ import scale from '../generator/scale.js';
5
+
6
+ export default {
7
+ cool() {
8
+ return scale([chroma.hsl(180, 1, 0.9), chroma.hsl(250, 0.7, 0.4)]);
9
+ },
10
+ hot() {
11
+ return scale(['#000', '#f00', '#ff0', '#fff'], [0, 0.25, 0.75, 1]).mode(
12
+ 'rgb'
13
+ );
14
+ }
15
+ };
@@ -0,0 +1,18 @@
1
+ // ported from jQuery's $.type
2
+ const classToType = {};
3
+ for (let name of [
4
+ 'Boolean',
5
+ 'Number',
6
+ 'String',
7
+ 'Function',
8
+ 'Array',
9
+ 'Date',
10
+ 'RegExp',
11
+ 'Undefined',
12
+ 'Null'
13
+ ]) {
14
+ classToType[`[object ${name}]`] = name.toLowerCase();
15
+ }
16
+ export default function (obj) {
17
+ return classToType[Object.prototype.toString.call(obj)] || 'object';
18
+ }
@@ -0,0 +1,17 @@
1
+ import type from './type.js';
2
+
3
+ export default (args, keyOrder = null) => {
4
+ // if called with more than 3 arguments, we return the arguments
5
+ if (args.length >= 3) return Array.prototype.slice.call(args);
6
+ // with less than 3 args we check if first arg is object
7
+ // and use the keyOrder string to extract and sort properties
8
+ if (type(args[0]) == 'object' && keyOrder) {
9
+ return keyOrder
10
+ .split('')
11
+ .filter((k) => args[0][k] !== undefined)
12
+ .map((k) => args[0][k]);
13
+ }
14
+ // otherwise we just return the first argument
15
+ // (which we suppose is an array of args)
16
+ return args[0].slice(0);
17
+ };
@@ -0,0 +1,11 @@
1
+ import Color from '../Color.js';
2
+
3
+ export default (...args) => {
4
+ try {
5
+ new Color(...args);
6
+ return true;
7
+ // eslint-disable-next-line
8
+ } catch (e) {
9
+ return false;
10
+ }
11
+ };
@@ -0,0 +1,2 @@
1
+ // this gets updated automatically
2
+ export const version = '3.1.2';
@@ -0,0 +1,132 @@
1
+ //download.js v3.0, by dandavis; 2008-2014. [CCBY2] see http://danml.com/download.html for tests/usage
2
+ // v1 landed a FF+Chrome compat way of downloading strings to local un-named files, upgraded to use a hidden frame and optional mime
3
+ // v2 added named files via a[download], msSaveBlob, IE (10+) support, and window.URL support for larger+faster saves than dataURLs
4
+ // v3 added dataURL and Blob Input, bind-toggle arity, and legacy dataURL fallback was improved with force-download mime and base64 support
5
+
6
+ // data can be a string, Blob, File, or dataURL
7
+
8
+
9
+
10
+
11
+ function download(data, strFileName, strMimeType) {
12
+
13
+ var self = window, // this script is only for browsers anyway...
14
+ u = "application/octet-stream", // this default mime also triggers iframe downloads
15
+ m = strMimeType || u,
16
+ x = data,
17
+ D = document,
18
+ a = D.createElement("a"),
19
+ z = function(a){return String(a);},
20
+
21
+
22
+ B = self.Blob || self.MozBlob || self.WebKitBlob || z,
23
+ BB = self.MSBlobBuilder || self.WebKitBlobBuilder || self.BlobBuilder,
24
+ fn = strFileName || "download",
25
+ blob,
26
+ b,
27
+ ua,
28
+ fr;
29
+
30
+ //if(typeof B.bind === 'function' ){ B=B.bind(self); }
31
+
32
+ if(String(this)==="true"){ //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
33
+ x=[x, m];
34
+ m=x[0];
35
+ x=x[1];
36
+ }
37
+
38
+
39
+
40
+ //go ahead and download dataURLs right away
41
+ if(String(x).match(/^data\:[\w+\-]+\/[\w+\-]+[,;]/)){
42
+ return navigator.msSaveBlob ? // IE10 can't do a[download], only Blobs:
43
+ navigator.msSaveBlob(d2b(x), fn) :
44
+ saver(x) ; // everyone else can save dataURLs un-processed
45
+ }//end if dataURL passed?
46
+
47
+ try{
48
+
49
+ blob = x instanceof B ?
50
+ x :
51
+ new B([x], {type: m}) ;
52
+ }catch(y){
53
+ if(BB){
54
+ b = new BB();
55
+ b.append([x]);
56
+ blob = b.getBlob(m); // the blob
57
+ }
58
+
59
+ }
60
+
61
+
62
+
63
+ function d2b(u) {
64
+ var p= u.split(/[:;,]/),
65
+ t= p[1],
66
+ dec= p[2] == "base64" ? atob : decodeURIComponent,
67
+ bin= dec(p.pop()),
68
+ mx= bin.length,
69
+ i= 0,
70
+ uia= new Uint8Array(mx);
71
+
72
+ for(i;i<mx;++i) uia[i]= bin.charCodeAt(i);
73
+
74
+ return new B([uia], {type: t});
75
+ }
76
+
77
+ function saver(url, winMode){
78
+
79
+
80
+ if ('download' in a) { //html5 A[download]
81
+ a.href = url;
82
+ a.setAttribute("download", fn);
83
+ a.innerHTML = "downloading...";
84
+ a.style.display = 'none';
85
+ D.body.appendChild(a);
86
+ setTimeout(function() {
87
+ a.click();
88
+ D.body.removeChild(a);
89
+ if(winMode===true){setTimeout(function(){ self.URL.revokeObjectURL(a.href);}, 250 );}
90
+ }, 66);
91
+ return true;
92
+ }
93
+
94
+ //do iframe dataURL download (old ch+FF):
95
+ var f = D.createElement("iframe");
96
+ D.body.appendChild(f);
97
+ if(!winMode){ // force a mime that will download:
98
+ url="data:"+url.replace(/^data:([\w\/\-\+]+)/, u);
99
+ }
100
+
101
+
102
+ f.src = url;
103
+ setTimeout(function(){ D.body.removeChild(f); }, 333);
104
+
105
+ }//end saver
106
+
107
+
108
+ if (navigator.msSaveBlob) { // IE10+ : (has Blob, but not a[download] or URL)
109
+ return navigator.msSaveBlob(blob, fn);
110
+ }
111
+
112
+ if(self.URL){ // simple fast and modern way using Blob and URL:
113
+ saver(self.URL.createObjectURL(blob), true);
114
+ }else{
115
+ // handle non-Blob()+non-URL browsers:
116
+ if(typeof blob === "string" || blob.constructor===z ){
117
+ try{
118
+ return saver( "data:" + m + ";base64," + self.btoa(blob) );
119
+ }catch(y){
120
+ return saver( "data:" + m + "," + encodeURIComponent(blob) );
121
+ }
122
+ }
123
+
124
+ // Blob but not URL:
125
+ fr=new FileReader();
126
+ fr.onload=function(e){
127
+ saver(this.result);
128
+ };
129
+ fr.readAsDataURL(blob);
130
+ }
131
+ return true;
132
+ } /* end download() */