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,238 @@
1
+ import hsl2rgb from '../hsl/hsl2rgb.js';
2
+ import lab2rgb from '../lab/lab2rgb.js';
3
+ import lch2rgb from '../lch/lch2rgb.js';
4
+ import oklab2rgb from '../oklab/oklab2rgb.js';
5
+ import oklch2rgb from '../oklch/oklch2rgb.js';
6
+ import input from '../input.js';
7
+ import limit from '../../utils/limit.js';
8
+ import { getLabWhitePoint, setLabWhitePoint } from '../lab/lab-constants.js';
9
+
10
+ const INT_OR_PCT = /((?:-?\d+)|(?:-?\d+(?:\.\d+)?)%|none)/.source;
11
+ const FLOAT_OR_PCT = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)%?)|none)/.source;
12
+ const PCT = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)%)|none)/.source;
13
+ const RE_S = /\s*/.source;
14
+ const SEP = /\s+/.source;
15
+ const COMMA = /\s*,\s*/.source;
16
+ const ANLGE = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)(?:deg)?)|none)/.source;
17
+ const ALPHA = /\s*(?:\/\s*((?:[01]|[01]?\.\d+)|\d+(?:\.\d+)?%))?/.source;
18
+
19
+ // e.g. rgb(250 20 0), rgb(100% 50% 20%), rgb(100% 50% 20% / 0.5)
20
+ const RE_RGB = new RegExp(
21
+ '^rgba?\\(' +
22
+ RE_S +
23
+ [INT_OR_PCT, INT_OR_PCT, INT_OR_PCT].join(SEP) +
24
+ ALPHA +
25
+ '\\)$'
26
+ );
27
+ const RE_RGB_LEGACY = new RegExp(
28
+ '^rgb\\(' +
29
+ RE_S +
30
+ [INT_OR_PCT, INT_OR_PCT, INT_OR_PCT].join(COMMA) +
31
+ RE_S +
32
+ '\\)$'
33
+ );
34
+ const RE_RGBA_LEGACY = new RegExp(
35
+ '^rgba\\(' +
36
+ RE_S +
37
+ [INT_OR_PCT, INT_OR_PCT, INT_OR_PCT, FLOAT_OR_PCT].join(COMMA) +
38
+ RE_S +
39
+ '\\)$'
40
+ );
41
+
42
+ const RE_HSL = new RegExp(
43
+ '^hsla?\\(' + RE_S + [ANLGE, PCT, PCT].join(SEP) + ALPHA + '\\)$'
44
+ );
45
+ const RE_HSL_LEGACY = new RegExp(
46
+ '^hsl?\\(' + RE_S + [ANLGE, PCT, PCT].join(COMMA) + RE_S + '\\)$'
47
+ );
48
+ const RE_HSLA_LEGACY =
49
+ /^hsla\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/;
50
+
51
+ const RE_LAB = new RegExp(
52
+ '^lab\\(' +
53
+ RE_S +
54
+ [FLOAT_OR_PCT, FLOAT_OR_PCT, FLOAT_OR_PCT].join(SEP) +
55
+ ALPHA +
56
+ '\\)$'
57
+ );
58
+ const RE_LCH = new RegExp(
59
+ '^lch\\(' +
60
+ RE_S +
61
+ [FLOAT_OR_PCT, FLOAT_OR_PCT, ANLGE].join(SEP) +
62
+ ALPHA +
63
+ '\\)$'
64
+ );
65
+ const RE_OKLAB = new RegExp(
66
+ '^oklab\\(' +
67
+ RE_S +
68
+ [FLOAT_OR_PCT, FLOAT_OR_PCT, FLOAT_OR_PCT].join(SEP) +
69
+ ALPHA +
70
+ '\\)$'
71
+ );
72
+ const RE_OKLCH = new RegExp(
73
+ '^oklch\\(' +
74
+ RE_S +
75
+ [FLOAT_OR_PCT, FLOAT_OR_PCT, ANLGE].join(SEP) +
76
+ ALPHA +
77
+ '\\)$'
78
+ );
79
+
80
+ const { round } = Math;
81
+
82
+ const roundRGB = (rgb) => {
83
+ return rgb.map((v, i) => (i <= 2 ? limit(round(v), 0, 255) : v));
84
+ };
85
+
86
+ const percentToAbsolute = (pct, min = 0, max = 100, signed = false) => {
87
+ if (typeof pct === 'string' && pct.endsWith('%')) {
88
+ pct = parseFloat(pct.substring(0, pct.length - 1)) / 100;
89
+ if (signed) {
90
+ // signed percentages are in the range -100% to 100%
91
+ pct = min + (pct + 1) * 0.5 * (max - min);
92
+ } else {
93
+ pct = min + pct * (max - min);
94
+ }
95
+ }
96
+ return +pct;
97
+ };
98
+
99
+ const noneToValue = (v, noneValue) => {
100
+ return v === 'none' ? noneValue : v;
101
+ };
102
+
103
+ const css2rgb = (css) => {
104
+ css = css.toLowerCase().trim();
105
+
106
+ if (css === 'transparent') {
107
+ return [0, 0, 0, 0];
108
+ }
109
+
110
+ let m;
111
+
112
+ if (input.format.named) {
113
+ try {
114
+ return input.format.named(css);
115
+ // eslint-disable-next-line
116
+ } catch (e) {}
117
+ }
118
+
119
+ // rgb(250 20 0) or rgb(250,20,0)
120
+ if ((m = css.match(RE_RGB)) || (m = css.match(RE_RGB_LEGACY))) {
121
+ let rgb = m.slice(1, 4);
122
+ for (let i = 0; i < 3; i++) {
123
+ rgb[i] = +percentToAbsolute(noneToValue(rgb[i], 0), 0, 255);
124
+ }
125
+ rgb = roundRGB(rgb);
126
+ const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
127
+ rgb[3] = alpha; // default alpha
128
+ return rgb;
129
+ }
130
+
131
+ // rgba(250,20,0,0.4)
132
+ if ((m = css.match(RE_RGBA_LEGACY))) {
133
+ const rgb = m.slice(1, 5);
134
+ for (let i = 0; i < 4; i++) {
135
+ rgb[i] = +percentToAbsolute(rgb[i], 0, 255);
136
+ }
137
+ return rgb;
138
+ }
139
+
140
+ // hsl(0,100%,50%)
141
+ if ((m = css.match(RE_HSL)) || (m = css.match(RE_HSL_LEGACY))) {
142
+ const hsl = m.slice(1, 4);
143
+ hsl[0] = +noneToValue(hsl[0].replace('deg', ''), 0);
144
+ hsl[1] = +percentToAbsolute(noneToValue(hsl[1], 0), 0, 100) * 0.01;
145
+ hsl[2] = +percentToAbsolute(noneToValue(hsl[2], 0), 0, 100) * 0.01;
146
+ const rgb = roundRGB(hsl2rgb(hsl));
147
+ const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
148
+ rgb[3] = alpha;
149
+ return rgb;
150
+ }
151
+
152
+ // hsla(0,100%,50%,0.5)
153
+ if ((m = css.match(RE_HSLA_LEGACY))) {
154
+ const hsl = m.slice(1, 4);
155
+ hsl[1] *= 0.01;
156
+ hsl[2] *= 0.01;
157
+ const rgb = hsl2rgb(hsl);
158
+ for (let i = 0; i < 3; i++) {
159
+ rgb[i] = round(rgb[i]);
160
+ }
161
+ rgb[3] = +m[4]; // default alpha = 1
162
+ return rgb;
163
+ }
164
+
165
+ if ((m = css.match(RE_LAB))) {
166
+ const lab = m.slice(1, 4);
167
+ lab[0] = percentToAbsolute(noneToValue(lab[0], 0), 0, 100);
168
+ lab[1] = percentToAbsolute(noneToValue(lab[1], 0), -125, 125, true);
169
+ lab[2] = percentToAbsolute(noneToValue(lab[2], 0), -125, 125, true);
170
+ // convert to D50 Lab whitepoint
171
+ const wp = getLabWhitePoint();
172
+ setLabWhitePoint('d50');
173
+ const rgb = roundRGB(lab2rgb(lab));
174
+ // convert back to original Lab whitepoint
175
+ setLabWhitePoint(wp);
176
+ const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
177
+ rgb[3] = alpha;
178
+ return rgb;
179
+ }
180
+
181
+ if ((m = css.match(RE_LCH))) {
182
+ const lch = m.slice(1, 4);
183
+ lch[0] = percentToAbsolute(lch[0], 0, 100);
184
+ lch[1] = percentToAbsolute(noneToValue(lch[1], 0), 0, 150, false);
185
+ lch[2] = +noneToValue(lch[2].replace('deg', ''), 0);
186
+ // convert to D50 Lab whitepoint
187
+ const wp = getLabWhitePoint();
188
+ setLabWhitePoint('d50');
189
+ const rgb = roundRGB(lch2rgb(lch));
190
+ // convert back to original Lab whitepoint
191
+ setLabWhitePoint(wp);
192
+ const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
193
+ rgb[3] = alpha;
194
+ return rgb;
195
+ }
196
+
197
+ if ((m = css.match(RE_OKLAB))) {
198
+ const oklab = m.slice(1, 4);
199
+ oklab[0] = percentToAbsolute(noneToValue(oklab[0], 0), 0, 1);
200
+ oklab[1] = percentToAbsolute(noneToValue(oklab[1], 0), -0.4, 0.4, true);
201
+ oklab[2] = percentToAbsolute(noneToValue(oklab[2], 0), -0.4, 0.4, true);
202
+ const rgb = roundRGB(oklab2rgb(oklab));
203
+ const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
204
+ rgb[3] = alpha;
205
+ return rgb;
206
+ }
207
+
208
+ if ((m = css.match(RE_OKLCH))) {
209
+ const oklch = m.slice(1, 4);
210
+ oklch[0] = percentToAbsolute(noneToValue(oklch[0], 0), 0, 1);
211
+ oklch[1] = percentToAbsolute(noneToValue(oklch[1], 0), 0, 0.4, false);
212
+ oklch[2] = +noneToValue(oklch[2].replace('deg', ''), 0);
213
+ const rgb = roundRGB(oklch2rgb(oklch));
214
+ const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
215
+ rgb[3] = alpha;
216
+ return rgb;
217
+ }
218
+ };
219
+
220
+ css2rgb.test = (s) => {
221
+ return (
222
+ // modern
223
+ RE_RGB.test(s) ||
224
+ RE_HSL.test(s) ||
225
+ RE_LAB.test(s) ||
226
+ RE_LCH.test(s) ||
227
+ RE_OKLAB.test(s) ||
228
+ RE_OKLCH.test(s) ||
229
+ // legacy
230
+ RE_RGB_LEGACY.test(s) ||
231
+ RE_RGBA_LEGACY.test(s) ||
232
+ RE_HSL_LEGACY.test(s) ||
233
+ RE_HSLA_LEGACY.test(s) ||
234
+ s === 'transparent'
235
+ );
236
+ };
237
+
238
+ export default css2rgb;
@@ -0,0 +1,26 @@
1
+ import { unpack, last, rnd2 } from '../../utils/index.js';
2
+
3
+ /*
4
+ * supported arguments:
5
+ * - hsl2css(h,s,l)
6
+ * - hsl2css(h,s,l,a)
7
+ * - hsl2css([h,s,l], mode)
8
+ * - hsl2css([h,s,l,a], mode)
9
+ * - hsl2css({h,s,l,a}, mode)
10
+ */
11
+ const hsl2css = (...args) => {
12
+ const hsla = unpack(args, 'hsla');
13
+ let mode = last(args) || 'lsa';
14
+ hsla[0] = rnd2(hsla[0] || 0) + 'deg';
15
+ hsla[1] = rnd2(hsla[1] * 100) + '%';
16
+ hsla[2] = rnd2(hsla[2] * 100) + '%';
17
+ if (mode === 'hsla' || (hsla.length > 3 && hsla[3] < 1)) {
18
+ hsla[3] = '/ ' + (hsla.length > 3 ? hsla[3] : 1);
19
+ mode = 'hsla';
20
+ } else {
21
+ hsla.length = 3;
22
+ }
23
+ return `${mode.substr(0, 3)}(${hsla.join(' ')})`;
24
+ };
25
+
26
+ export default hsl2css;
@@ -0,0 +1,27 @@
1
+ import chroma from '../../chroma.js';
2
+ import Color from '../../Color.js';
3
+ import input from '../input.js';
4
+ import { type } from '../../utils/index.js';
5
+
6
+ import rgb2css from './rgb2css.js';
7
+ import css2rgb from './css2rgb.js';
8
+
9
+ Color.prototype.css = function (mode) {
10
+ return rgb2css(this._rgb, mode);
11
+ };
12
+
13
+ const css = (...args) => new Color(...args, 'css');
14
+ chroma.css = css;
15
+
16
+ input.format.css = css2rgb;
17
+
18
+ input.autodetect.push({
19
+ p: 5,
20
+ test: (h, ...rest) => {
21
+ if (!rest.length && type(h) === 'string' && css2rgb.test(h)) {
22
+ return 'css';
23
+ }
24
+ }
25
+ });
26
+
27
+ export { css };
@@ -0,0 +1,24 @@
1
+ import { unpack, last, rnd2 } from '../../utils/index.js';
2
+
3
+ /*
4
+ * supported arguments:
5
+ * - lab2css(l,a,b)
6
+ * - lab2css(l,a,b,alpha)
7
+ * - lab2css([l,a,b], mode)
8
+ * - lab2css([l,a,b,alpha], mode)
9
+ */
10
+ const lab2css = (...args) => {
11
+ const laba = unpack(args, 'lab');
12
+ let mode = last(args) || 'lab';
13
+ laba[0] = rnd2(laba[0]) + '%';
14
+ laba[1] = rnd2(laba[1]);
15
+ laba[2] = rnd2(laba[2]);
16
+ if (mode === 'laba' || (laba.length > 3 && laba[3] < 1)) {
17
+ laba[3] = '/ ' + (laba.length > 3 ? laba[3] : 1);
18
+ } else {
19
+ laba.length = 3;
20
+ }
21
+ return `lab(${laba.join(' ')})`;
22
+ };
23
+
24
+ export default lab2css;
@@ -0,0 +1,24 @@
1
+ import { unpack, last, rnd2 } from '../../utils/index.js';
2
+
3
+ /*
4
+ * supported arguments:
5
+ * - lab2css(l,a,b)
6
+ * - lab2css(l,a,b,alpha)
7
+ * - lab2css([l,a,b], mode)
8
+ * - lab2css([l,a,b,alpha], mode)
9
+ */
10
+ const lch2css = (...args) => {
11
+ const lcha = unpack(args, 'lch');
12
+ let mode = last(args) || 'lab';
13
+ lcha[0] = rnd2(lcha[0]) + '%';
14
+ lcha[1] = rnd2(lcha[1]);
15
+ lcha[2] = isNaN(lcha[2]) ? 'none' : rnd2(lcha[2]) + 'deg'; // add deg unit to hue
16
+ if (mode === 'lcha' || (lcha.length > 3 && lcha[3] < 1)) {
17
+ lcha[3] = '/ ' + (lcha.length > 3 ? lcha[3] : 1);
18
+ } else {
19
+ lcha.length = 3;
20
+ }
21
+ return `lch(${lcha.join(' ')})`;
22
+ };
23
+
24
+ export default lch2css;
@@ -0,0 +1,16 @@
1
+ import { unpack, rnd2, rnd3 } from '../../utils/index.js';
2
+
3
+ const oklab2css = (...args) => {
4
+ const laba = unpack(args, 'lab');
5
+ laba[0] = rnd2(laba[0] * 100) + '%';
6
+ laba[1] = rnd3(laba[1]);
7
+ laba[2] = rnd3(laba[2]);
8
+ if (laba.length > 3 && laba[3] < 1) {
9
+ laba[3] = '/ ' + (laba.length > 3 ? laba[3] : 1);
10
+ } else {
11
+ laba.length = 3;
12
+ }
13
+ return `oklab(${laba.join(' ')})`;
14
+ };
15
+
16
+ export default oklab2css;
@@ -0,0 +1,16 @@
1
+ import { unpack, rnd2, rnd3 } from '../../utils/index.js';
2
+
3
+ const oklch2css = (...args) => {
4
+ const lcha = unpack(args, 'lch');
5
+ lcha[0] = rnd2(lcha[0] * 100) + '%';
6
+ lcha[1] = rnd3(lcha[1]);
7
+ lcha[2] = isNaN(lcha[2]) ? 'none' : rnd2(lcha[2]) + 'deg'; // add deg unit to hue
8
+ if (lcha.length > 3 && lcha[3] < 1) {
9
+ lcha[3] = '/ ' + (lcha.length > 3 ? lcha[3] : 1);
10
+ } else {
11
+ lcha.length = 3;
12
+ }
13
+ return `oklch(${lcha.join(' ')})`;
14
+ };
15
+
16
+ export default oklch2css;
@@ -0,0 +1,61 @@
1
+ import { unpack, last } from '../../utils/index.js';
2
+ import hsl2css from './hsl2css.js';
3
+ import rgb2hsl from '../hsl/rgb2hsl.js';
4
+ import lab2css from './lab2css.js';
5
+ import rgb2lab from '../lab/rgb2lab.js';
6
+ import lch2css from './lch2css.js';
7
+ import rgb2lch from '../lch/rgb2lch.js';
8
+ import rgb2oklab from '../oklab/rgb2oklab.js';
9
+ import oklab2css from './oklab2css.js';
10
+ import rgb2oklch from '../oklch/rgb2oklch.js';
11
+ import oklch2css from './oklch2css.js';
12
+ import { getLabWhitePoint, setLabWhitePoint } from '../lab/lab-constants.js';
13
+ const { round } = Math;
14
+
15
+ /*
16
+ * supported arguments:
17
+ * - rgb2css(r,g,b)
18
+ * - rgb2css(r,g,b,a)
19
+ * - rgb2css([r,g,b], mode)
20
+ * - rgb2css([r,g,b,a], mode)
21
+ * - rgb2css({r,g,b,a}, mode)
22
+ */
23
+ const rgb2css = (...args) => {
24
+ const rgba = unpack(args, 'rgba');
25
+ let mode = last(args) || 'rgb';
26
+ if (mode.substr(0, 3) === 'hsl') {
27
+ return hsl2css(rgb2hsl(rgba), mode);
28
+ }
29
+ if (mode.substr(0, 3) === 'lab') {
30
+ // change to D50 lab whitepoint since this is what W3C is using for CSS Lab colors
31
+ const prevWhitePoint = getLabWhitePoint();
32
+ setLabWhitePoint('d50');
33
+ const cssColor = lab2css(rgb2lab(rgba), mode);
34
+ setLabWhitePoint(prevWhitePoint);
35
+ return cssColor;
36
+ }
37
+ if (mode.substr(0, 3) === 'lch') {
38
+ // change to D50 lab whitepoint since this is what W3C is using for CSS Lab colors
39
+ const prevWhitePoint = getLabWhitePoint();
40
+ setLabWhitePoint('d50');
41
+ const cssColor = lch2css(rgb2lch(rgba), mode);
42
+ setLabWhitePoint(prevWhitePoint);
43
+ return cssColor;
44
+ }
45
+ if (mode.substr(0, 5) === 'oklab') {
46
+ return oklab2css(rgb2oklab(rgba));
47
+ }
48
+ if (mode.substr(0, 5) === 'oklch') {
49
+ return oklch2css(rgb2oklch(rgba));
50
+ }
51
+ rgba[0] = round(rgba[0]);
52
+ rgba[1] = round(rgba[1]);
53
+ rgba[2] = round(rgba[2]);
54
+ if (mode === 'rgba' || (rgba.length > 3 && rgba[3] < 1)) {
55
+ rgba[3] = '/ ' + (rgba.length > 3 ? rgba[3] : 1);
56
+ mode = 'rgba';
57
+ }
58
+ return `${mode.substr(0, 3)}(${rgba.slice(0, mode === 'rgb' ? 3 : 4).join(' ')})`;
59
+ };
60
+
61
+ export default rgb2css;
@@ -0,0 +1,22 @@
1
+ import Color from '../../Color.js';
2
+ import chroma from '../../chroma.js';
3
+ import input from '../input.js';
4
+ import { unpack } from '../../utils/index.js';
5
+
6
+ input.format.gl = (...args) => {
7
+ const rgb = unpack(args, 'rgba');
8
+ rgb[0] *= 255;
9
+ rgb[1] *= 255;
10
+ rgb[2] *= 255;
11
+ return rgb;
12
+ };
13
+
14
+ const gl = (...args) => new Color(...args, 'gl');
15
+ chroma.gl = gl;
16
+
17
+ Color.prototype.gl = function () {
18
+ const rgb = this._rgb;
19
+ return [rgb[0] / 255, rgb[1] / 255, rgb[2] / 255, rgb[3]];
20
+ };
21
+
22
+ export { gl };
@@ -0,0 +1,55 @@
1
+ import { unpack } from '../../utils/index.js';
2
+ const { floor } = Math;
3
+
4
+ /*
5
+ * this is basically just HSV with some minor tweaks
6
+ *
7
+ * hue.. [0..360]
8
+ * chroma .. [0..1]
9
+ * grayness .. [0..1]
10
+ */
11
+
12
+ const hcg2rgb = (...args) => {
13
+ args = unpack(args, 'hcg');
14
+ let [h, c, _g] = args;
15
+ let r, g, b;
16
+ _g = _g * 255;
17
+ const _c = c * 255;
18
+ if (c === 0) {
19
+ r = g = b = _g;
20
+ } else {
21
+ if (h === 360) h = 0;
22
+ if (h > 360) h -= 360;
23
+ if (h < 0) h += 360;
24
+ h /= 60;
25
+ const i = floor(h);
26
+ const f = h - i;
27
+ const p = _g * (1 - c);
28
+ const q = p + _c * (1 - f);
29
+ const t = p + _c * f;
30
+ const v = p + _c;
31
+ switch (i) {
32
+ case 0:
33
+ [r, g, b] = [v, t, p];
34
+ break;
35
+ case 1:
36
+ [r, g, b] = [q, v, p];
37
+ break;
38
+ case 2:
39
+ [r, g, b] = [p, v, t];
40
+ break;
41
+ case 3:
42
+ [r, g, b] = [p, q, v];
43
+ break;
44
+ case 4:
45
+ [r, g, b] = [t, p, v];
46
+ break;
47
+ case 5:
48
+ [r, g, b] = [v, p, q];
49
+ break;
50
+ }
51
+ }
52
+ return [r, g, b, args.length > 3 ? args[3] : 1];
53
+ };
54
+
55
+ export default hcg2rgb;
@@ -0,0 +1,27 @@
1
+ import { unpack, type } from '../../utils/index.js';
2
+ import chroma from '../../chroma.js';
3
+ import Color from '../../Color.js';
4
+ import input from '../input.js';
5
+ import hcg2rgb from './hcg2rgb.js';
6
+ import rgb2hcg from './rgb2hcg.js';
7
+
8
+ Color.prototype.hcg = function () {
9
+ return rgb2hcg(this._rgb);
10
+ };
11
+
12
+ const hcg = (...args) => new Color(...args, 'hcg');
13
+ chroma.hcg = hcg;
14
+
15
+ input.format.hcg = hcg2rgb;
16
+
17
+ input.autodetect.push({
18
+ p: 1,
19
+ test: (...args) => {
20
+ args = unpack(args, 'hcg');
21
+ if (type(args) === 'array' && args.length === 3) {
22
+ return 'hcg';
23
+ }
24
+ }
25
+ });
26
+
27
+ export { hcg };
@@ -0,0 +1,23 @@
1
+ import { unpack, max, min } from '../../utils/index.js';
2
+
3
+ const rgb2hcg = (...args) => {
4
+ const [r, g, b] = unpack(args, 'rgb');
5
+ const minRgb = min(r, g, b);
6
+ const maxRgb = max(r, g, b);
7
+ const delta = maxRgb - minRgb;
8
+ const c = (delta * 100) / 255;
9
+ const _g = (minRgb / (255 - delta)) * 100;
10
+ let h;
11
+ if (delta === 0) {
12
+ h = Number.NaN;
13
+ } else {
14
+ if (r === maxRgb) h = (g - b) / delta;
15
+ if (g === maxRgb) h = 2 + (b - r) / delta;
16
+ if (b === maxRgb) h = 4 + (r - g) / delta;
17
+ h *= 60;
18
+ if (h < 0) h += 360;
19
+ }
20
+ return [h, c, _g];
21
+ };
22
+
23
+ export default rgb2hcg;
@@ -0,0 +1,56 @@
1
+ const RE_HEX = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
2
+ const RE_HEXA = /^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/;
3
+
4
+ const hex2rgb = (hex) => {
5
+ if (hex.match(RE_HEX)) {
6
+ // remove optional leading #
7
+ if (hex.length === 4 || hex.length === 7) {
8
+ hex = hex.substr(1);
9
+ }
10
+ // expand short-notation to full six-digit
11
+ if (hex.length === 3) {
12
+ hex = hex.split('');
13
+ hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
14
+ }
15
+ const u = parseInt(hex, 16);
16
+ const r = u >> 16;
17
+ const g = (u >> 8) & 0xff;
18
+ const b = u & 0xff;
19
+ return [r, g, b, 1];
20
+ }
21
+
22
+ // match rgba hex format, eg #FF000077
23
+ if (hex.match(RE_HEXA)) {
24
+ if (hex.length === 5 || hex.length === 9) {
25
+ // remove optional leading #
26
+ hex = hex.substr(1);
27
+ }
28
+ // expand short-notation to full eight-digit
29
+ if (hex.length === 4) {
30
+ hex = hex.split('');
31
+ hex =
32
+ hex[0] +
33
+ hex[0] +
34
+ hex[1] +
35
+ hex[1] +
36
+ hex[2] +
37
+ hex[2] +
38
+ hex[3] +
39
+ hex[3];
40
+ }
41
+ const u = parseInt(hex, 16);
42
+ const r = (u >> 24) & 0xff;
43
+ const g = (u >> 16) & 0xff;
44
+ const b = (u >> 8) & 0xff;
45
+ const a = Math.round(((u & 0xff) / 0xff) * 100) / 100;
46
+ return [r, g, b, a];
47
+ }
48
+
49
+ // we used to check for css colors here
50
+ // if _input.css? and rgb = _input.css hex
51
+ // return rgb
52
+
53
+ throw new Error(`unknown hex color: ${hex}`);
54
+ };
55
+
56
+ export default hex2rgb;
@@ -0,0 +1,29 @@
1
+ import Color from '../../Color.js';
2
+ import chroma from '../../chroma.js';
3
+ import { type } from '../../utils/index.js';
4
+ import input from '../input.js';
5
+ import hex2rgb from './hex2rgb.js';
6
+ import rgb2hex from './rgb2hex.js';
7
+
8
+ Color.prototype.hex = function (mode) {
9
+ return rgb2hex(this._rgb, mode);
10
+ };
11
+
12
+ const hex = (...args) => new Color(...args, 'hex');
13
+ chroma.hex = hex;
14
+
15
+ input.format.hex = hex2rgb;
16
+ input.autodetect.push({
17
+ p: 4,
18
+ test: (h, ...rest) => {
19
+ if (
20
+ !rest.length &&
21
+ type(h) === 'string' &&
22
+ [3, 4, 5, 6, 7, 8, 9].indexOf(h.length) >= 0
23
+ ) {
24
+ return 'hex';
25
+ }
26
+ }
27
+ });
28
+
29
+ export { hex };
@@ -0,0 +1,29 @@
1
+ import { unpack, last } from '../../utils/index.js';
2
+ const { round } = Math;
3
+
4
+ const rgb2hex = (...args) => {
5
+ let [r, g, b, a] = unpack(args, 'rgba');
6
+ let mode = last(args) || 'auto';
7
+ if (a === undefined) a = 1;
8
+ if (mode === 'auto') {
9
+ mode = a < 1 ? 'rgba' : 'rgb';
10
+ }
11
+ r = round(r);
12
+ g = round(g);
13
+ b = round(b);
14
+ const u = (r << 16) | (g << 8) | b;
15
+ let str = '000000' + u.toString(16); //#.toUpperCase();
16
+ str = str.substr(str.length - 6);
17
+ let hxa = '0' + round(a * 255).toString(16);
18
+ hxa = hxa.substr(hxa.length - 2);
19
+ switch (mode.toLowerCase()) {
20
+ case 'rgba':
21
+ return `#${str}${hxa}`;
22
+ case 'argb':
23
+ return `#${hxa}${str}`;
24
+ default:
25
+ return `#${str}`;
26
+ }
27
+ };
28
+
29
+ export default rgb2hex;