react-cheminfo 0.15.0 → 0.17.0

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 (157) hide show
  1. package/README.md +96 -0
  2. package/lib/core.d.ts +1 -0
  3. package/lib/core.d.ts.map +1 -1
  4. package/lib/core.js +1 -0
  5. package/lib/core.js.map +1 -1
  6. package/lib/credits/core/credits.d.ts +17 -0
  7. package/lib/credits/core/credits.d.ts.map +1 -1
  8. package/lib/credits/core/credits.js +20 -0
  9. package/lib/credits/core/credits.js.map +1 -1
  10. package/lib/ecosystem/core/sites.d.ts.map +1 -1
  11. package/lib/ecosystem/core/sites.js +40 -0
  12. package/lib/ecosystem/core/sites.js.map +1 -1
  13. package/lib/ecosystem/core/types.d.ts +1 -1
  14. package/lib/ecosystem/core/types.d.ts.map +1 -1
  15. package/lib/ecosystem/ui/glyphs.d.ts.map +1 -1
  16. package/lib/ecosystem/ui/glyphs.js +11 -0
  17. package/lib/ecosystem/ui/glyphs.js.map +1 -1
  18. package/lib/parallel/core/index.d.ts +29 -0
  19. package/lib/parallel/core/index.d.ts.map +1 -0
  20. package/lib/parallel/core/index.js +22 -0
  21. package/lib/parallel/core/index.js.map +1 -0
  22. package/lib/parallel/core/parallelAxes.d.ts +103 -0
  23. package/lib/parallel/core/parallelAxes.d.ts.map +1 -0
  24. package/lib/parallel/core/parallelAxes.js +146 -0
  25. package/lib/parallel/core/parallelAxes.js.map +1 -0
  26. package/lib/parallel/core/parallelBrush.d.ts +100 -0
  27. package/lib/parallel/core/parallelBrush.d.ts.map +1 -0
  28. package/lib/parallel/core/parallelBrush.js +149 -0
  29. package/lib/parallel/core/parallelBrush.js.map +1 -0
  30. package/lib/parallel/core/parallelExtent.d.ts +28 -0
  31. package/lib/parallel/core/parallelExtent.d.ts.map +1 -0
  32. package/lib/parallel/core/parallelExtent.js +47 -0
  33. package/lib/parallel/core/parallelExtent.js.map +1 -0
  34. package/lib/parallel/core/parallelFilter.d.ts +49 -0
  35. package/lib/parallel/core/parallelFilter.d.ts.map +1 -0
  36. package/lib/parallel/core/parallelFilter.js +107 -0
  37. package/lib/parallel/core/parallelFilter.js.map +1 -0
  38. package/lib/parallel/core/parallelHit.d.ts +47 -0
  39. package/lib/parallel/core/parallelHit.d.ts.map +1 -0
  40. package/lib/parallel/core/parallelHit.js +81 -0
  41. package/lib/parallel/core/parallelHit.js.map +1 -0
  42. package/lib/parallel/core/parallelOrder.d.ts +36 -0
  43. package/lib/parallel/core/parallelOrder.d.ts.map +1 -0
  44. package/lib/parallel/core/parallelOrder.js +65 -0
  45. package/lib/parallel/core/parallelOrder.js.map +1 -0
  46. package/lib/parallel/core/parallelPaint.d.ts +108 -0
  47. package/lib/parallel/core/parallelPaint.d.ts.map +1 -0
  48. package/lib/parallel/core/parallelPaint.js +169 -0
  49. package/lib/parallel/core/parallelPaint.js.map +1 -0
  50. package/lib/parallel/core/parallelPalette.d.ts +40 -0
  51. package/lib/parallel/core/parallelPalette.d.ts.map +1 -0
  52. package/lib/parallel/core/parallelPalette.js +81 -0
  53. package/lib/parallel/core/parallelPalette.js.map +1 -0
  54. package/lib/parallel/core/parallelSelection.d.ts +43 -0
  55. package/lib/parallel/core/parallelSelection.d.ts.map +1 -0
  56. package/lib/parallel/core/parallelSelection.js +87 -0
  57. package/lib/parallel/core/parallelSelection.js.map +1 -0
  58. package/lib/parallel/core/parallelTicks.d.ts +34 -0
  59. package/lib/parallel/core/parallelTicks.d.ts.map +1 -0
  60. package/lib/parallel/core/parallelTicks.js +119 -0
  61. package/lib/parallel/core/parallelTicks.js.map +1 -0
  62. package/lib/parallel/core/parallelTypes.d.ts +140 -0
  63. package/lib/parallel/core/parallelTypes.d.ts.map +1 -0
  64. package/lib/parallel/core/parallelTypes.js +29 -0
  65. package/lib/parallel/core/parallelTypes.js.map +1 -0
  66. package/lib/parallel/ui/ParallelAxesLayer.d.ts +28 -0
  67. package/lib/parallel/ui/ParallelAxesLayer.d.ts.map +1 -0
  68. package/lib/parallel/ui/ParallelAxesLayer.js +29 -0
  69. package/lib/parallel/ui/ParallelAxesLayer.js.map +1 -0
  70. package/lib/parallel/ui/ParallelCoordinates.d.ts +21 -0
  71. package/lib/parallel/ui/ParallelCoordinates.d.ts.map +1 -0
  72. package/lib/parallel/ui/ParallelCoordinates.js +114 -0
  73. package/lib/parallel/ui/ParallelCoordinates.js.map +1 -0
  74. package/lib/parallel/ui/ParallelLabels.d.ts +32 -0
  75. package/lib/parallel/ui/ParallelLabels.d.ts.map +1 -0
  76. package/lib/parallel/ui/ParallelLabels.js +37 -0
  77. package/lib/parallel/ui/ParallelLabels.js.map +1 -0
  78. package/lib/parallel/ui/ParallelTooltip.d.ts +26 -0
  79. package/lib/parallel/ui/ParallelTooltip.d.ts.map +1 -0
  80. package/lib/parallel/ui/ParallelTooltip.js +30 -0
  81. package/lib/parallel/ui/ParallelTooltip.js.map +1 -0
  82. package/lib/parallel/ui/index.d.ts +29 -0
  83. package/lib/parallel/ui/index.d.ts.map +1 -0
  84. package/lib/parallel/ui/index.js +20 -0
  85. package/lib/parallel/ui/index.js.map +1 -0
  86. package/lib/parallel/ui/parallelCoordinatesProps.d.ts +203 -0
  87. package/lib/parallel/ui/parallelCoordinatesProps.d.ts.map +1 -0
  88. package/lib/parallel/ui/parallelCoordinatesProps.js +11 -0
  89. package/lib/parallel/ui/parallelCoordinatesProps.js.map +1 -0
  90. package/lib/parallel/ui/parallelGestureModel.d.ts +83 -0
  91. package/lib/parallel/ui/parallelGestureModel.d.ts.map +1 -0
  92. package/lib/parallel/ui/parallelGestureModel.js +110 -0
  93. package/lib/parallel/ui/parallelGestureModel.js.map +1 -0
  94. package/lib/parallel/ui/parallelInk.d.ts +76 -0
  95. package/lib/parallel/ui/parallelInk.d.ts.map +1 -0
  96. package/lib/parallel/ui/parallelInk.js +113 -0
  97. package/lib/parallel/ui/parallelInk.js.map +1 -0
  98. package/lib/parallel/ui/parallelPlotModel.d.ts +55 -0
  99. package/lib/parallel/ui/parallelPlotModel.d.ts.map +1 -0
  100. package/lib/parallel/ui/parallelPlotModel.js +113 -0
  101. package/lib/parallel/ui/parallelPlotModel.js.map +1 -0
  102. package/lib/parallel/ui/parallelStyles.d.ts +106 -0
  103. package/lib/parallel/ui/parallelStyles.d.ts.map +1 -0
  104. package/lib/parallel/ui/parallelStyles.js +153 -0
  105. package/lib/parallel/ui/parallelStyles.js.map +1 -0
  106. package/lib/parallel/ui/useParallelAxisDrag.d.ts +60 -0
  107. package/lib/parallel/ui/useParallelAxisDrag.d.ts.map +1 -0
  108. package/lib/parallel/ui/useParallelAxisDrag.js +96 -0
  109. package/lib/parallel/ui/useParallelAxisDrag.js.map +1 -0
  110. package/lib/parallel/ui/useParallelCanvas.d.ts +49 -0
  111. package/lib/parallel/ui/useParallelCanvas.d.ts.map +1 -0
  112. package/lib/parallel/ui/useParallelCanvas.js +58 -0
  113. package/lib/parallel/ui/useParallelCanvas.js.map +1 -0
  114. package/lib/parallel/ui/useParallelGesture.d.ts +72 -0
  115. package/lib/parallel/ui/useParallelGesture.d.ts.map +1 -0
  116. package/lib/parallel/ui/useParallelGesture.js +164 -0
  117. package/lib/parallel/ui/useParallelGesture.js.map +1 -0
  118. package/lib/structure/ui/useToolbarFloor.d.ts.map +1 -1
  119. package/lib/structure/ui/useToolbarFloor.js +29 -22
  120. package/lib/structure/ui/useToolbarFloor.js.map +1 -1
  121. package/lib/ui.d.ts +1 -0
  122. package/lib/ui.d.ts.map +1 -1
  123. package/lib/ui.js +1 -0
  124. package/lib/ui.js.map +1 -1
  125. package/package.json +1 -1
  126. package/src/core.ts +1 -0
  127. package/src/credits/core/credits.ts +21 -0
  128. package/src/ecosystem/core/sites.ts +40 -0
  129. package/src/ecosystem/core/types.ts +4 -1
  130. package/src/ecosystem/ui/glyphs.tsx +46 -0
  131. package/src/parallel/core/index.ts +96 -0
  132. package/src/parallel/core/parallelAxes.ts +207 -0
  133. package/src/parallel/core/parallelBrush.ts +211 -0
  134. package/src/parallel/core/parallelExtent.ts +56 -0
  135. package/src/parallel/core/parallelFilter.ts +131 -0
  136. package/src/parallel/core/parallelHit.ts +106 -0
  137. package/src/parallel/core/parallelOrder.ts +73 -0
  138. package/src/parallel/core/parallelPaint.ts +242 -0
  139. package/src/parallel/core/parallelPalette.ts +93 -0
  140. package/src/parallel/core/parallelSelection.ts +99 -0
  141. package/src/parallel/core/parallelTicks.ts +168 -0
  142. package/src/parallel/core/parallelTypes.ts +159 -0
  143. package/src/parallel/ui/ParallelAxesLayer.tsx +129 -0
  144. package/src/parallel/ui/ParallelCoordinates.tsx +252 -0
  145. package/src/parallel/ui/ParallelLabels.tsx +77 -0
  146. package/src/parallel/ui/ParallelTooltip.tsx +55 -0
  147. package/src/parallel/ui/index.ts +65 -0
  148. package/src/parallel/ui/parallelCoordinatesProps.ts +217 -0
  149. package/src/parallel/ui/parallelGestureModel.ts +159 -0
  150. package/src/parallel/ui/parallelInk.ts +182 -0
  151. package/src/parallel/ui/parallelPlotModel.ts +130 -0
  152. package/src/parallel/ui/parallelStyles.ts +188 -0
  153. package/src/parallel/ui/useParallelAxisDrag.ts +147 -0
  154. package/src/parallel/ui/useParallelCanvas.ts +104 -0
  155. package/src/parallel/ui/useParallelGesture.ts +260 -0
  156. package/src/structure/ui/useToolbarFloor.ts +27 -22
  157. package/src/ui.ts +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallelFilter.js","sourceRoot":"","sources":["../../../src/parallel/core/parallelFilter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Which row the pointer is over.
3
+ *
4
+ * Only the segment between the two axes the pointer sits between is tested, so
5
+ * the cost is one distance per row whatever the number of axes. The vertical
6
+ * gap to the segment is projected onto its normal, so a steep line is no
7
+ * harder to pick than a flat one — without which the only rows a reader can
8
+ * ever point at are the uninteresting ones.
9
+ */
10
+ import type { ParallelAxisLayout } from './parallelAxes.ts';
11
+ /** How far the pointer may sit from a line and still pick it, in pixels. */
12
+ export declare const PARALLEL_HOVER_TOLERANCE = 6;
13
+ /** A pointer position, relative to the top left of the drawing area. */
14
+ export interface ParallelPoint {
15
+ /** Pixels from the left of the drawing area. */
16
+ x: number;
17
+ /** Pixels from its top. */
18
+ y: number;
19
+ }
20
+ /** The pair of axes a pointer sits between, as indices into the layouts. */
21
+ export interface ParallelSegment {
22
+ /** The axis to the left of the pointer. */
23
+ left: number;
24
+ /** The axis to its right. */
25
+ right: number;
26
+ }
27
+ /**
28
+ * The pair of axes a horizontal position sits between.
29
+ * @param x - Pixels from the left of the drawing area.
30
+ * @param axes - The axes, from left to right.
31
+ * @param tolerance - How far past the first and the last axis still counts. Defaults to {@link PARALLEL_HOVER_TOLERANCE}.
32
+ * @returns The pair, or `null` when there are fewer than two axes or the
33
+ * position is past either end of the figure.
34
+ */
35
+ export declare function parallelSegmentAt(x: number, axes: readonly ParallelAxisLayout[], tolerance?: number): ParallelSegment | null;
36
+ /**
37
+ * The row whose line runs closest to the pointer.
38
+ * @param point - Where the pointer is, relative to the drawing area.
39
+ * @param axes - The axes, from left to right.
40
+ * @param values - Each axis's column, in the same order.
41
+ * @param count - How many rows are drawn.
42
+ * @param included - Which rows a brush keeps, a zero meaning the row is not pickable. Defaults to every row.
43
+ * @param tolerance - How far the pointer may sit from a line. Defaults to {@link PARALLEL_HOVER_TOLERANCE}.
44
+ * @returns The row, or `-1` when the pointer is over no line.
45
+ */
46
+ export declare function parallelNearestRow(point: ParallelPoint, axes: readonly ParallelAxisLayout[], values: ReadonlyArray<ArrayLike<number>>, count: number, included?: Uint8Array, tolerance?: number): number;
47
+ //# sourceMappingURL=parallelHit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallelHit.d.ts","sourceRoot":"","sources":["../../../src/parallel/core/parallelHit.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG5D,4EAA4E;AAC5E,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,wEAAwE;AACxE,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,CAAC,EAAE,MAAM,CAAC;IACV,2BAA2B;IAC3B,CAAC,EAAE,MAAM,CAAC;CACX;AAED,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,MAAM,EACT,IAAI,EAAE,SAAS,kBAAkB,EAAE,EACnC,SAAS,GAAE,MAAiC,GAC3C,eAAe,GAAG,IAAI,CAaxB;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,SAAS,kBAAkB,EAAE,EACnC,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EACxC,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,UAAU,EACrB,SAAS,GAAE,MAAiC,GAC3C,MAAM,CA6BR"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Which row the pointer is over.
3
+ *
4
+ * Only the segment between the two axes the pointer sits between is tested, so
5
+ * the cost is one distance per row whatever the number of axes. The vertical
6
+ * gap to the segment is projected onto its normal, so a steep line is no
7
+ * harder to pick than a flat one — without which the only rows a reader can
8
+ * ever point at are the uninteresting ones.
9
+ */
10
+ import { parallelPixelAt } from "./parallelAxes.js";
11
+ /** How far the pointer may sit from a line and still pick it, in pixels. */
12
+ export const PARALLEL_HOVER_TOLERANCE = 6;
13
+ /**
14
+ * The pair of axes a horizontal position sits between.
15
+ * @param x - Pixels from the left of the drawing area.
16
+ * @param axes - The axes, from left to right.
17
+ * @param tolerance - How far past the first and the last axis still counts. Defaults to {@link PARALLEL_HOVER_TOLERANCE}.
18
+ * @returns The pair, or `null` when there are fewer than two axes or the
19
+ * position is past either end of the figure.
20
+ */
21
+ export function parallelSegmentAt(x, axes, tolerance = PARALLEL_HOVER_TOLERANCE) {
22
+ const first = axes[0];
23
+ const last = axes.at(-1);
24
+ if (first === undefined || last === undefined || axes.length < 2)
25
+ return null;
26
+ if (x < first.x - tolerance || x > last.x + tolerance)
27
+ return null;
28
+ for (let index = 1; index < axes.length; index++) {
29
+ const right = axes[index];
30
+ if (right === undefined)
31
+ continue;
32
+ if (x <= right.x || index === axes.length - 1) {
33
+ return { left: index - 1, right: index };
34
+ }
35
+ }
36
+ return null;
37
+ }
38
+ /**
39
+ * The row whose line runs closest to the pointer.
40
+ * @param point - Where the pointer is, relative to the drawing area.
41
+ * @param axes - The axes, from left to right.
42
+ * @param values - Each axis's column, in the same order.
43
+ * @param count - How many rows are drawn.
44
+ * @param included - Which rows a brush keeps, a zero meaning the row is not pickable. Defaults to every row.
45
+ * @param tolerance - How far the pointer may sit from a line. Defaults to {@link PARALLEL_HOVER_TOLERANCE}.
46
+ * @returns The row, or `-1` when the pointer is over no line.
47
+ */
48
+ export function parallelNearestRow(point, axes, values, count, included, tolerance = PARALLEL_HOVER_TOLERANCE) {
49
+ const segment = parallelSegmentAt(point.x, axes, tolerance);
50
+ if (segment === null)
51
+ return -1;
52
+ const left = axes[segment.left];
53
+ const right = axes[segment.right];
54
+ const leftColumn = values[segment.left];
55
+ const rightColumn = values[segment.right];
56
+ if (left === undefined || right === undefined)
57
+ return -1;
58
+ if (leftColumn === undefined || rightColumn === undefined)
59
+ return -1;
60
+ const width = right.x - left.x;
61
+ if (width <= 0)
62
+ return -1;
63
+ const ratio = (point.x - left.x) / width;
64
+ const rows = Math.min(count, leftColumn.length, rightColumn.length);
65
+ let nearest = -1;
66
+ let nearestDistance = tolerance;
67
+ for (let row = 0; row < rows; row++) {
68
+ if (included?.[row] === 0)
69
+ continue;
70
+ const leftY = parallelPixelAt(left.pixels, leftColumn[row]);
71
+ const rightY = parallelPixelAt(right.pixels, rightColumn[row]);
72
+ const gap = Math.abs(leftY + (rightY - leftY) * ratio - point.y);
73
+ const distance = (gap * width) / Math.hypot(width, rightY - leftY);
74
+ if (distance < nearestDistance) {
75
+ nearestDistance = distance;
76
+ nearest = row;
77
+ }
78
+ }
79
+ return nearest;
80
+ }
81
+ //# sourceMappingURL=parallelHit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallelHit.js","sourceRoot":"","sources":["../../../src/parallel/core/parallelHit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Which order the axes stand in, when the reader is the one deciding.
3
+ *
4
+ * A parallel-coordinates figure only shows a relationship between two columns
5
+ * that stand next to each other, so the order is not decoration: moving an
6
+ * axis is how a reader asks a different question of the same data. The
7
+ * arithmetic of the move is here, away from the pointer that starts it, so
8
+ * that dragging a name and pressing an arrow key are the same operation.
9
+ */
10
+ import type { ParallelAxisLayout } from './parallelAxes.ts';
11
+ /**
12
+ * The same ids with one of them moved.
13
+ * @param ids - The axes, from left to right.
14
+ * @param from - Which one is moving.
15
+ * @param to - The place it lands in, counted in the list it left.
16
+ * @returns The new order. The list comes back unchanged when either place is
17
+ * outside it or when nothing moves, so a caller can report without comparing.
18
+ */
19
+ export declare function parallelMoveAxis(ids: readonly string[], from: number, to: number): string[];
20
+ /**
21
+ * Where an axis dragged to that position would land.
22
+ * @param x - Where the pointer is, in pixels from the left of the drawing area.
23
+ * @param layouts - The axes, from left to right.
24
+ * @returns The index of the axis whose place it would take, or `-1` when there
25
+ * is nowhere to land. Nearest axis rather than nearest gap: a reader dragging
26
+ * a name over its neighbour means the two to swap, and the neighbour's own
27
+ * name is the thing they are aiming at.
28
+ */
29
+ export declare function parallelDropIndex(x: number, layouts: readonly ParallelAxisLayout[]): number;
30
+ /**
31
+ * The ids of the axes, from left to right.
32
+ * @param layouts - The axes, already placed.
33
+ * @returns Their ids, which is what an order is reported as.
34
+ */
35
+ export declare function parallelAxisOrder(layouts: readonly ParallelAxisLayout[]): string[];
36
+ //# sourceMappingURL=parallelOrder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallelOrder.d.ts","sourceRoot":"","sources":["../../../src/parallel/core/parallelOrder.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,SAAS,MAAM,EAAE,EACtB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,MAAM,EAAE,CAQV;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,MAAM,EACT,OAAO,EAAE,SAAS,kBAAkB,EAAE,GACrC,MAAM,CAaR;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,SAAS,kBAAkB,EAAE,GACrC,MAAM,EAAE,CAIV"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Which order the axes stand in, when the reader is the one deciding.
3
+ *
4
+ * A parallel-coordinates figure only shows a relationship between two columns
5
+ * that stand next to each other, so the order is not decoration: moving an
6
+ * axis is how a reader asks a different question of the same data. The
7
+ * arithmetic of the move is here, away from the pointer that starts it, so
8
+ * that dragging a name and pressing an arrow key are the same operation.
9
+ */
10
+ /**
11
+ * The same ids with one of them moved.
12
+ * @param ids - The axes, from left to right.
13
+ * @param from - Which one is moving.
14
+ * @param to - The place it lands in, counted in the list it left.
15
+ * @returns The new order. The list comes back unchanged when either place is
16
+ * outside it or when nothing moves, so a caller can report without comparing.
17
+ */
18
+ export function parallelMoveAxis(ids, from, to) {
19
+ const order = [...ids];
20
+ if (from < 0 || from >= order.length)
21
+ return order;
22
+ if (to < 0 || to >= order.length || to === from)
23
+ return order;
24
+ const [moved] = order.splice(from, 1);
25
+ if (moved === undefined)
26
+ return [...ids];
27
+ order.splice(to, 0, moved);
28
+ return order;
29
+ }
30
+ /**
31
+ * Where an axis dragged to that position would land.
32
+ * @param x - Where the pointer is, in pixels from the left of the drawing area.
33
+ * @param layouts - The axes, from left to right.
34
+ * @returns The index of the axis whose place it would take, or `-1` when there
35
+ * is nowhere to land. Nearest axis rather than nearest gap: a reader dragging
36
+ * a name over its neighbour means the two to swap, and the neighbour's own
37
+ * name is the thing they are aiming at.
38
+ */
39
+ export function parallelDropIndex(x, layouts) {
40
+ let nearest = -1;
41
+ let nearestDistance = Number.POSITIVE_INFINITY;
42
+ for (let index = 0; index < layouts.length; index++) {
43
+ const layout = layouts[index];
44
+ if (layout === undefined)
45
+ continue;
46
+ const distance = Math.abs(x - layout.x);
47
+ if (distance < nearestDistance) {
48
+ nearestDistance = distance;
49
+ nearest = index;
50
+ }
51
+ }
52
+ return nearest;
53
+ }
54
+ /**
55
+ * The ids of the axes, from left to right.
56
+ * @param layouts - The axes, already placed.
57
+ * @returns Their ids, which is what an order is reported as.
58
+ */
59
+ export function parallelAxisOrder(layouts) {
60
+ const ids = [];
61
+ for (const layout of layouts)
62
+ ids.push(layout.id);
63
+ return ids;
64
+ }
65
+ //# sourceMappingURL=parallelOrder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallelOrder.js","sourceRoot":"","sources":["../../../src/parallel/core/parallelOrder.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAAsB,EACtB,IAAY,EACZ,EAAU;IAEV,MAAM,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;IACvB,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,KAAK,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACnD,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACtC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;IACzC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;IAC3B,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAC/B,CAAS,EACT,OAAsC;IAEtC,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;IACjB,IAAI,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAC/C,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,MAAM,KAAK,SAAS;YAAE,SAAS;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxC,IAAI,QAAQ,GAAG,eAAe,EAAE,CAAC;YAC/B,eAAe,GAAG,QAAQ,CAAC;YAC3B,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAsC;IAEtC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,MAAM,IAAI,OAAO;QAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAClD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * The lines, painted into a canvas.
3
+ *
4
+ * The first canvas figure in the family, and for one reason: ten thousand
5
+ * polylines of a dozen points each is a hundred and twenty thousand SVG
6
+ * coordinates the browser would keep as elements. Everything a reader points
7
+ * at, brushes or reads is still SVG or HTML over the top, so only the mass of
8
+ * lines is pixels — which is also why saving the figure keeps the axes and
9
+ * loses the lines, and why a site that needs a downloadable figure should say
10
+ * so before choosing this one.
11
+ */
12
+ import type { ParallelAxisLayout } from './parallelAxes.ts';
13
+ /** How strongly one kept line is drawn, so that the mass reads as a density. */
14
+ export declare const PARALLEL_INCLUDED_ALPHA = 0.35;
15
+ /** What one pass of the line painter needs. */
16
+ export interface ParallelPaint {
17
+ /** The axes, from left to right, already placed and measured. */
18
+ layouts: readonly ParallelAxisLayout[];
19
+ /** Each axis's column, in the same order. */
20
+ values: ReadonlyArray<ArrayLike<number>>;
21
+ /** How many rows to draw. */
22
+ count: number;
23
+ /**
24
+ * Which rows the brushes keep, a zero meaning the row is drawn underneath in
25
+ * the excluded ink.
26
+ * @default null — every row is kept and nothing is drawn underneath
27
+ */
28
+ included?: Uint8Array | null;
29
+ /**
30
+ * Which colour each row takes, as a step into `palette`.
31
+ * @default null — every line takes `line`
32
+ */
33
+ steps?: Uint8Array | null;
34
+ /**
35
+ * The colours a step indexes, from `parallelPalette`.
36
+ * @default [] — nothing to index
37
+ */
38
+ palette?: readonly string[];
39
+ /** The ink a line takes when no quantity is colouring the lines. */
40
+ line: string;
41
+ /** The ink the rows a brush left out are drawn in. */
42
+ excluded: string;
43
+ /**
44
+ * How strongly a kept line is drawn. Turn it down for a dense library.
45
+ * @default PARALLEL_INCLUDED_ALPHA
46
+ */
47
+ includedAlpha?: number;
48
+ }
49
+ /** One row drawn over the mass, and the ink it is drawn in. */
50
+ export interface ParallelHighlight {
51
+ /** The row. */
52
+ row: number;
53
+ /** Its ink. */
54
+ color: string;
55
+ }
56
+ /** What the highlight pass needs. */
57
+ export interface ParallelHighlightPaint {
58
+ /** The rows to draw, the last one on top. */
59
+ highlights: readonly ParallelHighlight[];
60
+ /** The axes, from left to right. */
61
+ layouts: readonly ParallelAxisLayout[];
62
+ /** Each axis's column, in the same order. */
63
+ values: ReadonlyArray<ArrayLike<number>>;
64
+ /** The ink the halo under each line is drawn in. */
65
+ halo: string;
66
+ }
67
+ /**
68
+ * Resize a canvas to the device pixel grid and move its origin to the drawing
69
+ * area, which also clears whatever it held.
70
+ * @param canvas - The canvas, or `null` before it is mounted.
71
+ * @param width - Width of the figure, in CSS pixels.
72
+ * @param height - Its height, in CSS pixels.
73
+ * @returns The context, or `null` when there is nothing to draw on.
74
+ */
75
+ export declare function preparePlotCanvas(canvas: HTMLCanvasElement | null, width: number, height: number): CanvasRenderingContext2D | null;
76
+ /**
77
+ * Draw one line per row: the ones a brush left out first, underneath, then the
78
+ * kept ones over them.
79
+ *
80
+ * The excluded rows are one single path stroked once, in a light grey rather
81
+ * than a translucent black: overlapping segments of one stroked path
82
+ * accumulate alpha, so a translucent black saturates to black wherever the
83
+ * library is dense, while a light grey is a colour the pile can only converge
84
+ * on.
85
+ * @param context - A context already scaled and moved to the drawing area by {@link preparePlotCanvas}.
86
+ * @param paint - See {@link ParallelPaint}.
87
+ */
88
+ export declare function paintParallelLines(context: CanvasRenderingContext2D, paint: ParallelPaint): void;
89
+ /**
90
+ * Draw a few singled-out rows over the mass, each over a halo and dotted at
91
+ * every axis crossing.
92
+ * @param context - A context already scaled and moved to the drawing area.
93
+ * @param paint - See {@link ParallelHighlightPaint}.
94
+ */
95
+ export declare function paintParallelHighlights(context: CanvasRenderingContext2D, paint: ParallelHighlightPaint): void;
96
+ /**
97
+ * Add one row's line to the path being built.
98
+ *
99
+ * The line is one polyline per unbroken run of known values, so a row with a
100
+ * gap in the middle is drawn as two, and nothing is painted over an axis the
101
+ * row has no value on.
102
+ * @param context - A context already scaled and moved to the drawing area.
103
+ * @param row - The row to trace.
104
+ * @param layouts - The axes, from left to right.
105
+ * @param values - Each axis's column, in the same order.
106
+ */
107
+ export declare function traceParallelRow(context: CanvasRenderingContext2D, row: number, layouts: readonly ParallelAxisLayout[], values: ReadonlyArray<ArrayLike<number>>): void;
108
+ //# sourceMappingURL=parallelPaint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallelPaint.d.ts","sourceRoot":"","sources":["../../../src/parallel/core/parallelPaint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG5D,gFAAgF;AAChF,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAa5C,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACvC,6CAA6C;IAC7C,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACzC,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,QAAQ,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B;;;OAGG;IACH,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC1B;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,eAAe;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qCAAqC;AACrC,MAAM,WAAW,sBAAsB;IACrC,6CAA6C;IAC7C,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACzC,oCAAoC;IACpC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACvC,6CAA6C;IAC7C,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACzC,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,iBAAiB,GAAG,IAAI,EAChC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,wBAAwB,GAAG,IAAI,CAYjC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,aAAa,GACnB,IAAI,CAsCN;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,sBAAsB,GAC5B,IAAI,CA2BN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,wBAAwB,EACjC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,SAAS,kBAAkB,EAAE,EACtC,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,GACvC,IAAI,CAsBN"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * The lines, painted into a canvas.
3
+ *
4
+ * The first canvas figure in the family, and for one reason: ten thousand
5
+ * polylines of a dozen points each is a hundred and twenty thousand SVG
6
+ * coordinates the browser would keep as elements. Everything a reader points
7
+ * at, brushes or reads is still SVG or HTML over the top, so only the mass of
8
+ * lines is pixels — which is also why saving the figure keeps the axes and
9
+ * loses the lines, and why a site that needs a downloadable figure should say
10
+ * so before choosing this one.
11
+ */
12
+ import { PARALLEL_MARGIN, parallelPixelAt } from "./parallelAxes.js";
13
+ /** How strongly one kept line is drawn, so that the mass reads as a density. */
14
+ export const PARALLEL_INCLUDED_ALPHA = 0.35;
15
+ /** How wide a singled-out line's halo is, in pixels. */
16
+ const HALO_WIDTH = 5;
17
+ /** How wide a singled-out line itself is. */
18
+ const HIGHLIGHT_WIDTH = 2;
19
+ /** How large the dot at each of its axis crossings is. */
20
+ const HIGHLIGHT_DOT_RADIUS = 3;
21
+ const FULL_TURN = 2 * Math.PI;
22
+ /**
23
+ * Resize a canvas to the device pixel grid and move its origin to the drawing
24
+ * area, which also clears whatever it held.
25
+ * @param canvas - The canvas, or `null` before it is mounted.
26
+ * @param width - Width of the figure, in CSS pixels.
27
+ * @param height - Its height, in CSS pixels.
28
+ * @returns The context, or `null` when there is nothing to draw on.
29
+ */
30
+ export function preparePlotCanvas(canvas, width, height) {
31
+ if (canvas === null)
32
+ return null;
33
+ const context = canvas.getContext('2d');
34
+ if (context === null)
35
+ return null;
36
+ const pixelRatio = Math.max(globalThis.devicePixelRatio || 1, 1);
37
+ // Assigning the backing store is what clears it; there is no second clear.
38
+ canvas.width = Math.round(width * pixelRatio);
39
+ canvas.height = Math.round(height * pixelRatio);
40
+ context.resetTransform();
41
+ context.scale(pixelRatio, pixelRatio);
42
+ context.translate(PARALLEL_MARGIN.left, PARALLEL_MARGIN.top);
43
+ return context;
44
+ }
45
+ /**
46
+ * Draw one line per row: the ones a brush left out first, underneath, then the
47
+ * kept ones over them.
48
+ *
49
+ * The excluded rows are one single path stroked once, in a light grey rather
50
+ * than a translucent black: overlapping segments of one stroked path
51
+ * accumulate alpha, so a translucent black saturates to black wherever the
52
+ * library is dense, while a light grey is a colour the pile can only converge
53
+ * on.
54
+ * @param context - A context already scaled and moved to the drawing area by {@link preparePlotCanvas}.
55
+ * @param paint - See {@link ParallelPaint}.
56
+ */
57
+ export function paintParallelLines(context, paint) {
58
+ const { layouts, values, count, line, excluded, includedAlpha } = paint;
59
+ if (layouts.length < 2)
60
+ return;
61
+ const included = paint.included ?? null;
62
+ const steps = paint.steps ?? null;
63
+ const palette = paint.palette ?? [];
64
+ context.lineWidth = 1;
65
+ if (included !== null) {
66
+ context.strokeStyle = excluded;
67
+ context.beginPath();
68
+ for (let row = 0; row < count; row++) {
69
+ if (included[row] !== 0)
70
+ continue;
71
+ traceParallelRow(context, row, layouts, values);
72
+ }
73
+ context.stroke();
74
+ }
75
+ context.globalAlpha = includedAlpha ?? PARALLEL_INCLUDED_ALPHA;
76
+ context.strokeStyle = line;
77
+ let previousStep = -1;
78
+ for (let row = 0; row < count; row++) {
79
+ if (included !== null && included[row] === 0)
80
+ continue;
81
+ if (steps !== null) {
82
+ const step = steps[row];
83
+ if (step !== previousStep) {
84
+ // A step past the end of the ramp is a quantity nobody knows for this
85
+ // row; it is drawn in the neutral ink rather than in the ramp's first
86
+ // colour, which means the smallest value in the set.
87
+ context.strokeStyle = palette[step] ?? line;
88
+ previousStep = step;
89
+ }
90
+ }
91
+ context.beginPath();
92
+ traceParallelRow(context, row, layouts, values);
93
+ context.stroke();
94
+ }
95
+ context.globalAlpha = 1;
96
+ }
97
+ /**
98
+ * Draw a few singled-out rows over the mass, each over a halo and dotted at
99
+ * every axis crossing.
100
+ * @param context - A context already scaled and moved to the drawing area.
101
+ * @param paint - See {@link ParallelHighlightPaint}.
102
+ */
103
+ export function paintParallelHighlights(context, paint) {
104
+ const { highlights, layouts, values, halo } = paint;
105
+ if (layouts.length < 2)
106
+ return;
107
+ context.lineJoin = 'round';
108
+ context.lineCap = 'round';
109
+ for (const { row, color } of highlights) {
110
+ context.beginPath();
111
+ traceParallelRow(context, row, layouts, values);
112
+ context.strokeStyle = halo;
113
+ context.lineWidth = HALO_WIDTH;
114
+ context.stroke();
115
+ context.strokeStyle = color;
116
+ context.lineWidth = HIGHLIGHT_WIDTH;
117
+ context.stroke();
118
+ context.fillStyle = color;
119
+ for (let index = 0; index < layouts.length; index++) {
120
+ const layout = layouts[index];
121
+ const column = values[index];
122
+ if (layout === undefined || column === undefined)
123
+ continue;
124
+ const y = parallelPixelAt(layout.pixels, column[row]);
125
+ if (!Number.isFinite(y))
126
+ continue;
127
+ context.beginPath();
128
+ context.arc(layout.x, y, HIGHLIGHT_DOT_RADIUS, 0, FULL_TURN);
129
+ context.fill();
130
+ }
131
+ }
132
+ }
133
+ /**
134
+ * Add one row's line to the path being built.
135
+ *
136
+ * The line is one polyline per unbroken run of known values, so a row with a
137
+ * gap in the middle is drawn as two, and nothing is painted over an axis the
138
+ * row has no value on.
139
+ * @param context - A context already scaled and moved to the drawing area.
140
+ * @param row - The row to trace.
141
+ * @param layouts - The axes, from left to right.
142
+ * @param values - Each axis's column, in the same order.
143
+ */
144
+ export function traceParallelRow(context, row, layouts, values) {
145
+ let started = false;
146
+ for (let index = 0; index < layouts.length; index++) {
147
+ const layout = layouts[index];
148
+ const column = values[index];
149
+ if (layout === undefined || column === undefined)
150
+ continue;
151
+ const y = parallelPixelAt(layout.pixels, column[row]);
152
+ // A row whose value on this axis is not known yet has no point to draw,
153
+ // and the line breaks rather than bridging the axis: a segment drawn
154
+ // across it reads as a value the row does not hold, and the hit test,
155
+ // which has no endpoint there, cannot pick it back.
156
+ if (!Number.isFinite(y)) {
157
+ started = false;
158
+ continue;
159
+ }
160
+ if (started) {
161
+ context.lineTo(layout.x, y);
162
+ }
163
+ else {
164
+ context.moveTo(layout.x, y);
165
+ started = true;
166
+ }
167
+ }
168
+ }
169
+ //# sourceMappingURL=parallelPaint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallelPaint.js","sourceRoot":"","sources":["../../../src/parallel/core/parallelPaint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The colour each line is drawn in, as a step into a sampled ramp.
3
+ *
4
+ * A canvas reassigns `strokeStyle` once per line, and a thousand different
5
+ * colours is a thousand style writes. Quantising the ramp to 121 steps and
6
+ * keeping the rows in the order they came means the style is written about
7
+ * 121 times for the whole figure — while no reader can tell a hundred-and-
8
+ * twenty-first of a ramp apart from its neighbour.
9
+ */
10
+ import type { ColorScale } from '../../color/core/interpolate.ts';
11
+ import type { ParallelColorBy } from './parallelTypes.ts';
12
+ /** How many steps the ramp is quantised into; there is one more colour than steps. */
13
+ export declare const PARALLEL_PALETTE_STEPS = 120;
14
+ /**
15
+ * The step a row whose colouring quantity is unknown takes.
16
+ *
17
+ * Past the end of the ramp on purpose: no colour indexes it, so the painter
18
+ * leaves such a row in the neutral ink rather than claiming for it the ink of
19
+ * the smallest value in the set.
20
+ */
21
+ export declare const PARALLEL_PALETTE_UNKNOWN: number;
22
+ /**
23
+ * The ramp, sampled into the steps a line's colour is looked up by.
24
+ * @param scale - The ramp, as the registry hands it over or as a plain list of colours. Defaults to viridis.
25
+ * @returns `PARALLEL_PALETTE_STEPS + 1` colours, from the low end to the high end.
26
+ */
27
+ export declare function parallelPalette(scale?: ColorScale | readonly string[]): readonly string[];
28
+ /**
29
+ * Which step of the ramp each row takes.
30
+ *
31
+ * Worked out once per data change rather than per repaint, and held as bytes:
32
+ * a library of ten thousand rows costs ten kilobytes and the painter's inner
33
+ * loop reads an integer instead of placing a value on a ramp.
34
+ * @param color - The quantity the lines are coloured by.
35
+ * @param count - How many rows there are.
36
+ * @returns One step per row, from `0` to {@link PARALLEL_PALETTE_STEPS}, or
37
+ * {@link PARALLEL_PALETTE_UNKNOWN} for a row whose value is not a number.
38
+ */
39
+ export declare function parallelColorSteps(color: ParallelColorBy, count: number): Uint8Array;
40
+ //# sourceMappingURL=parallelPalette.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallelPalette.d.ts","sourceRoot":"","sources":["../../../src/parallel/core/parallelPalette.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAOlE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,sFAAsF;AACtF,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,QAA6B,CAAC;AAEnE;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,MAAM,EAAE,GACrC,SAAS,MAAM,EAAE,CAEnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,MAAM,GACZ,UAAU,CAqBZ"}