@genome-spy/core 0.78.0 → 0.79.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 (289) hide show
  1. package/dist/bundle/{browser-KWU9rWZT.js → browser-CETrb2cm.js} +53 -33
  2. package/dist/bundle/esm-BdLYkz-m.js +248 -0
  3. package/dist/bundle/esm-BwiDsqSb.js +1367 -0
  4. package/dist/bundle/esm-CDFd1cjk.js +441 -0
  5. package/dist/bundle/{esm-DVOHLB1e.js → esm-CTUHLDbv.js} +30 -30
  6. package/dist/bundle/{esm-NIYEaYkc.js → esm-Cx-EbkOj.js} +13 -13
  7. package/dist/bundle/esm-DlYGqi79.js +128 -0
  8. package/dist/bundle/{esm-BygJiwh0.js → esm-k9p3oHkt.js} +133 -158
  9. package/dist/bundle/{esm-CT3ygiMq.js → esm-zAZJQO6D.js} +226 -212
  10. package/dist/bundle/index.es.js +14840 -11661
  11. package/dist/bundle/index.js +119 -108
  12. package/dist/bundle/{parquetRead-DG_-F5j5.js → parquetRead-Cad1SOVV.js} +473 -399
  13. package/dist/schema.json +18940 -6914
  14. package/dist/src/config/axisConfig.d.ts +2 -2
  15. package/dist/src/config/axisConfig.d.ts.map +1 -1
  16. package/dist/src/config/axisConfig.js +28 -44
  17. package/dist/src/config/configLayers.d.ts +45 -0
  18. package/dist/src/config/configLayers.d.ts.map +1 -0
  19. package/dist/src/config/configLayers.js +110 -0
  20. package/dist/src/config/defaultConfig.d.ts.map +1 -1
  21. package/dist/src/config/defaultConfig.js +8 -1
  22. package/dist/src/config/defaults/legendDefaults.d.ts +14 -0
  23. package/dist/src/config/defaults/legendDefaults.d.ts.map +1 -0
  24. package/dist/src/config/defaults/legendDefaults.js +46 -0
  25. package/dist/src/config/defaults/titleDefaults.d.ts.map +1 -1
  26. package/dist/src/config/defaults/titleDefaults.js +26 -18
  27. package/dist/src/config/legendConfig.d.ts +11 -0
  28. package/dist/src/config/legendConfig.d.ts.map +1 -0
  29. package/dist/src/config/legendConfig.js +63 -0
  30. package/dist/src/config/styleUtils.d.ts +8 -2
  31. package/dist/src/config/styleUtils.d.ts.map +1 -1
  32. package/dist/src/config/styleUtils.js +25 -1
  33. package/dist/src/config/themes.d.ts.map +1 -1
  34. package/dist/src/config/themes.js +21 -2
  35. package/dist/src/config/titleConfig.d.ts.map +1 -1
  36. package/dist/src/config/titleConfig.js +2 -18
  37. package/dist/src/data/collector.d.ts.map +1 -1
  38. package/dist/src/data/collector.js +40 -18
  39. package/dist/src/data/flowInit.d.ts +6 -0
  40. package/dist/src/data/flowInit.d.ts.map +1 -1
  41. package/dist/src/data/flowInit.js +1 -1
  42. package/dist/src/data/flowNode.d.ts +32 -0
  43. package/dist/src/data/flowNode.d.ts.map +1 -1
  44. package/dist/src/data/flowNode.js +59 -0
  45. package/dist/src/data/sources/lazy/bamSource.d.ts +0 -1
  46. package/dist/src/data/sources/lazy/bamSource.d.ts.map +1 -1
  47. package/dist/src/data/sources/lazy/bamSource.js +39 -30
  48. package/dist/src/data/sources/lazy/bigBedSource.d.ts +0 -10
  49. package/dist/src/data/sources/lazy/bigBedSource.d.ts.map +1 -1
  50. package/dist/src/data/sources/lazy/bigBedSource.js +127 -62
  51. package/dist/src/data/sources/lazy/bigWigSource.d.ts +2 -2
  52. package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
  53. package/dist/src/data/sources/lazy/bigWigSource.js +234 -81
  54. package/dist/src/data/sources/lazy/gff3Source.d.ts +7 -3
  55. package/dist/src/data/sources/lazy/gff3Source.d.ts.map +1 -1
  56. package/dist/src/data/sources/lazy/gff3Source.js +7 -8
  57. package/dist/src/data/sources/lazy/indexedFastaSource.d.ts +1 -1
  58. package/dist/src/data/sources/lazy/indexedFastaSource.d.ts.map +1 -1
  59. package/dist/src/data/sources/lazy/indexedFastaSource.js +28 -19
  60. package/dist/src/data/sources/lazy/legendEntriesSource.d.ts +24 -0
  61. package/dist/src/data/sources/lazy/legendEntriesSource.d.ts.map +1 -0
  62. package/dist/src/data/sources/lazy/legendEntriesSource.js +217 -0
  63. package/dist/src/data/sources/lazy/legendGradientSource.d.ts +30 -0
  64. package/dist/src/data/sources/lazy/legendGradientSource.d.ts.map +1 -0
  65. package/dist/src/data/sources/lazy/legendGradientSource.js +388 -0
  66. package/dist/src/data/sources/lazy/mockLazySource.d.ts +4 -1
  67. package/dist/src/data/sources/lazy/mockLazySource.d.ts.map +1 -1
  68. package/dist/src/data/sources/lazy/mockLazySource.js +49 -4
  69. package/dist/src/data/sources/lazy/registerCoreLazySources.js +2 -0
  70. package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts.map +1 -1
  71. package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +3 -4
  72. package/dist/src/data/sources/lazy/tabixSource.d.ts +9 -4
  73. package/dist/src/data/sources/lazy/tabixSource.d.ts.map +1 -1
  74. package/dist/src/data/sources/lazy/tabixSource.js +201 -70
  75. package/dist/src/data/sources/lazy/tabixTsvSource.d.ts +2 -3
  76. package/dist/src/data/sources/lazy/tabixTsvSource.d.ts.map +1 -1
  77. package/dist/src/data/sources/lazy/tabixTsvSource.js +14 -12
  78. package/dist/src/data/sources/lazy/vcfSource.d.ts +7 -3
  79. package/dist/src/data/sources/lazy/vcfSource.d.ts.map +1 -1
  80. package/dist/src/data/sources/lazy/vcfSource.js +7 -8
  81. package/dist/src/data/sources/urlDescriptor.d.ts +165 -0
  82. package/dist/src/data/sources/urlDescriptor.d.ts.map +1 -0
  83. package/dist/src/data/sources/urlDescriptor.js +473 -0
  84. package/dist/src/data/sources/urlDescriptorController.d.ts +25 -0
  85. package/dist/src/data/sources/urlDescriptorController.d.ts.map +1 -0
  86. package/dist/src/data/sources/urlDescriptorController.js +72 -0
  87. package/dist/src/data/sources/urlDescriptorState.d.ts +47 -0
  88. package/dist/src/data/sources/urlDescriptorState.d.ts.map +1 -0
  89. package/dist/src/data/sources/urlDescriptorState.js +129 -0
  90. package/dist/src/data/sources/urlSource.d.ts.map +1 -1
  91. package/dist/src/data/sources/urlSource.js +101 -61
  92. package/dist/src/data/transforms/packLegendLabels.d.ts +21 -0
  93. package/dist/src/data/transforms/packLegendLabels.d.ts.map +1 -0
  94. package/dist/src/data/transforms/packLegendLabels.js +189 -0
  95. package/dist/src/data/transforms/transformFactory.d.ts.map +1 -1
  96. package/dist/src/data/transforms/transformFactory.js +4 -0
  97. package/dist/src/data/transforms/truncateText.d.ts +27 -0
  98. package/dist/src/data/transforms/truncateText.d.ts.map +1 -0
  99. package/dist/src/data/transforms/truncateText.js +94 -0
  100. package/dist/src/debug/dataflowDebugSnapshot.d.ts +58 -0
  101. package/dist/src/debug/dataflowDebugSnapshot.d.ts.map +1 -0
  102. package/dist/src/debug/dataflowDebugSnapshot.js +159 -0
  103. package/dist/src/debug/markDebugSnapshot.d.ts +54 -0
  104. package/dist/src/debug/markDebugSnapshot.d.ts.map +1 -0
  105. package/dist/src/debug/markDebugSnapshot.js +100 -0
  106. package/dist/src/debug/paramDebugSnapshot.d.ts +53 -0
  107. package/dist/src/debug/paramDebugSnapshot.d.ts.map +1 -0
  108. package/dist/src/debug/paramDebugSnapshot.js +86 -0
  109. package/dist/src/debug/resolutionDebugSnapshot.d.ts +155 -0
  110. package/dist/src/debug/resolutionDebugSnapshot.d.ts.map +1 -0
  111. package/dist/src/debug/resolutionDebugSnapshot.js +291 -0
  112. package/dist/src/debug/valuePreview.d.ts +9 -0
  113. package/dist/src/debug/valuePreview.d.ts.map +1 -0
  114. package/dist/src/debug/valuePreview.js +57 -0
  115. package/dist/src/debug/viewDebugSnapshot.d.ts +131 -0
  116. package/dist/src/debug/viewDebugSnapshot.d.ts.map +1 -0
  117. package/dist/src/debug/viewDebugSnapshot.js +390 -0
  118. package/dist/src/embedFactory.d.ts.map +1 -1
  119. package/dist/src/embedFactory.js +6 -1
  120. package/dist/src/encoder/encoder.d.ts +2 -2
  121. package/dist/src/encoder/encoder.d.ts.map +1 -1
  122. package/dist/src/encoder/encoder.js +5 -4
  123. package/dist/src/fonts/bmFontManager.d.ts +1 -1
  124. package/dist/src/fonts/bmFontManager.d.ts.map +1 -1
  125. package/dist/src/fonts/bmFontManager.js +45 -10
  126. package/dist/src/fonts/textMetrics.d.ts +69 -0
  127. package/dist/src/fonts/textMetrics.d.ts.map +1 -0
  128. package/dist/src/fonts/textMetrics.js +73 -0
  129. package/dist/src/genomeSpy/headlessBootstrap.d.ts.map +1 -1
  130. package/dist/src/genomeSpy/headlessBootstrap.js +6 -0
  131. package/dist/src/genomeSpy/renderCoordinator.d.ts.map +1 -1
  132. package/dist/src/genomeSpy/renderCoordinator.js +25 -3
  133. package/dist/src/genomeSpy/viewDataInit.d.ts +14 -0
  134. package/dist/src/genomeSpy/viewDataInit.d.ts.map +1 -1
  135. package/dist/src/genomeSpy/viewDataInit.js +45 -8
  136. package/dist/src/genomeSpyBase.d.ts +6 -0
  137. package/dist/src/genomeSpyBase.d.ts.map +1 -1
  138. package/dist/src/genomeSpyBase.js +20 -3
  139. package/dist/src/gl/glslScaleGenerator.d.ts +17 -0
  140. package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -1
  141. package/dist/src/gl/glslScaleGenerator.js +39 -2
  142. package/dist/src/gl/includes/common.glsl.js +1 -1
  143. package/dist/src/gl/vertexRangeIndex.d.ts.map +1 -1
  144. package/dist/src/gl/vertexRangeIndex.js +4 -2
  145. package/dist/src/gl/webGLHelper.d.ts +1 -1
  146. package/dist/src/gl/webGLHelper.d.ts.map +1 -1
  147. package/dist/src/gl/webGLHelper.js +13 -8
  148. package/dist/src/marks/__snapshots__/shaderSnapshot.test.js.snap +140 -3
  149. package/dist/src/marks/mark.d.ts +47 -4
  150. package/dist/src/marks/mark.d.ts.map +1 -1
  151. package/dist/src/marks/mark.js +158 -54
  152. package/dist/src/marks/point.d.ts.map +1 -1
  153. package/dist/src/marks/point.js +4 -0
  154. package/dist/src/marks/point.vertex.glsl.js +1 -1
  155. package/dist/src/marks/text.d.ts +1 -1
  156. package/dist/src/marks/text.d.ts.map +1 -1
  157. package/dist/src/marks/text.js +2 -7
  158. package/dist/src/marks/text.vertex.glsl.js +1 -1
  159. package/dist/src/paramRuntime/paramUtils.d.ts +43 -9
  160. package/dist/src/paramRuntime/paramUtils.d.ts.map +1 -1
  161. package/dist/src/paramRuntime/paramUtils.js +61 -1
  162. package/dist/src/paramRuntime/viewParamRuntime.d.ts +32 -0
  163. package/dist/src/paramRuntime/viewParamRuntime.d.ts.map +1 -1
  164. package/dist/src/paramRuntime/viewParamRuntime.js +63 -0
  165. package/dist/src/scales/axisResolution.d.ts +35 -0
  166. package/dist/src/scales/axisResolution.d.ts.map +1 -1
  167. package/dist/src/scales/axisResolution.js +115 -7
  168. package/dist/src/scales/legendResolution.d.ts +83 -0
  169. package/dist/src/scales/legendResolution.d.ts.map +1 -0
  170. package/dist/src/scales/legendResolution.js +461 -0
  171. package/dist/src/scales/scaleResolution.d.ts +36 -0
  172. package/dist/src/scales/scaleResolution.d.ts.map +1 -1
  173. package/dist/src/scales/scaleResolution.js +59 -0
  174. package/dist/src/scales/viewLevelGuideConfig.d.ts +53 -0
  175. package/dist/src/scales/viewLevelGuideConfig.d.ts.map +1 -0
  176. package/dist/src/scales/viewLevelGuideConfig.js +224 -0
  177. package/dist/src/scales/viewLevelScaleConfig.d.ts.map +1 -1
  178. package/dist/src/scales/viewLevelScaleConfig.js +13 -2
  179. package/dist/src/spec/axis.d.ts +109 -3
  180. package/dist/src/spec/channel.d.ts +23 -4
  181. package/dist/src/spec/config.d.ts +59 -4
  182. package/dist/src/spec/data.d.ts +177 -17
  183. package/dist/src/spec/legend.d.ts +246 -0
  184. package/dist/src/spec/mark.d.ts +16 -4
  185. package/dist/src/spec/title.d.ts +58 -1
  186. package/dist/src/spec/transform.d.ts +149 -0
  187. package/dist/src/spec/view.d.ts +39 -6
  188. package/dist/src/types/embedApi.d.ts +262 -6
  189. package/dist/src/types/rendering.d.ts +19 -3
  190. package/dist/src/types/viewContext.d.ts +18 -2
  191. package/dist/src/utils/arrayUtils.d.ts +11 -0
  192. package/dist/src/utils/arrayUtils.d.ts.map +1 -1
  193. package/dist/src/utils/arrayUtils.js +23 -0
  194. package/dist/src/utils/suspension.d.ts +17 -0
  195. package/dist/src/utils/suspension.d.ts.map +1 -0
  196. package/dist/src/utils/suspension.js +41 -0
  197. package/dist/src/view/axisGridView.d.ts.map +1 -1
  198. package/dist/src/view/axisGridView.js +1 -4
  199. package/dist/src/view/axisView.d.ts +18 -2
  200. package/dist/src/view/axisView.d.ts.map +1 -1
  201. package/dist/src/view/axisView.js +180 -75
  202. package/dist/src/view/concatView.d.ts +10 -2
  203. package/dist/src/view/concatView.d.ts.map +1 -1
  204. package/dist/src/view/concatView.js +46 -9
  205. package/dist/src/view/containerMutationHelper.d.ts +20 -1
  206. package/dist/src/view/containerMutationHelper.d.ts.map +1 -1
  207. package/dist/src/view/containerMutationHelper.js +196 -33
  208. package/dist/src/view/facetView.d.ts +1 -1
  209. package/dist/src/view/gridView/gridChild.d.ts +54 -4
  210. package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
  211. package/dist/src/view/gridView/gridChild.js +301 -120
  212. package/dist/src/view/gridView/gridChildLegends.d.ts +57 -0
  213. package/dist/src/view/gridView/gridChildLegends.d.ts.map +1 -0
  214. package/dist/src/view/gridView/gridChildLegends.js +503 -0
  215. package/dist/src/view/gridView/gridView.d.ts +25 -0
  216. package/dist/src/view/gridView/gridView.d.ts.map +1 -1
  217. package/dist/src/view/gridView/gridView.js +454 -78
  218. package/dist/src/view/gridView/legendLayout.d.ts +26 -0
  219. package/dist/src/view/gridView/legendLayout.d.ts.map +1 -0
  220. package/dist/src/view/gridView/legendLayout.js +111 -0
  221. package/dist/src/view/gridView/scrollbar.d.ts.map +1 -1
  222. package/dist/src/view/gridView/scrollbar.js +1 -4
  223. package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
  224. package/dist/src/view/gridView/selectionRect.js +1 -4
  225. package/dist/src/view/gridView/separatorView.d.ts.map +1 -1
  226. package/dist/src/view/gridView/separatorView.js +1 -4
  227. package/dist/src/view/layerView.d.ts +9 -2
  228. package/dist/src/view/layerView.d.ts.map +1 -1
  229. package/dist/src/view/layerView.js +18 -1
  230. package/dist/src/view/layout/flexLayout.d.ts +20 -4
  231. package/dist/src/view/layout/flexLayout.d.ts.map +1 -1
  232. package/dist/src/view/layout/flexLayout.js +331 -31
  233. package/dist/src/view/layout/rectangle.d.ts +14 -0
  234. package/dist/src/view/layout/rectangle.d.ts.map +1 -1
  235. package/dist/src/view/layout/rectangle.js +40 -0
  236. package/dist/src/view/legend/legendEntries.d.ts +20 -0
  237. package/dist/src/view/legend/legendEntries.d.ts.map +1 -0
  238. package/dist/src/view/legend/legendEntries.js +21 -0
  239. package/dist/src/view/legendView.d.ts +134 -0
  240. package/dist/src/view/legendView.d.ts.map +1 -0
  241. package/dist/src/view/legendView.js +1611 -0
  242. package/dist/src/view/renderingContext/bufferedViewRenderingContext.d.ts.map +1 -1
  243. package/dist/src/view/renderingContext/bufferedViewRenderingContext.js +26 -4
  244. package/dist/src/view/renderingContext/clipOptions.d.ts +44 -0
  245. package/dist/src/view/renderingContext/clipOptions.d.ts.map +1 -0
  246. package/dist/src/view/renderingContext/clipOptions.js +140 -0
  247. package/dist/src/view/renderingContext/simpleViewRenderingContext.d.ts.map +1 -1
  248. package/dist/src/view/renderingContext/simpleViewRenderingContext.js +12 -1
  249. package/dist/src/view/resolutionPlanner.d.ts +2 -1
  250. package/dist/src/view/resolutionPlanner.d.ts.map +1 -1
  251. package/dist/src/view/resolutionPlanner.js +89 -25
  252. package/dist/src/view/testUtils.d.ts +4 -2
  253. package/dist/src/view/testUtils.d.ts.map +1 -1
  254. package/dist/src/view/testUtils.js +29 -7
  255. package/dist/src/view/titleView.d.ts +37 -0
  256. package/dist/src/view/titleView.d.ts.map +1 -0
  257. package/dist/src/view/titleView.js +584 -0
  258. package/dist/src/view/unitView.d.ts +3 -3
  259. package/dist/src/view/unitView.d.ts.map +1 -1
  260. package/dist/src/view/unitView.js +3 -2
  261. package/dist/src/view/view.d.ts +25 -24
  262. package/dist/src/view/view.d.ts.map +1 -1
  263. package/dist/src/view/view.js +121 -16
  264. package/dist/src/view/viewFactory.d.ts +2 -5
  265. package/dist/src/view/viewFactory.d.ts.map +1 -1
  266. package/dist/src/view/viewFactory.js +1 -2
  267. package/dist/src/view/viewIdentityRegistry.d.ts +37 -0
  268. package/dist/src/view/viewIdentityRegistry.d.ts.map +1 -0
  269. package/dist/src/view/viewIdentityRegistry.js +71 -0
  270. package/dist/src/view/viewMutationAcidTestUtils.d.ts +112 -0
  271. package/dist/src/view/viewMutationAcidTestUtils.d.ts.map +1 -0
  272. package/dist/src/view/viewMutationAcidTestUtils.js +234 -0
  273. package/dist/src/view/viewMutationApi.d.ts +42 -0
  274. package/dist/src/view/viewMutationApi.d.ts.map +1 -0
  275. package/dist/src/view/viewMutationApi.js +811 -0
  276. package/dist/src/view/viewSelectors.d.ts +10 -0
  277. package/dist/src/view/viewSelectors.d.ts.map +1 -1
  278. package/dist/src/view/viewSelectors.js +23 -1
  279. package/package.json +4 -4
  280. package/dist/bundle/esm-CuMSzCHy.js +0 -298
  281. package/dist/bundle/esm-DAnOffpD.js +0 -1426
  282. package/dist/bundle/esm-DMXpJXM4.js +0 -369
  283. package/dist/bundle/esm-DNtC3H80.js +0 -121
  284. package/dist/src/view/title.d.ts +0 -13
  285. package/dist/src/view/title.d.ts.map +0 -1
  286. package/dist/src/view/title.js +0 -154
  287. /package/dist/bundle/{AbortablePromiseCache-3gHJdF3E.js → AbortablePromiseCache-BTmAcN-t.js} +0 -0
  288. /package/dist/bundle/{esm-CuVa5T98.js → esm-VvpZ9hsq.js} +0 -0
  289. /package/dist/bundle/{chunk-DmhlhrBa.js → rolldown-runtime-Dy4uBu1J.js} +0 -0
@@ -0,0 +1,129 @@
1
+ import {
2
+ loadUrlDescriptorOrSkip,
3
+ UrlLimitExceededError,
4
+ urlDescriptorKey,
5
+ } from "./urlDescriptor.js";
6
+
7
+ /**
8
+ * Tracks active URL descriptors, descriptor-keyed handles, and the descriptor
9
+ * set covered by the last published data batch.
10
+ *
11
+ * @template T
12
+ */
13
+ export default class UrlDescriptorState {
14
+ /** @type {Map<string, T>} */
15
+ #handleCache = new Map();
16
+
17
+ /** @type {T[]} */
18
+ #handles = [];
19
+
20
+ /** @type {Set<string>} */
21
+ #activeKeys = new Set();
22
+
23
+ /** @type {Set<string>} */
24
+ #loadedKeys = new Set();
25
+
26
+ get handles() {
27
+ return this.#handles;
28
+ }
29
+
30
+ get activeSetLoaded() {
31
+ return this.#activeKeys.isSubsetOf(this.#loadedKeys);
32
+ }
33
+
34
+ markLoaded() {
35
+ this.#loadedKeys = new Set(this.#activeKeys);
36
+ }
37
+
38
+ clearActive() {
39
+ this.#handles = [];
40
+ this.#activeKeys = new Set();
41
+ this.#loadedKeys = new Set();
42
+ }
43
+
44
+ /**
45
+ * Refreshes active descriptors while reusing cached handles.
46
+ *
47
+ * @param {import("./urlDescriptor.js").UrlDescriptor[]} descriptors
48
+ * @param {(descriptor: import("./urlDescriptor.js").UrlDescriptor, descriptorKey: string) => Promise<T | undefined>} createHandle
49
+ */
50
+ async update(descriptors, createHandle) {
51
+ const descriptorKeys = descriptors.map(urlDescriptorKey);
52
+ const entries = await Promise.all(
53
+ descriptors.map((descriptor, i) =>
54
+ this.#getOrCreateHandle(
55
+ descriptor,
56
+ descriptorKeys[i],
57
+ createHandle
58
+ )
59
+ )
60
+ );
61
+ this.#handles = entries
62
+ .filter((entry) => entry.handle)
63
+ .map((entry) => /** @type {T} */ (entry.handle));
64
+ this.#activeKeys = new Set(
65
+ entries
66
+ .filter((entry) => entry.handle)
67
+ .map((entry) => entry.descriptorKey)
68
+ );
69
+ }
70
+
71
+ /**
72
+ * @param {import("./urlDescriptor.js").UrlDescriptor} descriptor
73
+ * @param {string} descriptorKey
74
+ * @param {(descriptor: import("./urlDescriptor.js").UrlDescriptor, descriptorKey: string) => Promise<T | undefined>} createHandle
75
+ * @returns {Promise<{ descriptorKey: string, handle: T | undefined }>}
76
+ */
77
+ async #getOrCreateHandle(descriptor, descriptorKey, createHandle) {
78
+ const cachedHandle = this.#handleCache.get(descriptorKey);
79
+ if (cachedHandle) {
80
+ return { descriptorKey, handle: cachedHandle };
81
+ }
82
+
83
+ const handle = await createHandle(descriptor, descriptorKey);
84
+ if (handle) {
85
+ this.#handleCache.set(descriptorKey, handle);
86
+ }
87
+ return { descriptorKey, handle };
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Updates descriptor-backed lazy-source handles using the shared multi-URL
93
+ * loading policy. Over-limit URL expansion is treated as an empty completed
94
+ * source so stale data is cleared without surfacing a runtime error.
95
+ *
96
+ * @template T
97
+ * @template M
98
+ * @param {{
99
+ * controller: { normalize: () => Promise<import("./urlDescriptor.js").UrlDescriptor[]> },
100
+ * state: UrlDescriptorState<T>,
101
+ * clearData: () => void,
102
+ * setLoadingStatus: (status: import("../../types/viewContext.js").DataLoadingStatus, detail?: string) => void,
103
+ * loadModules: () => Promise<M>,
104
+ * createHandle: (descriptor: import("./urlDescriptor.js").UrlDescriptor, modules: M) => Promise<T>,
105
+ * }} options
106
+ */
107
+ export async function updateUrlDescriptorState(options) {
108
+ try {
109
+ const descriptors = await options.controller.normalize();
110
+ const modules = await options.loadModules();
111
+
112
+ options.setLoadingStatus("loading");
113
+ await options.state.update(descriptors, (descriptor) =>
114
+ loadUrlDescriptorOrSkip(descriptor, () =>
115
+ options.createHandle(descriptor, modules)
116
+ )
117
+ );
118
+ options.setLoadingStatus("complete");
119
+ } catch (e) {
120
+ options.clearData();
121
+ if (e instanceof UrlLimitExceededError) {
122
+ options.state.clearActive();
123
+ options.setLoadingStatus("complete");
124
+ } else {
125
+ options.setLoadingStatus("error", e.message);
126
+ throw e;
127
+ }
128
+ }
129
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"urlSource.d.ts","sourceRoot":"","sources":["../../../../src/data/sources/urlSource.js"],"names":[],"mappings":"AAuJA;;;GAGG;AACH,gCAHW,OAAO,CAAC,OAAO,oBAAoB,EAAE,IAAI,CAAC,GACxC,IAAI,IAAI,OAAO,oBAAoB,EAAE,OAAO,CAIxD;AA5ID;;;GAGG;AACH;IACI;;;OAGG;IACH,oBAHW,OAAO,oBAAoB,EAAE,OAAO,QACpC,OAAO,oBAAoB,EAAE,OAAO,EAc9C;IATG,6CAMC;IAED,gBAAiC;;CAgHxC;uBA9IsB,iBAAiB"}
1
+ {"version":3,"file":"urlSource.d.ts","sourceRoot":"","sources":["../../../../src/data/sources/urlSource.js"],"names":[],"mappings":"AA+LA;;;GAGG;AACH,gCAHW,OAAO,CAAC,OAAO,oBAAoB,EAAE,IAAI,CAAC,GACxC,IAAI,IAAI,OAAO,oBAAoB,EAAE,OAAO,CAIxD;AA9KD;;;GAGG;AACH;IAII;;;OAGG;IACH,oBAHW,OAAO,oBAAoB,EAAE,OAAO,QACpC,OAAO,oBAAoB,EAAE,OAAO,EAkB9C;IAbG,6CAMC;IAED,gBAAiC;;CA+IxC;uBAtLsB,iBAAiB"}
@@ -11,6 +11,12 @@ import {
11
11
  withoutExprRef,
12
12
  } from "../../paramRuntime/paramUtils.js";
13
13
  import { concatUrl } from "../../utils/url.js";
14
+ import {
15
+ createDescriptorFieldAttacher,
16
+ loadUrlDescriptorOrSkip,
17
+ UrlLimitExceededError,
18
+ } from "./urlDescriptor.js";
19
+ import UrlDescriptorController from "./urlDescriptorController.js";
14
20
 
15
21
  const gzipMimeTypes = new Set(["application/gzip", "application/x-gzip"]);
16
22
  const textDecoder = new TextDecoder();
@@ -20,6 +26,9 @@ const textDecoder = new TextDecoder();
20
26
  * payloads before handing them to the registered format reader.
21
27
  */
22
28
  export default class UrlSource extends DataSource {
29
+ /** @type {UrlDescriptorController} */
30
+ #urlDescriptors;
31
+
23
32
  /**
24
33
  * @param {import("../../spec/data.js").UrlData} params
25
34
  * @param {import("../../view/view.js").default} view
@@ -36,6 +45,10 @@ export default class UrlSource extends DataSource {
36
45
  );
37
46
 
38
47
  this.baseUrl = view?.getBaseUrl();
48
+ this.#urlDescriptors = new UrlDescriptorController(this, {
49
+ getUrl: () => this.params.url,
50
+ onChange: () => this.load(),
51
+ });
39
52
  }
40
53
 
41
54
  get identifier() {
@@ -77,73 +90,100 @@ export default class UrlSource extends DataSource {
77
90
  }
78
91
 
79
92
  async load() {
80
- const url = withoutExprRef(this.params.url);
81
-
82
- /** @type {string[]} */
83
- const urls =
84
- typeof url == "object" && "urlsFromFile" in url
85
- ? await this.#loadUrlsFromFile(url)
86
- : (Array.isArray(url) ? url : [url]).map((u) =>
87
- concatUrl(this.baseUrl, u)
88
- );
89
-
90
- const format = getFormat(this.params, urls);
91
- const type = responseType(format.type);
92
-
93
- if (urls.length === 0 || !urls[0]) {
94
- this.reset();
95
- this.complete();
96
- return;
97
- }
98
-
99
- /** @param {string} url */
100
- const load = async (url) => {
101
- try {
102
- const result = await fetch(url);
103
- if (!result.ok) {
104
- throw new Error(`${result.status} ${result.statusText}`);
105
- }
106
- return await readResponseBody(result, url, type);
107
- } catch (e) {
108
- throw new Error(
109
- `Could not load data: ${url}. Reason: ${e.message}`,
110
- { cause: e }
111
- );
112
- }
113
- };
114
-
115
- /**
116
- * @param {any} content
117
- * @param {string} [url]
118
- */
119
- const readAndParse = async (content, url) => {
120
- try {
121
- /** @type {any[] | Promise<any[]>} */
122
- const dataOrPromise = read(content, toVegaLoaderFormat(format));
123
- const data =
124
- dataOrPromise instanceof Promise
125
- ? await dataOrPromise
126
- : dataOrPromise;
127
- this.beginBatch({ type: "file", url: url });
128
- for (const d of data) {
129
- this._propagate(d);
130
- }
131
- } catch (e) {
132
- console.warn(e);
133
- throw new Error(`Cannot parse: ${url}: ${e.message}`, {
134
- cause: e,
135
- });
136
- }
137
- };
138
-
139
93
  this.setLoadingStatus("loading");
140
94
  this.reset();
141
95
 
142
96
  try {
143
- await Promise.all(urls.map((url) => load(url).then(readAndParse)));
97
+ const url = withoutExprRef(this.params.url);
98
+
99
+ /** @type {import("./urlDescriptor.js").UrlDescriptor[]} */
100
+ const descriptors =
101
+ typeof url == "object" && "urlsFromFile" in url
102
+ ? (await this.#loadUrlsFromFile(url)).map((url) => ({
103
+ url,
104
+ }))
105
+ : await this.#urlDescriptors.normalize();
106
+
107
+ const urls = descriptors.map((descriptor) => descriptor.url);
108
+ if (urls.length > 0 && urls[0]) {
109
+ const format = getFormat(this.params, urls);
110
+ const type = responseType(format.type);
111
+
112
+ /** @param {string} url */
113
+ const load = async (url) => {
114
+ try {
115
+ const result = await fetch(url);
116
+ if (!result.ok) {
117
+ throw new Error(
118
+ `${result.status} ${result.statusText}`
119
+ );
120
+ }
121
+ return await readResponseBody(result, url, type);
122
+ } catch (e) {
123
+ throw new Error(
124
+ `Could not load data: ${url}. Reason: ${e.message}`,
125
+ { cause: e }
126
+ );
127
+ }
128
+ };
129
+
130
+ /**
131
+ * @param {any} content
132
+ * @param {import("./urlDescriptor.js").UrlDescriptor} descriptor
133
+ */
134
+ const readAndParse = async (content, descriptor) => {
135
+ try {
136
+ /** @type {any[] | Promise<any[]>} */
137
+ const dataOrPromise = read(
138
+ content,
139
+ toVegaLoaderFormat(format)
140
+ );
141
+ const data =
142
+ dataOrPromise instanceof Promise
143
+ ? await dataOrPromise
144
+ : dataOrPromise;
145
+ this.beginBatch({ type: "file", url: descriptor.url });
146
+ const attachFields = createDescriptorFieldAttacher(
147
+ descriptor.fields
148
+ );
149
+ for (const d of data) {
150
+ this._propagate(attachFields(d));
151
+ }
152
+ } catch (e) {
153
+ console.warn(e);
154
+ throw new Error(
155
+ `Cannot parse: ${descriptor.url}: ${e.message}`,
156
+ {
157
+ cause: e,
158
+ }
159
+ );
160
+ }
161
+ };
162
+
163
+ const loaded = await Promise.all(
164
+ descriptors.map((descriptor) =>
165
+ loadUrlDescriptorOrSkip(descriptor, async () => ({
166
+ descriptor,
167
+ content: await load(descriptor.url),
168
+ }))
169
+ )
170
+ );
171
+
172
+ await Promise.all(
173
+ loaded.map((entry) =>
174
+ entry
175
+ ? readAndParse(entry.content, entry.descriptor)
176
+ : undefined
177
+ )
178
+ );
179
+ }
144
180
  this.setLoadingStatus("complete");
145
181
  } catch (e) {
146
- this.setLoadingStatus("error", e.message);
182
+ if (e instanceof UrlLimitExceededError) {
183
+ this.setLoadingStatus("complete");
184
+ } else {
185
+ this.setLoadingStatus("error", e.message);
186
+ }
147
187
  }
148
188
  this.complete();
149
189
  }
@@ -0,0 +1,21 @@
1
+ export default class PackLegendLabelsTransform extends Transform {
2
+ /**
3
+ * @param {import("../../spec/transform.js").PackLegendLabelsParams} params
4
+ * @param {import("../flowNode.js").ParamRuntimeProvider} paramRuntimeProvider
5
+ */
6
+ constructor(params: import("../../spec/transform.js").PackLegendLabelsParams, paramRuntimeProvider: import("../flowNode.js").ParamRuntimeProvider);
7
+ params: import("../../spec/transform.js").PackLegendLabelsParams;
8
+ labelWidthAccessor: import("vega-util").AccessorFn<any>;
9
+ symbolSizeAccessor: import("vega-util").AccessorFn<any> | (() => string | number);
10
+ symbolStrokeWidthAccessor: import("vega-util").AccessorFn<any> | (() => string | number);
11
+ /** @type {number | undefined} */
12
+ yExtent: number | undefined;
13
+ /** @type {any[]} */
14
+ buffer: any[];
15
+ /**
16
+ * @param {any} datum
17
+ */
18
+ handle(datum: any): void;
19
+ }
20
+ import Transform from "./transform.js";
21
+ //# sourceMappingURL=packLegendLabels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packLegendLabels.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/packLegendLabels.js"],"names":[],"mappings":"AAgBA;IAKI;;;OAGG;IACH,oBAHW,OAAO,yBAAyB,EAAE,sBAAsB,wBACxD,OAAO,gBAAgB,EAAE,oBAAoB,EAsCvD;IAjCG,iEAAoB;IACpB,wDAAkD;IAClD,kFAGwC;IACxC,yFAG6C;IAC7C,iCAAiC;IACjC,SADW,MAAM,GAAG,SAAS,CACL;IAoBxB,oBAAoB;IACpB,QADW,GAAG,EAAE,CACA;IAQpB;;OAEG;IACH,cAFW,GAAG,QAIb;CAmHJ;sBA1LqB,gBAAgB"}
@@ -0,0 +1,189 @@
1
+ import { BEHAVIOR_MODIFIES } from "../flowNode.js";
2
+ import { field } from "../../utils/field.js";
3
+ import Transform from "./transform.js";
4
+ import { isExprRef } from "../../paramRuntime/paramUtils.js";
5
+
6
+ /**
7
+ * @param {unknown} symbolSize
8
+ * @param {unknown} symbolStrokeWidth
9
+ */
10
+ function getSymbolExtent(symbolSize, symbolStrokeWidth) {
11
+ const size = Number(symbolSize);
12
+ const area = Number.isFinite(size) && size >= 0 ? size : 100;
13
+ const strokeWidth = Number(symbolStrokeWidth);
14
+ return Math.sqrt(area) + (Number.isFinite(strokeWidth) ? strokeWidth : 0);
15
+ }
16
+
17
+ export default class PackLegendLabelsTransform extends Transform {
18
+ get behavior() {
19
+ return BEHAVIOR_MODIFIES;
20
+ }
21
+
22
+ /**
23
+ * @param {import("../../spec/transform.js").PackLegendLabelsParams} params
24
+ * @param {import("../flowNode.js").ParamRuntimeProvider} paramRuntimeProvider
25
+ */
26
+ constructor(params, paramRuntimeProvider) {
27
+ super(params, paramRuntimeProvider);
28
+
29
+ this.params = params;
30
+ this.labelWidthAccessor = field(params.labelWidth);
31
+ this.symbolSizeAccessor =
32
+ typeof params.symbolSize == "string"
33
+ ? field(params.symbolSize)
34
+ : () => params.symbolSize ?? 100;
35
+ this.symbolStrokeWidthAccessor =
36
+ typeof params.symbolStrokeWidth == "string"
37
+ ? field(params.symbolStrokeWidth)
38
+ : () => params.symbolStrokeWidth ?? 0;
39
+ /** @type {number | undefined} */
40
+ this.yExtent = undefined;
41
+
42
+ if (isExprRef(params.yExtent)) {
43
+ const yExtentExpr = this.paramRuntime.watchExpression(
44
+ params.yExtent.expr,
45
+ () => {
46
+ this.yExtent = yExtentExpr();
47
+ this.repropagate();
48
+ },
49
+ {
50
+ scopeOwned: false,
51
+ registerDisposer: (disposer) =>
52
+ this.registerDisposer(disposer),
53
+ }
54
+ );
55
+ this.yExtent = yExtentExpr();
56
+ } else {
57
+ this.yExtent = params.yExtent;
58
+ }
59
+
60
+ /** @type {any[]} */
61
+ this.buffer = [];
62
+ }
63
+
64
+ reset() {
65
+ super.reset();
66
+ this.buffer = [];
67
+ }
68
+
69
+ /**
70
+ * @param {any} datum
71
+ */
72
+ handle(datum) {
73
+ this.buffer.push(datum);
74
+ }
75
+
76
+ complete() {
77
+ const params = this.params;
78
+ const direction = params.direction ?? "vertical";
79
+ const rowPadding = params.rowPadding ?? 0;
80
+ const columnPadding = params.columnPadding ?? 0;
81
+ const labelOffset = params.labelOffset ?? 0;
82
+ const fontSize = params.fontSize ?? 10;
83
+ const xOffset = params.xOffset ?? 0;
84
+ const yOffset = params.yOffset ?? 0;
85
+ const symbolOffset = params.symbolOffset ?? 0;
86
+ const yExtent = this.yExtent;
87
+
88
+ /** @type {number} */
89
+ const n = this.buffer.length;
90
+ const columns =
91
+ params.columns && params.columns > 0
92
+ ? params.columns
93
+ : direction == "horizontal"
94
+ ? n
95
+ : 1;
96
+ const rows = Math.ceil(n / Math.max(columns, 1));
97
+
98
+ /** @type {number[]} */
99
+ const columnWidths = Array.from({ length: columns }, () => 0);
100
+ /** @type {number[]} */
101
+ const columnSymbolExtents = Array.from({ length: columns }, () => 0);
102
+ /** @type {number[]} */
103
+ const columnLabelWidths = Array.from({ length: columns }, () => 0);
104
+ /** @type {number[]} */
105
+ const rowHeights = Array.from({ length: rows }, () => 0);
106
+ /** @type {Array<{ row: number, column: number, symbolExtent: number }>} */
107
+ const entries = [];
108
+
109
+ for (let index = 0; index < n; index++) {
110
+ const datum = this.buffer[index];
111
+ const row =
112
+ direction == "horizontal"
113
+ ? Math.floor(index / columns)
114
+ : index % rows;
115
+ const column =
116
+ direction == "horizontal"
117
+ ? index % columns
118
+ : Math.floor(index / rows);
119
+ const symbolExtent = getSymbolExtent(
120
+ this.symbolSizeAccessor(datum),
121
+ this.symbolStrokeWidthAccessor(datum)
122
+ );
123
+ const labelWidth = this.labelWidthAccessor(datum);
124
+
125
+ entries.push({ row, column, symbolExtent });
126
+ columnSymbolExtents[column] = Math.max(
127
+ columnSymbolExtents[column],
128
+ symbolExtent
129
+ );
130
+ columnLabelWidths[column] = Math.max(
131
+ columnLabelWidths[column],
132
+ labelWidth
133
+ );
134
+ rowHeights[row] = Math.max(rowHeights[row], symbolExtent, fontSize);
135
+ }
136
+
137
+ for (let column = 0; column < columns; column++) {
138
+ columnWidths[column] =
139
+ columnSymbolExtents[column] +
140
+ labelOffset +
141
+ columnLabelWidths[column];
142
+ }
143
+
144
+ /** @type {number[]} */
145
+ const columnX = [];
146
+ for (let column = 0, x = 0; column < columns; column++) {
147
+ columnX[column] = x;
148
+ x += columnWidths[column] + columnPadding;
149
+ }
150
+
151
+ /** @type {number[]} */
152
+ const rowY = [];
153
+ for (let row = 0, y = 0; row < rows; row++) {
154
+ rowY[row] = y;
155
+ y += rowHeights[row] + rowPadding;
156
+ }
157
+
158
+ for (let index = 0; index < n; index++) {
159
+ const datum = this.buffer[index];
160
+ const entry = entries[index];
161
+ const x = columnX[entry.column];
162
+ const y = rowY[entry.row];
163
+ const symbolSlotWidth = columnSymbolExtents[entry.column];
164
+ const symbolCenterOffset = symbolSlotWidth / 2;
165
+
166
+ datum.row = entry.row;
167
+ datum.column = entry.column;
168
+ const entryY = y + yOffset;
169
+ const labelY = y + yOffset + rowHeights[entry.row] / 2;
170
+
171
+ datum.symbolX = x + xOffset + symbolOffset;
172
+ datum.symbolX2 = x + xOffset + symbolOffset + symbolSlotWidth;
173
+ datum.entryX = x + xOffset + symbolOffset + symbolCenterOffset;
174
+ datum.entryY = entryY;
175
+ datum.entryWidth = columnWidths[entry.column];
176
+ datum.entryHeight = rowHeights[entry.row];
177
+ datum.labelX = x + xOffset + symbolSlotWidth + labelOffset;
178
+ datum.labelY = labelY;
179
+ if (yExtent != null) {
180
+ datum.entryY2 = yExtent - entryY;
181
+ datum.labelY2 = yExtent - labelY;
182
+ }
183
+
184
+ this._propagate(datum);
185
+ }
186
+
187
+ super.complete();
188
+ }
189
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"transformFactory.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/transformFactory.js"],"names":[],"mappings":"AA+CA;;;GAGG;AACH,gDAHW,OAAO,yBAAyB,EAAE,mBAAmB,SACrD,OAAO,oBAAoB,EAAE,OAAO,oCAS9C;AAtCD;;;;GAIG;AACH,yBAFU,MAAM,CAAC,MAAM,EAAE,KAAK,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,OAAO,oBAAoB,EAAE,OAAO,KAAK,OAAO,gBAAgB,EAAE,OAAO,CAAC,CAsB1H"}
1
+ {"version":3,"file":"transformFactory.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/transformFactory.js"],"names":[],"mappings":"AAmDA;;;GAGG;AACH,gDAHW,OAAO,yBAAyB,EAAE,mBAAmB,SACrD,OAAO,oBAAoB,EAAE,OAAO,oCAS9C;AAxCD;;;;GAIG;AACH,yBAFU,MAAM,CAAC,MAAM,EAAE,KAAK,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,OAAO,oBAAoB,EAAE,OAAO,KAAK,OAAO,gBAAgB,EAAE,OAAO,CAAC,CAwB1H"}
@@ -8,6 +8,7 @@ import FlattenDelimitedTransform from "./flattenDelimited.js";
8
8
  import FormulaTransform from "./formula.js";
9
9
  import LinearizeGenomicCoordinate from "./linearizeGenomicCoordinate.js";
10
10
  import MeasureTextTransform from "./measureText.js";
11
+ import PackLegendLabelsTransform from "./packLegendLabels.js";
11
12
  import PileupTransform from "./pileup.js";
12
13
  import ProjectTransform from "./project.js";
13
14
  import RegexExtractTransform from "./regexExtract.js";
@@ -17,6 +18,7 @@ import StackTransform from "./stack.js";
17
18
  import FlattenSequenceTransform from "./flattenSequence.js";
18
19
  import AggregateTransform from "./aggregate.js";
19
20
  import IdentifierTransform from "./identifier.js";
21
+ import TruncateTextTransform from "./truncateText.js";
20
22
 
21
23
  /**
22
24
  * TODO: Make this dynamic
@@ -37,11 +39,13 @@ export const transforms = {
37
39
  identifier: IdentifierTransform,
38
40
  linearizeGenomicCoordinate: LinearizeGenomicCoordinate,
39
41
  measureText: MeasureTextTransform,
42
+ packLegendLabels: PackLegendLabelsTransform,
40
43
  pileup: PileupTransform,
41
44
  project: ProjectTransform,
42
45
  regexExtract: RegexExtractTransform,
43
46
  regexFold: RegexFoldTransform,
44
47
  sample: SampleTransform,
48
+ truncateText: TruncateTextTransform,
45
49
  stack: StackTransform,
46
50
  };
47
51
 
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @param {string} text
3
+ * @param {number | undefined} limit
4
+ * @param {((text: string, fontSize?: number) => number) | undefined} measureWidth
5
+ * @param {number} fontSize
6
+ * @param {string} ellipsis
7
+ */
8
+ export function truncateText(text: string, limit: number | undefined, measureWidth: ((text: string, fontSize?: number) => number) | undefined, fontSize: number, ellipsis: string): string;
9
+ export default class TruncateTextTransform extends Transform {
10
+ /**
11
+ * @param {import("../../spec/transform.js").TruncateTextParams} params
12
+ * @param {import("../flowNode.js").ParamRuntimeProvider} paramRuntimeProvider
13
+ */
14
+ constructor(params: import("../../spec/transform.js").TruncateTextParams, paramRuntimeProvider: import("../flowNode.js").ParamRuntimeProvider);
15
+ params: import("../../spec/transform.js").TruncateTextParams;
16
+ accessor: import("vega-util").AccessorFn<any>;
17
+ as: string;
18
+ fontSize: number;
19
+ ellipsis: string;
20
+ font: import("../../fonts/bmFontManager.js").FontEntry;
21
+ /**
22
+ * @param {any} datum
23
+ */
24
+ handle(datum: any): void;
25
+ }
26
+ import Transform from "./transform.js";
27
+ //# sourceMappingURL=truncateText.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"truncateText.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/truncateText.js"],"names":[],"mappings":"AAMA;;;;;;GAMG;AACH,mCANW,MAAM,SACN,MAAM,GAAG,SAAS,gBAClB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,YACzD,MAAM,YACN,MAAM,UA+BhB;AAED;IAKI;;;OAGG;IACH,oBAHW,OAAO,yBAAyB,EAAE,kBAAkB,wBACpD,OAAO,gBAAgB,EAAE,oBAAoB,EAUvD;IALG,6DAAoB;IACpB,8CAAmC;IACnC,WAAmC;IACnC,iBAA+B;IAC/B,iBAAmD;IAKnD,uDAMkC;IAGtC;;OAEG;IACH,cAFW,GAAG,QAiBb;CACJ;sBA3FqB,gBAAgB"}