@genome-spy/core 0.66.1 → 0.68.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 (191) hide show
  1. package/dist/bundle/index.es.js +7669 -6115
  2. package/dist/bundle/index.js +114 -133
  3. package/dist/schema.json +534 -132
  4. package/dist/src/data/collector.d.ts +20 -0
  5. package/dist/src/data/collector.d.ts.map +1 -1
  6. package/dist/src/data/collector.js +148 -0
  7. package/dist/src/data/dataFlow.d.ts +6 -0
  8. package/dist/src/data/dataFlow.d.ts.map +1 -1
  9. package/dist/src/data/dataFlow.js +10 -0
  10. package/dist/src/data/flowHandle.d.ts +2 -0
  11. package/dist/src/data/flowHandle.d.ts.map +1 -1
  12. package/dist/src/data/flowHandle.js +1 -0
  13. package/dist/src/data/flowInit.d.ts +12 -4
  14. package/dist/src/data/flowInit.d.ts.map +1 -1
  15. package/dist/src/data/flowInit.js +115 -17
  16. package/dist/src/data/flowNode.d.ts +8 -0
  17. package/dist/src/data/flowNode.d.ts.map +1 -1
  18. package/dist/src/data/flowNode.js +18 -0
  19. package/dist/src/data/keyIndex.d.ts +18 -0
  20. package/dist/src/data/keyIndex.d.ts.map +1 -0
  21. package/dist/src/data/keyIndex.js +241 -0
  22. package/dist/src/data/keyIndex.test.d.ts +2 -0
  23. package/dist/src/data/keyIndex.test.d.ts.map +1 -0
  24. package/dist/src/data/sources/dataSource.d.ts.map +1 -1
  25. package/dist/src/data/sources/dataSource.js +5 -1
  26. package/dist/src/data/sources/dataSourceFactory.d.ts +14 -12
  27. package/dist/src/data/sources/dataSourceFactory.d.ts.map +1 -1
  28. package/dist/src/data/sources/dataSourceFactory.js +52 -16
  29. package/dist/src/data/sources/lazy/mockLazySource.d.ts +29 -0
  30. package/dist/src/data/sources/lazy/mockLazySource.d.ts.map +1 -0
  31. package/dist/src/data/sources/lazy/mockLazySource.js +44 -0
  32. package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts +22 -1
  33. package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts.map +1 -1
  34. package/dist/src/data/sources/lazy/singleAxisLazySource.js +34 -2
  35. package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts.map +1 -1
  36. package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +15 -0
  37. package/dist/src/data/sources/lazy/tabixSource.d.ts.map +1 -1
  38. package/dist/src/data/sources/lazy/tabixSource.js +15 -5
  39. package/dist/src/data/transforms/stack.d.ts.map +1 -1
  40. package/dist/src/data/transforms/stack.js +1 -0
  41. package/dist/src/encoder/accessor.d.ts +43 -0
  42. package/dist/src/encoder/accessor.d.ts.map +1 -1
  43. package/dist/src/encoder/accessor.js +164 -0
  44. package/dist/src/encoder/encoder.d.ts +11 -2
  45. package/dist/src/encoder/encoder.d.ts.map +1 -1
  46. package/dist/src/encoder/encoder.js +24 -4
  47. package/dist/src/encoder/metadataChannels.d.ts +15 -0
  48. package/dist/src/encoder/metadataChannels.d.ts.map +1 -0
  49. package/dist/src/encoder/metadataChannels.js +65 -0
  50. package/dist/src/encoder/metadataChannels.test.d.ts +2 -0
  51. package/dist/src/encoder/metadataChannels.test.d.ts.map +1 -0
  52. package/dist/src/genome/scaleLocus.d.ts.map +1 -1
  53. package/dist/src/genome/scaleLocus.js +14 -1
  54. package/dist/src/genomeSpy/containerUi.d.ts +0 -1
  55. package/dist/src/genomeSpy/containerUi.d.ts.map +1 -1
  56. package/dist/src/genomeSpy/containerUi.js +0 -14
  57. package/dist/src/genomeSpy/loadingIndicatorManager.d.ts +3 -7
  58. package/dist/src/genomeSpy/loadingIndicatorManager.d.ts.map +1 -1
  59. package/dist/src/genomeSpy/loadingIndicatorManager.js +68 -20
  60. package/dist/src/genomeSpy/loadingStatusRegistry.d.ts +52 -0
  61. package/dist/src/genomeSpy/loadingStatusRegistry.d.ts.map +1 -0
  62. package/dist/src/genomeSpy/loadingStatusRegistry.js +86 -0
  63. package/dist/src/genomeSpy/viewContextFactory.d.ts.map +1 -1
  64. package/dist/src/genomeSpy/viewContextFactory.js +0 -1
  65. package/dist/src/genomeSpy/viewDataInit.d.ts +10 -0
  66. package/dist/src/genomeSpy/viewDataInit.d.ts.map +1 -1
  67. package/dist/src/genomeSpy/viewDataInit.js +166 -2
  68. package/dist/src/genomeSpy/viewDataInit.test.d.ts +2 -0
  69. package/dist/src/genomeSpy/viewDataInit.test.d.ts.map +1 -0
  70. package/dist/src/genomeSpy.d.ts +1 -2
  71. package/dist/src/genomeSpy.d.ts.map +1 -1
  72. package/dist/src/genomeSpy.js +69 -27
  73. package/dist/src/gl/dataToVertices.d.ts.map +1 -1
  74. package/dist/src/gl/dataToVertices.js +16 -4
  75. package/dist/src/marks/mark.d.ts.map +1 -1
  76. package/dist/src/marks/mark.js +18 -11
  77. package/dist/src/marks/markUtils.js +1 -1
  78. package/dist/src/scale/scale.d.ts +6 -1
  79. package/dist/src/scale/scale.d.ts.map +1 -1
  80. package/dist/src/scale/scale.js +83 -23
  81. package/dist/src/scales/axisResolution.d.ts.map +1 -1
  82. package/dist/src/scales/axisResolution.js +10 -0
  83. package/dist/src/scales/{scaleDomainAggregator.d.ts → domainPlanner.d.ts} +8 -5
  84. package/dist/src/scales/domainPlanner.d.ts.map +1 -0
  85. package/dist/src/scales/domainPlanner.js +285 -0
  86. package/dist/src/scales/domainPlanner.test.d.ts +2 -0
  87. package/dist/src/scales/domainPlanner.test.d.ts.map +1 -0
  88. package/dist/src/scales/scaleInstanceManager.d.ts.map +1 -1
  89. package/dist/src/scales/scaleInstanceManager.js +8 -4
  90. package/dist/src/scales/scaleInteractionController.d.ts +6 -0
  91. package/dist/src/scales/scaleInteractionController.d.ts.map +1 -1
  92. package/dist/src/scales/scaleInteractionController.js +41 -3
  93. package/dist/src/scales/scaleResolution.d.ts +19 -16
  94. package/dist/src/scales/scaleResolution.d.ts.map +1 -1
  95. package/dist/src/scales/scaleResolution.js +255 -70
  96. package/dist/src/scales/scaleResolution.test.d.ts.map +1 -1
  97. package/dist/src/selection/selection.d.ts +21 -0
  98. package/dist/src/selection/selection.d.ts.map +1 -1
  99. package/dist/src/selection/selection.js +82 -0
  100. package/dist/src/spec/channel.d.ts +52 -15
  101. package/dist/src/spec/data.d.ts +4 -0
  102. package/dist/src/spec/parameter.d.ts +16 -11
  103. package/dist/src/spec/testing.d.ts +12 -0
  104. package/dist/src/spec/testing.d.ts.map +1 -0
  105. package/dist/src/spec/testing.js +20 -0
  106. package/dist/src/spec/view.d.ts +45 -10
  107. package/dist/src/styles/genome-spy.css +3 -31
  108. package/dist/src/styles/genome-spy.css.d.ts +1 -1
  109. package/dist/src/styles/genome-spy.css.d.ts.map +1 -1
  110. package/dist/src/styles/genome-spy.css.js +0 -29
  111. package/dist/src/types/encoder.d.ts +37 -2
  112. package/dist/src/types/rendering.d.ts +4 -3
  113. package/dist/src/types/viewContext.d.ts +0 -14
  114. package/dist/src/utils/domainArray.d.ts.map +1 -1
  115. package/dist/src/utils/domainArray.js +3 -0
  116. package/dist/src/utils/indexer.d.ts +3 -0
  117. package/dist/src/utils/indexer.d.ts.map +1 -1
  118. package/dist/src/utils/indexer.js +3 -0
  119. package/dist/src/utils/throttle.d.ts +4 -1
  120. package/dist/src/utils/throttle.d.ts.map +1 -1
  121. package/dist/src/utils/throttle.js +54 -23
  122. package/dist/src/utils/throttle.test.d.ts +2 -0
  123. package/dist/src/utils/throttle.test.d.ts.map +1 -0
  124. package/dist/src/utils/transition.d.ts +21 -0
  125. package/dist/src/utils/transition.d.ts.map +1 -1
  126. package/dist/src/utils/transition.js +28 -0
  127. package/dist/src/utils/ui/tooltip.d.ts.map +1 -1
  128. package/dist/src/utils/ui/tooltip.js +7 -1
  129. package/dist/src/utils/ui/tooltip.test.d.ts +2 -0
  130. package/dist/src/utils/ui/tooltip.test.d.ts.map +1 -0
  131. package/dist/src/view/axisGridView.d.ts.map +1 -1
  132. package/dist/src/view/axisGridView.js +22 -5
  133. package/dist/src/view/axisView.d.ts.map +1 -1
  134. package/dist/src/view/axisView.js +20 -5
  135. package/dist/src/view/concatView.js +3 -3
  136. package/dist/src/view/containerMutationHelper.d.ts.map +1 -1
  137. package/dist/src/view/containerMutationHelper.js +6 -2
  138. package/dist/src/view/containerView.d.ts +9 -5
  139. package/dist/src/view/containerView.d.ts.map +1 -1
  140. package/dist/src/view/containerView.js +34 -9
  141. package/dist/src/view/dataReadiness.d.ts +46 -0
  142. package/dist/src/view/dataReadiness.d.ts.map +1 -0
  143. package/dist/src/view/dataReadiness.js +267 -0
  144. package/dist/src/view/dataReadiness.test.d.ts +2 -0
  145. package/dist/src/view/dataReadiness.test.d.ts.map +1 -0
  146. package/dist/src/view/facetView.d.ts.map +1 -1
  147. package/dist/src/view/facetView.js +7 -5
  148. package/dist/src/view/flowBuilder.d.ts +5 -3
  149. package/dist/src/view/flowBuilder.d.ts.map +1 -1
  150. package/dist/src/view/flowBuilder.js +74 -7
  151. package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
  152. package/dist/src/view/gridView/gridChild.js +8 -0
  153. package/dist/src/view/gridView/gridView.d.ts.map +1 -1
  154. package/dist/src/view/gridView/gridView.js +119 -2
  155. package/dist/src/view/gridView/scrollbar.d.ts.map +1 -1
  156. package/dist/src/view/gridView/scrollbar.js +3 -0
  157. package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
  158. package/dist/src/view/gridView/selectionRect.js +20 -5
  159. package/dist/src/view/gridView/separatorView.d.ts +51 -0
  160. package/dist/src/view/gridView/separatorView.d.ts.map +1 -0
  161. package/dist/src/view/gridView/separatorView.js +275 -0
  162. package/dist/src/view/layerView.js +3 -3
  163. package/dist/src/view/layout/flexLayout.d.ts +0 -30
  164. package/dist/src/view/layout/flexLayout.d.ts.map +1 -1
  165. package/dist/src/view/layout/flexLayout.js +0 -86
  166. package/dist/src/view/paramMediator.d.ts +19 -0
  167. package/dist/src/view/paramMediator.d.ts.map +1 -1
  168. package/dist/src/view/paramMediator.js +86 -19
  169. package/dist/src/view/testUtils.d.ts.map +1 -1
  170. package/dist/src/view/testUtils.js +11 -1
  171. package/dist/src/view/unitView.d.ts +8 -13
  172. package/dist/src/view/unitView.d.ts.map +1 -1
  173. package/dist/src/view/unitView.js +127 -43
  174. package/dist/src/view/view.d.ts +34 -14
  175. package/dist/src/view/view.d.ts.map +1 -1
  176. package/dist/src/view/view.js +119 -9
  177. package/dist/src/view/viewFactory.d.ts.map +1 -1
  178. package/dist/src/view/viewFactory.js +20 -1
  179. package/dist/src/view/viewSelectors.d.ts +148 -0
  180. package/dist/src/view/viewSelectors.d.ts.map +1 -0
  181. package/dist/src/view/viewSelectors.js +773 -0
  182. package/dist/src/view/viewSelectors.test.d.ts +2 -0
  183. package/dist/src/view/viewSelectors.test.d.ts.map +1 -0
  184. package/dist/src/view/viewUtils.d.ts +0 -8
  185. package/dist/src/view/viewUtils.d.ts.map +1 -1
  186. package/dist/src/view/viewUtils.js +1 -21
  187. package/package.json +3 -3
  188. package/dist/src/scales/scaleDomainAggregator.d.ts.map +0 -1
  189. package/dist/src/scales/scaleDomainAggregator.js +0 -162
  190. package/dist/src/scales/scaleDomainAggregator.test.d.ts +0 -2
  191. package/dist/src/scales/scaleDomainAggregator.test.d.ts.map +0 -1
@@ -5,13 +5,17 @@ import {
5
5
  createMessageBox,
6
6
  } from "./genomeSpy/containerUi.js";
7
7
  import LoadingIndicatorManager from "./genomeSpy/loadingIndicatorManager.js";
8
+ import LoadingStatusRegistry from "./genomeSpy/loadingStatusRegistry.js";
8
9
  import { createViewHighlighter } from "./genomeSpy/viewHighlight.js";
9
10
  import KeyboardListenerManager from "./genomeSpy/keyboardListenerManager.js";
10
11
  import EventListenerRegistry from "./genomeSpy/eventListenerRegistry.js";
11
12
  import InputBindingManager from "./genomeSpy/inputBindingManager.js";
12
13
 
13
14
  import { calculateCanvasSize } from "./view/viewUtils.js";
14
- import { initializeViewData } from "./genomeSpy/viewDataInit.js";
15
+ import {
16
+ initializeViewData,
17
+ initializeVisibleViewData,
18
+ } from "./genomeSpy/viewDataInit.js";
15
19
  import UnitView from "./view/unitView.js";
16
20
 
17
21
  import WebGLHelper from "./gl/webGLHelper.js";
@@ -32,6 +36,7 @@ import {
32
36
  configureViewOpacity,
33
37
  } from "./genomeSpy/viewHierarchyConfig.js";
34
38
  import { exportCanvas } from "./genomeSpy/canvasExport.js";
39
+ import { validateSelectorConstraints } from "./view/viewSelectors.js";
35
40
 
36
41
  /**
37
42
  * Events that are broadcasted to all views.
@@ -47,6 +52,8 @@ export default class GenomeSpy {
47
52
  #renderCoordinator;
48
53
  /** @type {LoadingIndicatorManager} */
49
54
  #loadingIndicatorManager;
55
+ /** @type {LoadingStatusRegistry} */
56
+ #loadingStatusRegistry;
50
57
  /** @type {InputBindingManager} */
51
58
  #inputBindingManager;
52
59
  /** @type {InteractionController} */
@@ -234,12 +241,8 @@ export default class GenomeSpy {
234
241
  }
235
242
 
236
243
  #prepareContainer() {
237
- const {
238
- canvasWrapper,
239
- loadingMessageElement,
240
- loadingIndicatorsElement,
241
- tooltip,
242
- } = createContainerUi(this.container);
244
+ const { canvasWrapper, loadingIndicatorsElement, tooltip } =
245
+ createContainerUi(this.container);
243
246
 
244
247
  this.#glHelper = new WebGLHelper(
245
248
  canvasWrapper,
@@ -250,16 +253,11 @@ export default class GenomeSpy {
250
253
  { powerPreference: this.options.powerPreference ?? "default" }
251
254
  );
252
255
 
253
- // The initial loading message that is shown until the first frame is rendered
254
- this.loadingMessageElement = loadingMessageElement;
255
- // A container for loading indicators (for lazy data sources.)
256
- // These could alternatively be included in the view hierarchy,
257
- // but it's easier this way – particularly if we want to show
258
- // some fancy animated spinners.
259
- this.loadingIndicatorsElement = loadingIndicatorsElement;
260
256
  this.tooltip = tooltip;
257
+ this.#loadingStatusRegistry = new LoadingStatusRegistry();
261
258
  this.#loadingIndicatorManager = new LoadingIndicatorManager(
262
- loadingIndicatorsElement
259
+ loadingIndicatorsElement,
260
+ this.#loadingStatusRegistry
263
261
  );
264
262
  }
265
263
 
@@ -282,6 +280,8 @@ export default class GenomeSpy {
282
280
 
283
281
  this.#inputBindingManager.remove();
284
282
 
283
+ this.#loadingIndicatorManager.destroy();
284
+
285
285
  while (this.container.firstChild) {
286
286
  this.container.firstChild.remove();
287
287
  }
@@ -308,8 +308,11 @@ export default class GenomeSpy {
308
308
  }
309
309
 
310
310
  #createViewContext() {
311
+ const dataFlow = new DataFlow();
312
+ dataFlow.loadingStatusRegistry = this.#loadingStatusRegistry;
313
+
311
314
  return createViewContext({
312
- dataFlow: new DataFlow(),
315
+ dataFlow,
313
316
  glHelper: this.#glHelper,
314
317
  animator: this.animator,
315
318
  genomeStore: this.genomeStore,
@@ -318,12 +321,6 @@ export default class GenomeSpy {
318
321
  getNamedDataFromProvider: this.getNamedDataFromProvider.bind(this),
319
322
  getCurrentHover: () =>
320
323
  this.#interactionController.getCurrentHover(),
321
- setDataLoadingStatus: (view, status, detail) =>
322
- this.#loadingIndicatorManager.setDataLoadingStatus(
323
- view,
324
- status,
325
- detail
326
- ),
327
324
  addKeyboardListener: (type, listener) => {
328
325
  // TODO: Listeners should be called only when the mouse pointer is inside the
329
326
  // container or the app covers the full document.
@@ -375,6 +372,8 @@ export default class GenomeSpy {
375
372
  VIEW_ROOT_NAME
376
373
  );
377
374
 
375
+ this.#loadingStatusRegistry.set(this.viewRoot, "loading");
376
+
378
377
  this.#canvasWrapper.style.flexGrow =
379
378
  this.viewRoot.getSize().height.grow > 0 ? "1" : "0";
380
379
 
@@ -382,6 +381,7 @@ export default class GenomeSpy {
382
381
 
383
382
  configureViewHierarchy(this.viewRoot);
384
383
  configureViewOpacity(this.viewRoot);
384
+ this.#logSelectorConstraintWarnings();
385
385
 
386
386
  // We should now have a complete view hierarchy. Let's update the canvas size
387
387
  // and ensure that the loading message is visible.
@@ -402,6 +402,17 @@ export default class GenomeSpy {
402
402
  this.#setupDpr();
403
403
  }
404
404
 
405
+ #logSelectorConstraintWarnings() {
406
+ const issues = validateSelectorConstraints(this.viewRoot);
407
+ if (!issues.length) {
408
+ return;
409
+ }
410
+
411
+ for (const issue of issues) {
412
+ console.warn("Selector constraints warning:", issue.message);
413
+ }
414
+ }
415
+
405
416
  /**
406
417
  * @param {import("./types/viewContext.js").default} context
407
418
  */
@@ -432,6 +443,7 @@ export default class GenomeSpy {
432
443
  * @returns {Promise<boolean>} true if the launch was successful
433
444
  */
434
445
  async launch() {
446
+ let launched = false;
435
447
  try {
436
448
  this.#prepareContainer();
437
449
 
@@ -442,6 +454,7 @@ export default class GenomeSpy {
442
454
  this.computeLayout();
443
455
  this.animator.requestRender();
444
456
 
457
+ launched = true;
445
458
  return true;
446
459
  } catch (reason) {
447
460
  const message = `${
@@ -453,16 +466,42 @@ export default class GenomeSpy {
453
466
  createMessageBox(this.container, message);
454
467
  }
455
468
 
469
+ if (this.viewRoot) {
470
+ this.#loadingStatusRegistry.set(
471
+ this.viewRoot,
472
+ "error",
473
+ message
474
+ );
475
+ }
476
+
456
477
  return false;
457
478
  } finally {
458
479
  this.#canvasWrapper.classList.remove("loading");
459
- // Transition listener doesn't appear to work on observablehq
460
- window.setTimeout(() => {
461
- this.loadingMessageElement.style.display = "none";
462
- }, 2000);
480
+ if (launched && this.viewRoot) {
481
+ this.#loadingStatusRegistry.set(this.viewRoot, "complete");
482
+ }
463
483
  }
464
484
  }
465
485
 
486
+ async initializeVisibleViewData() {
487
+ if (!this.viewRoot) {
488
+ return;
489
+ }
490
+
491
+ await initializeVisibleViewData(
492
+ this.viewRoot,
493
+ this.viewRoot.context.dataFlow,
494
+ this.viewRoot.context.fontManager
495
+ );
496
+
497
+ // Visibility toggles can change sizes; ensure layout is recomputed even
498
+ // when callers don't explicitly request it.
499
+ this.viewRoot._invalidateCacheByPrefix("size", "progeny");
500
+ this.#glHelper.invalidateSize();
501
+ this.computeLayout();
502
+ this.animator.requestRender();
503
+ }
504
+
466
505
  registerMouseEvents() {
467
506
  this.#interactionController.registerMouseEvents();
468
507
  }
@@ -530,7 +569,10 @@ export default class GenomeSpy {
530
569
  /** @type {UnitView[]} */
531
570
  const views = [];
532
571
  this.viewRoot.visit((view) => {
533
- if (view instanceof UnitView && view.getDataAccessor("search")) {
572
+ if (
573
+ view instanceof UnitView &&
574
+ view.getSearchAccessors().length > 0
575
+ ) {
534
576
  views.push(view);
535
577
  }
536
578
  });
@@ -1 +1 @@
1
- {"version":3,"file":"dataToVertices.d.ts","sourceRoot":"","sources":["../../../src/gl/dataToVertices.js"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH;IACI;;;OAGG;IAEH;;;;;;OAMG;IACH,mDALG;QAAsE,QAAQ,EAAtE,MAAM,CAAC,OAAO,oBAAoB,EAAE,OAAO,wCAAU;QACnC,UAAU,GAA5B,MAAM,EAAE;QACQ,WAAW,GAA3B,MAAM;KAEhB,EAqFA;IAnFG,8FAAwB;IAIxB,sGAQK;IAQL,0BAAoC;IAEpC,8BAAoD;IAyDpD,mBAAmB;IAEnB,yFAAyF;IACzF,UADW,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CACkB;IAGrD;;;;OAIG;IACH,mBAFW,GAAG,QAcb;IAED;;OAEG;IACH,oBAFW,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,QAM5B;IAED;;;OAGG;IACH,cAHW,GAAG,QACH,MAAM,EAAE,kCAYlB;IAED;;;;OAIG;IACH,sBAJW,OAAO,qBAAqB,EAAE,IAAI,OAClC,MAAM,OACN,MAAM,QAgEhB;IAED;;;;;OAKG;IACH,mBAFW,OAAO,qBAAqB,EAAE,KAAK,QAI7C;IAhEO;;;MAAyB;IAkEjC;QAEQ,kJAAkJ;gBAAvI,MAAM,CAAC,MAAM,EAAE;YAAC,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,CAAC;YAAC,aAAa,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAC,CAAC;QAE9I,8BAA8B;;QAE9B,8CAA8C;;;MAIrD;CACJ;AAED;IACI;;;;;;OAMG;IACH,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EA8BA;IAnBG,qBAkBW;CA8BlB;AAED;IACI;;;;;;;;;OASG;IACH,sFAPG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,qBAAqB,GAArC,MAAM;QAEY,YAAY,GAA9B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAuBA;IARG,uBAAgC;IAEhC,8BAA8D;IAE9D,6CAA+D;IAC/D,4CAA6D;CA6CpE;AAED;IACI;;;;;;OAMG;IACH,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAQA;CACJ;AAED;IACI;;;;;OAKG;IACH,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAQA;CAYJ;AAED;IACI;;;;;;;;;OASG;IACH,+EAPG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACkD,WAAW,EAArE,OAAO,2BAA2B,EAAE,aAAa;QACrB,UAAU,EAAtC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;QACH,aAAa,GAA7B,MAAM;QACW,WAAW,GAA5B,OAAO;KAAsB,EA6CvC;IA9BG,4DAA2B;IAC3B,2DAA0B;IAE1B,gCAA4B;IAO5B,qCAAqC;IACrC,cADW,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAMf;IAElB,oDAGC;IACD,qDAGC;IAED,8CAAiE;CAgJxE;;;;;;;;YAjnBS,MAAM;;;;WACN,MAAM;YACN,OAAO,yBAAyB,EAAE,MAAM;;yBAjBzB,mBAAmB"}
1
+ {"version":3,"file":"dataToVertices.d.ts","sourceRoot":"","sources":["../../../src/gl/dataToVertices.js"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH;IACI;;;OAGG;IAEH;;;;;;OAMG;IACH,mDALG;QAAsE,QAAQ,EAAtE,MAAM,CAAC,OAAO,oBAAoB,EAAE,OAAO,wCAAU;QACnC,UAAU,GAA5B,MAAM,EAAE;QACQ,WAAW,GAA3B,MAAM;KAEhB,EAiGA;IA/FG,8FAAwB;IAIxB,sGAQK;IAQL,0BAAoC;IAEpC,8BAAoD;IAqEpD,mBAAmB;IAEnB,yFAAyF;IACzF,UADW,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CACkB;IAGrD;;;;OAIG;IACH,mBAFW,GAAG,QAcb;IAED;;OAEG;IACH,oBAFW,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,QAM5B;IAED;;;OAGG;IACH,cAHW,GAAG,QACH,MAAM,EAAE,kCAYlB;IAED;;;;OAIG;IACH,sBAJW,OAAO,qBAAqB,EAAE,IAAI,OAClC,MAAM,OACN,MAAM,QAgEhB;IAED;;;;;OAKG;IACH,mBAFW,OAAO,qBAAqB,EAAE,KAAK,QAI7C;IAhEO;;;MAAyB;IAkEjC;QAEQ,kJAAkJ;gBAAvI,MAAM,CAAC,MAAM,EAAE;YAAC,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,CAAC;YAAC,aAAa,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAC,CAAC;QAE9I,8BAA8B;;QAE9B,8CAA8C;;;MAIrD;CACJ;AAED;IACI;;;;;;OAMG;IACH,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EA8BA;IAnBG,qBAkBW;CA8BlB;AAED;IACI;;;;;;;;;OASG;IACH,sFAPG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,qBAAqB,GAArC,MAAM;QAEY,YAAY,GAA9B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAuBA;IARG,uBAAgC;IAEhC,8BAA8D;IAE9D,6CAA+D;IAC/D,4CAA6D;CA6CpE;AAED;IACI;;;;;;OAMG;IACH,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAQA;CACJ;AAED;IACI;;;;;OAKG;IACH,gDAJG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACQ,QAAQ,GAAxB,MAAM;KAChB,EAQA;CAYJ;AAED;IACI;;;;;;;;;OASG;IACH,+EAPG;QAAwC,QAAQ,EAAxC,MAAM,CAAC,MAAM,wCAAU;QACN,UAAU,EAA3B,MAAM,EAAE;QACkD,WAAW,EAArE,OAAO,2BAA2B,EAAE,aAAa;QACrB,UAAU,EAAtC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;QACH,aAAa,GAA7B,MAAM;QACW,WAAW,GAA5B,OAAO;KAAsB,EA6CvC;IA9BG,4DAA2B;IAC3B,2DAA0B;IAE1B,gCAA4B;IAO5B,qCAAqC;IACrC,cADW,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAMf;IAElB,oDAGC;IACD,qDAGC;IAED,8CAAiE;CAgJxE;;;;;;;;YA7nBS,MAAM;;;;WACN,MAAM;YACN,OAAO,yBAAyB,EAAE,MAAM;;yBAjBzB,mBAAmB"}
@@ -82,11 +82,23 @@ export class GeometryBuilder {
82
82
  getAttributeAndArrayTypes(scale, channel);
83
83
  const largeHpArray = [0, 0];
84
84
 
85
- /** @type {ReturnType<typeof createIndexer>} */
85
+ /** @type {ReturnType<typeof createIndexer> | undefined} */
86
86
  let indexer;
87
- if (scale && discrete && "domain" in scale) {
88
- indexer = createIndexer();
89
- indexer.addAll(scale.domain());
87
+ if (scale && discrete) {
88
+ if (
89
+ "props" in scale &&
90
+ /** @type {any} */ (scale.props).domainIndexer
91
+ ) {
92
+ // domainIndexer is a runtime-only extension, not in VegaScale typings.
93
+ indexer = /** @type {any} */ (scale.props).domainIndexer;
94
+ } else if ("domain" in scale) {
95
+ indexer = createIndexer();
96
+ indexer.addAll(scale.domain());
97
+ } else {
98
+ throw new Error(
99
+ "Missing domain indexer for discrete scale."
100
+ );
101
+ }
90
102
  }
91
103
 
92
104
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
@@ -940,6 +940,17 @@ export default class Mark {
940
940
  * initiated. The idea is to allow for parallel background compilation.
941
941
  */
942
942
  finalizeGraphicsInitialization() {
943
+ // Allow duplicate finalization calls when multiple init paths overlap.
944
+ if (this.programInfo) {
945
+ return;
946
+ }
947
+
948
+ if (!this.programStatus) {
949
+ throw new Error(
950
+ "No program status found! " + this.unitView.getPathString()
951
+ );
952
+ }
953
+
943
954
  const error = this.programStatus.getProgramErrors();
944
955
  if (error) {
945
956
  if (error.detail) {
@@ -1290,21 +1301,17 @@ export default class Mark {
1290
1301
  const locationSetter = this.programInfo.uniformSetters.uSampleFacet;
1291
1302
 
1292
1303
  if (opts && locationSetter) {
1293
- const pos = opts.locSize ? opts.locSize.location : 0.0;
1294
- const height = opts.locSize ? opts.locSize.size : 1.0;
1304
+ const scale = opts.pixelToUnit;
1305
+ const pos = opts.locSize.location * scale;
1306
+ const height = opts.locSize.size * scale;
1295
1307
 
1296
1308
  if (pos > 1.0 || pos + height < 0.0) {
1297
1309
  // Not visible
1298
1310
  return false;
1299
1311
  }
1300
1312
 
1301
- const targetPos = opts.targetLocSize
1302
- ? opts.targetLocSize.location
1303
- : pos;
1304
- const targetHeight = opts.targetLocSize
1305
- ? opts.targetLocSize.size
1306
- : height;
1307
-
1313
+ // No target locSize in the current API. Keep a consistent shader path
1314
+ // by repeating the current position/height.
1308
1315
  // Use WebGL directly, because twgl uses gl.uniform4fv, which has an
1309
1316
  // inferior performance. Based on profiling, this optimization gives
1310
1317
  // a significant performance boost.
@@ -1313,8 +1320,8 @@ export default class Mark {
1313
1320
  locationSetter.location, // TODO: Make a twgl pull request to fix typing
1314
1321
  pos,
1315
1322
  height,
1316
- targetPos,
1317
- targetHeight
1323
+ pos,
1324
+ height
1318
1325
  );
1319
1326
  }
1320
1327
 
@@ -38,7 +38,7 @@ export function fixPositional(encoding, channel) {
38
38
  if (!secondary) {
39
39
  if (primary.type == "quantitative") {
40
40
  // Bar plot, anchor the other end to zero
41
- secondary = { datum: 0, contributesToScaleDomain: false };
41
+ secondary = { datum: 0, domainInert: true };
42
42
  } else {
43
43
  secondary = { ...primary };
44
44
 
@@ -6,5 +6,10 @@ export function configureScale(_: any, scale: any, logger: any): void;
6
6
  * @returns {import("../encoder/encoder.js").VegaScale}
7
7
  */
8
8
  export default function createScale(_: import("../spec/scale.js").Scale, logger: any): import("../encoder/encoder.js").VegaScale;
9
- export function configureDomain(scale: any, _: any, logger: any): any;
9
+ export function configureDomain(scale: any, _: any, logger: any): {
10
+ domain: any;
11
+ count: any;
12
+ ordinalUnknown: any;
13
+ applyOrdinalUnknown: boolean;
14
+ };
10
15
  //# sourceMappingURL=scale.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scale.d.ts","sourceRoot":"","sources":["../../../src/scale/scale.js"],"names":[],"mappings":"AAoHA,sEAmBC;AAED;;;;;GAKG;AACH,uCAJW,OAAO,kBAAkB,EAAE,KAAK,UAChC,GAAC,GACC,OAAO,uBAAuB,EAAE,SAAS,CAoBrD;AAgCD,sEAuEC"}
1
+ {"version":3,"file":"scale.d.ts","sourceRoot":"","sources":["../../../src/scale/scale.js"],"names":[],"mappings":"AAgIA,sEAuBC;AAED;;;;;GAKG;AACH,uCAJW,OAAO,kBAAkB,EAAE,KAAK,UAChC,GAAC,GACC,OAAO,uBAAuB,EAAE,SAAS,CAoBrD;AA4CD;;;;;EAuGC"}
@@ -11,8 +11,20 @@
11
11
  /* eslint-disable */
12
12
  // @ts-nocheck
13
13
 
14
- // This file is a mess
15
- // TODO: Fix types, etc.
14
+ /*
15
+ * Rewrite rationale (non-perf):
16
+ * - This module mixes spec-level policy, vega-scale helpers, and D3 scale
17
+ * mutability. The combination works but is clunky to maintain and hard to
18
+ * integrate with higher-level orchestration like ScaleResolution.
19
+ * - Side-effectful configuration and implicit defaults make the data flow
20
+ * difficult to reason about and to test in isolation.
21
+ *
22
+ * Why not rewrite yet:
23
+ * - Behavior is subtle and well-tested; a rewrite is risky without a clear
24
+ * contract for the pure inputs/outputs and their callers.
25
+ * - It depends on D3 scale semantics (copy, unknown, interpolate, etc.), so any
26
+ * refactor must preserve those semantics explicitly.
27
+ */
16
28
 
17
29
  import { tickCount } from "./ticks.js";
18
30
  import {
@@ -128,11 +140,15 @@ export function configureScale(_, scale, logger) {
128
140
  }
129
141
  }
130
142
 
131
- configureRange(
132
- scale,
133
- _,
134
- configureBins(scale, _, configureDomain(scale, _, logger))
135
- );
143
+ const domainConfig = configureDomain(scale, _, logger);
144
+ if (domainConfig.domain) {
145
+ scale.domain(domainConfig.domain);
146
+ }
147
+ if (domainConfig.applyOrdinalUnknown) {
148
+ scale.unknown(domainConfig.ordinalUnknown);
149
+ }
150
+
151
+ configureRange(scale, _, configureBins(scale, _, domainConfig.count));
136
152
  }
137
153
 
138
154
  /**
@@ -191,24 +207,62 @@ function isContinuousColor(_) {
191
207
  );
192
208
  }
193
209
 
210
+ function copyScaleForDomain(scale) {
211
+ if (!scale.copy) {
212
+ return scale;
213
+ }
214
+
215
+ const copy = scale.copy();
216
+ if (copy.type == null && scale.type != null) {
217
+ copy.type = scale.type;
218
+ }
219
+ return copy;
220
+ }
221
+
194
222
  export function configureDomain(scale, _, logger) {
195
223
  if (!scale.domain) {
196
- return 0;
224
+ return {
225
+ domain: null,
226
+ count: 0,
227
+ ordinalUnknown: undefined,
228
+ applyOrdinalUnknown: false,
229
+ };
197
230
  }
198
231
 
199
232
  logger = ensureLogger(logger);
200
233
 
234
+ const workingScale = copyScaleForDomain(scale);
235
+
201
236
  // check raw domain, if provided use that and exit early
202
- var raw = rawDomain(scale, _.domainRaw, logger);
203
- if (raw > -1) return raw;
237
+ var raw = rawDomain(workingScale, _.domainRaw, logger);
238
+ if (raw > -1) {
239
+ return {
240
+ domain: workingScale.domain(),
241
+ count: raw,
242
+ ordinalUnknown:
243
+ workingScale.type === Ordinal
244
+ ? _.domainImplicit
245
+ ? scaleImplicit
246
+ : undefined
247
+ : undefined,
248
+ applyOrdinalUnknown: false,
249
+ };
250
+ }
204
251
 
205
252
  var domain = _.domain,
206
- type = scale.type,
207
- zero = _.zero || (_.zero === undefined && includeZero(scale)),
253
+ type = workingScale.type,
254
+ zero = _.zero || (_.zero === undefined && includeZero(workingScale)),
208
255
  n,
209
256
  mid;
210
257
 
211
- if (!domain) return 0;
258
+ if (!domain) {
259
+ return {
260
+ domain: null,
261
+ count: 0,
262
+ ordinalUnknown: undefined,
263
+ applyOrdinalUnknown: false,
264
+ };
265
+ }
212
266
 
213
267
  // adjust continuous domain for minimum pixel padding
214
268
  if (includePad(type) && _.padding && domain[0] !== peek(domain)) {
@@ -247,21 +301,27 @@ export function configureDomain(scale, _, logger) {
247
301
  }
248
302
 
249
303
  // set the scale domain
250
- scale.domain(domainCheck(type, domain, logger));
251
-
252
- // if ordinal scale domain is defined, prevent implicit
253
- // domain construction as side-effect of scale lookup
254
- if (type === Ordinal) {
255
- scale.unknown(_.domainImplicit ? scaleImplicit : undefined);
256
- }
304
+ workingScale.domain(domainCheck(type, domain, logger));
257
305
 
258
306
  // perform 'nice' adjustment as requested
259
- if (_.nice && scale.nice) {
260
- scale.nice((_.nice !== true && tickCount(scale, _.nice)) || null);
307
+ if (_.nice && workingScale.nice) {
308
+ workingScale.nice(
309
+ (_.nice !== true && tickCount(workingScale, _.nice)) || null
310
+ );
261
311
  }
262
312
 
263
313
  // return the cardinality of the domain
264
- return domain.length;
314
+ return {
315
+ domain: workingScale.domain(),
316
+ count: domain.length,
317
+ ordinalUnknown:
318
+ type === Ordinal
319
+ ? _.domainImplicit
320
+ ? scaleImplicit
321
+ : undefined
322
+ : undefined,
323
+ applyOrdinalUnknown: type === Ordinal,
324
+ };
265
325
  }
266
326
 
267
327
  function rawDomain(scale, raw, logger) {
@@ -1 +1 @@
1
- {"version":3,"file":"axisResolution.d.ts","sourceRoot":"","sources":["../../../src/scales/axisResolution.js"],"names":[],"mappings":"AAcA;;;;;;;GAOG;AACH;IASI;;OAEG;IACH,qBAFW,OAAO,oBAAoB,EAAE,wBAAwB,EAI/D;IADG,+DAAsB;IAG1B,2BAGC;IAiCD;;;OAGG;IACH,uBAHW,oBAAoB,GAClB,MAAM,OAAO,CAQzB;IAED;;;OAGG;IACH,qBAHW,oBAAoB,GAClB,OAAO,CAQnB;IAED,qDAuBC;IAED,mBAyDC;;CACJ;iCAtK6D,CAAC,SAAlD,OAAQ,oBAAoB,EAAE,iBAAkB;UAGnD,OAAO,qBAAqB,EAAE,OAAO;aACrC,CAAC;gBACD,OAAO,oBAAoB,EAAE,mBAAmB"}
1
+ {"version":3,"file":"axisResolution.d.ts","sourceRoot":"","sources":["../../../src/scales/axisResolution.js"],"names":[],"mappings":"AAcA;;;;;;;GAOG;AACH;IASI;;OAEG;IACH,qBAFW,OAAO,oBAAoB,EAAE,wBAAwB,EAI/D;IADG,+DAAsB;IAG1B,2BAGC;IAiCD;;;OAGG;IACH,uBAHW,oBAAoB,GAClB,MAAM,OAAO,CAQzB;IAED;;;OAGG;IACH,qBAHW,oBAAoB,GAClB,OAAO,CAQnB;IAED,qDAuBC;IAED,mBAmEC;;CACJ;iCAhL6D,CAAC,SAAlD,OAAQ,oBAAoB,EAAE,iBAAkB;UAGnD,OAAO,qBAAqB,EAAE,OAAO;aACrC,CAAC;gBACD,OAAO,oBAAoB,EAAE,mBAAmB"}
@@ -137,6 +137,9 @@ export default class AxisResolution {
137
137
 
138
138
  return {
139
139
  member,
140
+ axisTitle:
141
+ // TODO: Proper type guard
142
+ "axis" in channelDef ? channelDef.axis?.title : undefined,
140
143
  explicitTitle: coalesce(
141
144
  // TODO: Proper type guard
142
145
  "axis" in channelDef ? channelDef.axis?.title : undefined,
@@ -150,6 +153,13 @@ export default class AxisResolution {
150
153
  };
151
154
 
152
155
  const titles = Array.from(this.#members).map(computeTitle);
156
+ const explicitAxisTitle = titles
157
+ .map((title) => title.axisTitle)
158
+ .find((title) => title !== undefined);
159
+
160
+ if (explicitAxisTitle !== undefined) {
161
+ return explicitAxisTitle;
162
+ }
153
163
 
154
164
  // Skip implicit secondary channel titles if the primary channel has an explicit title
155
165
  const filteredTitles = titles.filter((title) => {
@@ -4,16 +4,18 @@
4
4
  * @typedef {import("../spec/scale.js").ScalarDomain} ScalarDomain
5
5
  * @typedef {import("./scaleResolution.js").ScaleResolutionMember} ScaleResolutionMember
6
6
  */
7
- export default class ScaleDomainAggregator {
7
+ export default class DomainPlanner {
8
8
  /**
9
9
  * @param {object} options
10
10
  * @param {() => Set<ScaleResolutionMember>} options.getMembers
11
+ * @param {() => Set<ScaleResolutionMember>} [options.getDataMembers]
11
12
  * @param {() => import("../spec/channel.js").Type} options.getType
12
13
  * @param {() => number[]} options.getLocusExtent
13
14
  * @param {(interval: ScalarDomain | ComplexDomain) => number[]} options.fromComplexInterval
14
15
  */
15
- constructor({ getMembers, getType, getLocusExtent, fromComplexInterval }: {
16
+ constructor({ getMembers, getDataMembers, getType, getLocusExtent, fromComplexInterval, }: {
16
17
  getMembers: () => Set<ScaleResolutionMember>;
18
+ getDataMembers?: () => Set<ScaleResolutionMember>;
17
19
  getType: () => import("../spec/channel.js").Type;
18
20
  getLocusExtent: () => number[];
19
21
  fromComplexInterval: (interval: ScalarDomain | ComplexDomain) => number[];
@@ -23,6 +25,7 @@ export default class ScaleDomainAggregator {
23
25
  */
24
26
  get initialDomainSnapshot(): any[];
25
27
  hasConfiguredDomain(): boolean;
28
+ invalidateConfiguredDomain(): void;
26
29
  /**
27
30
  * Returns the configured domain or a data-derived/default domain.
28
31
  *
@@ -39,9 +42,9 @@ export default class ScaleDomainAggregator {
39
42
  /**
40
43
  * Extracts and unions the data domains of all participating views.
41
44
  *
42
- * @return {DomainArray}
45
+ * @return {DomainArray | undefined}
43
46
  */
44
- getDataDomain(): DomainArray;
47
+ getDataDomain(): DomainArray | undefined;
45
48
  /**
46
49
  * @param {import("../types/encoder.js").VegaScale} scale
47
50
  * @param {boolean} domainWasInitialized
@@ -54,4 +57,4 @@ export type DomainArray = import("../utils/domainArray.js").DomainArray;
54
57
  export type ComplexDomain = import("../spec/scale.js").ComplexDomain;
55
58
  export type ScalarDomain = import("../spec/scale.js").ScalarDomain;
56
59
  export type ScaleResolutionMember = import("./scaleResolution.js").ScaleResolutionMember;
57
- //# sourceMappingURL=scaleDomainAggregator.d.ts.map
60
+ //# sourceMappingURL=domainPlanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domainPlanner.d.ts","sourceRoot":"","sources":["../../../src/scales/domainPlanner.js"],"names":[],"mappings":"AAOA;;;;;GAKG;AAEH;IA2BI;;;;;;;OAOG;IACH,2FANG;QAAkD,UAAU,EAApD,MAAM,GAAG,CAAC,qBAAqB,CAAC;QACW,cAAc,GAAzD,MAAM,GAAG,CAAC,qBAAqB,CAAC;QACiB,OAAO,EAAxD,MAAM,OAAO,oBAAoB,EAAE,IAAI;QACf,cAAc,EAAtC,MAAM,MAAM,EAAE;QACgD,mBAAmB,EAAjF,CAAC,QAAQ,EAAE,YAAY,GAAG,aAAa,KAAK,MAAM,EAAE;KAC9D,EAaA;IAED;;OAEG;IACH,6BAFa,GAAG,EAAE,CAIjB;IAED,+BAEC;IAED,mCAEC;IAED;;;;;OAKG;IACH,iDAHW,OAAO,GACL,GAAG,EAAE,CAYjB;IAED;;;;OAIG;IACH,uBAFY,WAAW,CActB;IAED;;;;OAIG;IACH,iBAFY,WAAW,GAAG,SAAS,CAQlC;IAED;;;;OAIG;IACH,4BAJW,OAAO,qBAAqB,EAAE,SAAS,wBACvC,OAAO,GACL,OAAO,CAgBnB;;CAkCJ;0BA7KY,OAAO,yBAAyB,EAAE,WAAW;4BAC7C,OAAO,kBAAkB,EAAE,aAAa;2BACxC,OAAO,kBAAkB,EAAE,YAAY;oCACvC,OAAO,sBAAsB,EAAE,qBAAqB"}