@sportsdataverse/sdvplot 0.1.0 → 0.2.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 (135) hide show
  1. package/NOTICE.md +15 -0
  2. package/README.md +84 -8
  3. package/dist/chartjs-surface.d.ts +2 -2
  4. package/dist/chartjs-surface.js +2 -2
  5. package/dist/chartjs-surface.js.map +1 -1
  6. package/dist/chartjs.d.ts +32 -2
  7. package/dist/chartjs.js +7 -4
  8. package/dist/chartjs.js.map +1 -1
  9. package/dist/chunk-57WFSI4Q.js +128 -0
  10. package/dist/chunk-57WFSI4Q.js.map +1 -0
  11. package/dist/{chunk-KKH6ABMA.js → chunk-7ULOCCFL.js} +94 -4
  12. package/dist/chunk-7ULOCCFL.js.map +1 -0
  13. package/dist/chunk-AMXASQHT.js +120 -0
  14. package/dist/chunk-AMXASQHT.js.map +1 -0
  15. package/dist/chunk-B2MP37SR.js +175 -0
  16. package/dist/chunk-B2MP37SR.js.map +1 -0
  17. package/dist/{chunk-NLPH2VZT.js → chunk-DYMUVE6K.js} +4 -4
  18. package/dist/{chunk-NLPH2VZT.js.map → chunk-DYMUVE6K.js.map} +1 -1
  19. package/dist/{chunk-QY65DUEF.js → chunk-H2C3FMMA.js} +4 -10
  20. package/dist/chunk-H2C3FMMA.js.map +1 -0
  21. package/dist/{chunk-JJFTD4VB.js → chunk-J4P4HDBF.js} +4 -4
  22. package/dist/{chunk-JJFTD4VB.js.map → chunk-J4P4HDBF.js.map} +1 -1
  23. package/dist/chunk-M3XD2OSN.js +132 -0
  24. package/dist/chunk-M3XD2OSN.js.map +1 -0
  25. package/dist/{chunk-OKEE4AH6.js → chunk-OIILARXI.js} +3 -3
  26. package/dist/{chunk-OKEE4AH6.js.map → chunk-OIILARXI.js.map} +1 -1
  27. package/dist/chunk-RPVVJY74.js +170 -0
  28. package/dist/chunk-RPVVJY74.js.map +1 -0
  29. package/dist/chunk-UL5M6KDE.js +205 -0
  30. package/dist/chunk-UL5M6KDE.js.map +1 -0
  31. package/dist/chunk-WQT4IVLX.js +10 -0
  32. package/dist/chunk-WQT4IVLX.js.map +1 -0
  33. package/dist/{chunk-TAXO3VXH.js → chunk-ZAEQXFJM.js} +3 -3
  34. package/dist/{chunk-TAXO3VXH.js.map → chunk-ZAEQXFJM.js.map} +1 -1
  35. package/dist/cytoscape.d.ts +188 -0
  36. package/dist/cytoscape.js +219 -0
  37. package/dist/cytoscape.js.map +1 -0
  38. package/dist/d3.d.ts +3 -3
  39. package/dist/d3.js +6 -6
  40. package/dist/d3.js.map +1 -1
  41. package/dist/deckgl.d.ts +232 -0
  42. package/dist/deckgl.js +197 -0
  43. package/dist/deckgl.js.map +1 -0
  44. package/dist/echarts.js +5 -5
  45. package/dist/g2.d.ts +251 -0
  46. package/dist/g2.js +102 -0
  47. package/dist/g2.js.map +1 -0
  48. package/dist/index.d.ts +2 -1
  49. package/dist/index.js +4 -5
  50. package/dist/lightweight-charts.d.ts +217 -0
  51. package/dist/lightweight-charts.js +155 -0
  52. package/dist/lightweight-charts.js.map +1 -0
  53. package/dist/maplibre.d.ts +271 -0
  54. package/dist/maplibre.js +175 -0
  55. package/dist/maplibre.js.map +1 -0
  56. package/dist/mui.d.ts +338 -0
  57. package/dist/mui.js +184 -0
  58. package/dist/mui.js.map +1 -0
  59. package/dist/nivo.d.ts +193 -0
  60. package/dist/nivo.js +8 -0
  61. package/dist/nivo.js.map +1 -0
  62. package/dist/perspective.d.ts +198 -0
  63. package/dist/perspective.js +171 -0
  64. package/dist/perspective.js.map +1 -0
  65. package/dist/placement-UWkqUzpa.d.ts +32 -0
  66. package/dist/plot.d.ts +7 -5
  67. package/dist/plot.js +9 -8
  68. package/dist/plot.js.map +1 -1
  69. package/dist/plotly.js +5 -5
  70. package/dist/react.d.ts +279 -3
  71. package/dist/react.js +364 -6
  72. package/dist/react.js.map +1 -1
  73. package/dist/recharts.d.ts +162 -0
  74. package/dist/recharts.js +8 -0
  75. package/dist/recharts.js.map +1 -0
  76. package/dist/shadcn.d.ts +83 -0
  77. package/dist/shadcn.js +88 -0
  78. package/dist/shadcn.js.map +1 -0
  79. package/dist/shots.js +3 -2
  80. package/dist/shots.js.map +1 -1
  81. package/dist/surface-TR7YFJW3.js +4 -0
  82. package/dist/surface-TR7YFJW3.js.map +1 -0
  83. package/dist/surfaces-MIG7HOFU.js +6 -0
  84. package/dist/surfaces-MIG7HOFU.js.map +1 -0
  85. package/dist/surfaces-W-odWLpT.d.ts +47 -0
  86. package/dist/svelte/HeadshotMark.svelte +25 -0
  87. package/dist/svelte/HeadshotMark.svelte.d.ts +10 -0
  88. package/dist/svelte/HeadshotMark.svelte.d.ts.map +1 -0
  89. package/dist/svelte/LogoMark.svelte +25 -0
  90. package/dist/svelte/LogoMark.svelte.d.ts +10 -0
  91. package/dist/svelte/LogoMark.svelte.d.ts.map +1 -0
  92. package/dist/svelte/Marks.svelte +25 -0
  93. package/dist/svelte/Marks.svelte.d.ts +10 -0
  94. package/dist/svelte/Marks.svelte.d.ts.map +1 -0
  95. package/dist/svelte/Surface.svelte +29 -0
  96. package/dist/svelte/Surface.svelte.d.ts +9 -0
  97. package/dist/svelte/Surface.svelte.d.ts.map +1 -0
  98. package/dist/svelte/SurfaceBackdrop.svelte +26 -0
  99. package/dist/svelte/SurfaceBackdrop.svelte.d.ts +11 -0
  100. package/dist/svelte/SurfaceBackdrop.svelte.d.ts.map +1 -0
  101. package/dist/svelte/index.d.ts +13 -0
  102. package/dist/svelte/index.d.ts.map +1 -0
  103. package/dist/svelte/index.js +11 -0
  104. package/dist/svelte-core.d.ts +139 -0
  105. package/dist/svelte-core.js +123 -0
  106. package/dist/svelte-core.js.map +1 -0
  107. package/dist/tanstack.d.ts +240 -0
  108. package/dist/tanstack.js +110 -0
  109. package/dist/tanstack.js.map +1 -0
  110. package/dist/testing.js +4 -5
  111. package/dist/testing.js.map +1 -1
  112. package/dist/three.d.ts +223 -0
  113. package/dist/three.js +50 -0
  114. package/dist/three.js.map +1 -0
  115. package/dist/{tiers-B6pUBPcE.d.ts → tiers-BN4md-GB.d.ts} +2 -30
  116. package/dist/unovis.d.ts +127 -0
  117. package/dist/unovis.js +108 -0
  118. package/dist/unovis.js.map +1 -0
  119. package/dist/uplot.d.ts +120 -0
  120. package/dist/uplot.js +110 -0
  121. package/dist/uplot.js.map +1 -0
  122. package/dist/vega.js +5 -5
  123. package/dist/victory.d.ts +107 -0
  124. package/dist/victory.js +38 -0
  125. package/dist/victory.js.map +1 -0
  126. package/package.json +218 -6
  127. package/dist/chunk-KKH6ABMA.js.map +0 -1
  128. package/dist/chunk-QY65DUEF.js.map +0 -1
  129. package/dist/chunk-RMT2GMFH.js +0 -97
  130. package/dist/chunk-RMT2GMFH.js.map +0 -1
  131. package/dist/chunk-SEBO35DV.js +0 -76
  132. package/dist/chunk-SEBO35DV.js.map +0 -1
  133. package/dist/chunk-TDNBAEQB.js +0 -105
  134. package/dist/chunk-TDNBAEQB.js.map +0 -1
  135. package/dist/surfaces-ChaD9nei.d.ts +0 -38
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/deckgl.ts"],"names":["sportySurface"],"mappings":";;;;;;;AA8KA,IAAM,OAAA,GAAU,GAAA;AAChB,IAAM,IAAA,GAAO,CAAC,CAAA,KAA4B,OAAO,MAAM,QAAA,IAAY,MAAA,CAAO,SAAS,CAAC,CAAA;AACpF,SAAS,OAAA,CAAQ,MAAc,CAAA,EAAoB;AACjD,EAAA,IAAI,CAAC,IAAA,CAAK,CAAC,CAAA,IAAK,IAAI,CAAA,EAAG,MAAM,IAAI,UAAA,CAAW,GAAG,IAAI,CAAA,0BAAA,EAA6B,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,CAAA;AAC3F,EAAA,OAAO,CAAA;AACT;AAEA,SAAS,QAAQ,KAAA,EAAuB;AACtC,EAAA,IAAI,CAAA,GAAI,OAAO,KAAK,CAAA,CAAE,MAAK,CAAE,OAAA,CAAQ,OAAO,EAAE,CAAA;AAC9C,EAAA,IAAI,CAAA,CAAE,MAAA,KAAW,CAAA,EAAG,CAAA,GAAI,CAAC,GAAG,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,EAAA,KAAO,EAAA,GAAK,EAAE,CAAA,CAAE,KAAK,EAAE,CAAA;AAC3D,EAAA,OAAO,CAAA,CAAE,MAAA,KAAW,CAAA,GAAI,MAAA,CAAO,QAAA,CAAS,EAAE,KAAA,CAAM,CAAC,CAAA,EAAG,EAAE,CAAA,GAAI,GAAA;AAC5D;AAEA,SAAS,KAAK,KAAA,EAAqB;AACjC,EAAA,MAAM,CAAA,GAAI,QAAQ,KAAK,CAAA;AACvB,EAAA,MAAM,CAAC,GAAG,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,CAAE,GAAA;AAAA,IAAI,CAAC,CAAA,KAC/B,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,OAAO,EAAE,SAAA,EAAW,IAAA,EAAM,EAAE,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,CAAC,GAAG,EAAE;AAAA,GACtE;AACA,EAAA,OAAO,CAAC,CAAA,EAAa,CAAA,EAAa,CAAA,EAAa,CAAC,CAAA;AAClD;AAsBO,SAAS,aAAA,CAAc,MAAsB,CAAA,EAAwC;AAC1F,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,MAAA,EAAQ,CAAA,CAAE,QAAQ,EAAE,CAAA;AACzC,EAAA,MAAM,OAAA,GAAU,UAAA,CAAW,CAAA,CAAE,KAAA,IAAS,CAAC,CAAA;AACvC,EAAA,MAAM,IAAA,GAAO,eAAe,IAAA,EAAM,MAAA,EAAQ,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAe;AAC/D,IAAA,MAAM,MAAA,GAAS,OAAA;AACf,IAAA,OAAO;AAAA,MACL,QAAA,EAAU,CAAC,MAAA,CAAO,CAAA,CAAE,CAAC,CAAA,EAAG,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,MACnC,MAAM,EAAE,GAAA,EAAK,EAAE,GAAA,EAAK,KAAA,EAAO,KAAK,KAAA,CAAM,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA,EAAG,MAAA,EAAQ,SAAS,MAAA,GAAS,CAAA,EAAG,MAAM,KAAA,EAAM;AAAA,MACrG,MAAM,CAAA,CAAE,EAAA;AAAA,MACR,OAAO,CAAA,CAAE;AAAA,KACX;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,EAAE,EAAA,IAAM,eAAA;AAAA,IACZ,IAAA;AAAA,IACA,WAAA,EAAa,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA;AAAA,IACtB,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA;AAAA,IAClB,OAAA,EAAS,IAAA;AAAA,IACT,SAAA,EAAW,QAAA;AAAA,IACX;AAAA,GACF;AACF;AAGA,IAAM,QAAQ,CAAC,CAAA,KACb,CAAA,KAAM,IAAA,IAAQ,MAAM,MAAA,GAAY,EAAA,GAAK,OAAO,CAAA,KAAM,WAAY,SAAA,CAAU,CAAC,CAAA,IAAK,EAAA,GAAM,OAAO,CAAC,CAAA;AAO9F,SAAS,SAAA,CAAU,GAAA,EAAiC,CAAA,EAAmB,KAAA,EAAwB;AAC7F,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,CAAA,CAAE,QAAA,IAAY,SAAS,CAAA;AAC7C,EAAA,MAAM,EAAA,GAAK,EAAE,QAAA,EAAU,SAAA,EAAoB,GAAI,CAAA,CAAE,MAAA,KAAW,MAAA,GAAY,EAAC,GAAI,EAAE,MAAA,EAAQ,CAAA,CAAE,QAAO,EAAG;AACnG,EAAA,MAAM,QAAQ,GAAA,CAAI,MAAA,CAAO,CAAC,EAAA,KAAqB,OAAO,IAAI,CAAA;AAC1D,EAAA,MAAM,IAAA,GAAO,UAAU,CAAA,CAAE,MAAA,EAAQ,OAAO,EAAE,GAAG,EAAA,EAAI,KAAA,EAAO,CAAA;AACxD,EAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,CAAA,CAAE,MAAA,EAAQ,KAAA,EAAO,EAAE,GAAG,EAAA,EAAI,KAAA,EAAO,KAAA,KAAU,SAAA,GAAY,WAAA,GAAc,WAAW,CAAA;AAExG,EAAA,IAAI,SAAS,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG,MAAM,IAAA,CAAK,CAAA,IAAK,KAAA,CAAM,CAAC,KAAK,QAAA,EAAU,EAAE,SAAA,EAAW,IAAA,EAAM,CAAC,CAAA;AACpF,EAAA,IAAI,CAAA,CAAE,UAAA,KAAe,MAAA,EAAW,MAAA,GAAS,WAAA,CAAY,MAAA,EAAQ,KAAA,EAAO,IAAA,CAAK,CAAA,CAAE,UAAU,CAAA,EAAG,KAAK,CAAA;AAC7F,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,OAAO,GAAA,CAAI,IAAI,CAAC,EAAA,KAAQ,OAAO,IAAA,GAAO,QAAA,GAAY,MAAA,CAAO,CAAA,EAAG,CAAa,CAAA;AAC3E;AAkCO,SAAS,YAAA,CAAa,MAAsB,CAAA,EAAsC;AACvF,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,OAAA,EAAS,CAAA,CAAE,SAAS,CAAC,CAAA;AAC3C,EAAA,MAAM,OAAA,GAAU,UAAA,CAAW,CAAA,CAAE,KAAA,IAAS,CAAC,CAAA;AACvC,EAAA,IAAI,CAAA,CAAE,IAAA,KAAS,MAAA,IAAa,EAAE,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,IAAK,CAAA,CAAE,IAAA,IAAQ,GAAA,IAAO,CAAA,CAAE,IAAA,IAAQ,EAAA,CAAA;AACvE,IAAA,MAAM,IAAI,UAAA,CAAW,CAAA,sCAAA,EAAyC,OAAO,CAAA,CAAE,IAAI,CAAC,CAAA,CAAE,CAAA;AAChF,EAAA,IAAI,CAAA,CAAE,WAAW,MAAA,IAAa,EAAE,KAAK,CAAA,CAAE,MAAM,CAAA,IAAK,CAAA,CAAE,MAAA,IAAU,CAAA,CAAA;AAC5D,IAAA,MAAM,IAAI,UAAA,CAAW,CAAA,qDAAA,EAAwD,OAAO,CAAA,CAAE,MAAM,CAAC,CAAA,CAAE,CAAA;AACjG,EAAA,MAAM,IAAA,GAAO,CAAC,CAAA,CAAE,CAAA,EAAG,CAAA,CAAE,GAAG,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,IAAI,CAAA,CAAE,GAAA;AAAA,IAAI,CAAC,CAAA,EAAG,CAAA,KAC9C,MAAA,CAAO,IAAA,EAAM,CAAA,EAAG,CAAC,GAAA,EAAK,GAAA,EAAK,MAAA,EAAQ,MAAM,CAAA,CAAE,CAAC,CAAW;AAAA,GACzD;AACA,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,EAAM,CAAA,CAAE,MAAM,MAAM,CAAA;AACzC,EAAA,MAAM,OAAiB,EAAC;AACxB,EAAA,MAAM,UAAmB,EAAC;AAC1B,EAAA,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACrB,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,KAAM,IAAA,CAAK,CAAA,CAAE,CAAC,CAAC,CAAC,CAAA,EAAG,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AAAA,SACzC,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAU,CAAA;AAAA,EACrC,CAAC,CAAA;AACD,EAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,IAAA,MAAM,QACJ,OAAA,CAAQ,KAAA,CAAM,GAAG,EAAE,CAAA,CAAE,IAAI,MAAM,CAAA,CAAE,KAAK,IAAI,CAAA,IACzC,QAAQ,MAAA,GAAS,EAAA,GAAK,QAAQ,OAAA,CAAQ,MAAA,GAAS,EAAE,CAAA,KAAA,CAAA,GAAU,EAAA,CAAA;AAC9D,IAAA,IAAA;AAAA,MACE,CAAA,YAAA,EAAe,CAAA,CAAE,MAAM,CAAA,SAAA,EAAY,KAAK,CAAA,CAAA;AAAA,MACxC,CAAA,QAAA,EAAW,OAAA,CAAQ,MAAM,CAAA,mCAAA,EAAsC,KAAK,CAAA;AAAA,KACtE;AAAA,EACF;AACA,EAAA,MAAM,EAAA,GAAK;AAAA,IACT,GAAI,EAAE,MAAA,KAAW,MAAA,GAAY,EAAC,GAAI,EAAE,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAO;AAAA,IACrD,GAAI,EAAE,QAAA,KAAa,MAAA,GAAY,EAAC,GAAI,EAAE,QAAA,EAAU,CAAA,CAAE,QAAA;AAAS,GAC7D;AACA,EAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,KAAA,CAAM,CAAC,CAAU,CAAA;AAC9C,EAAA,MAAM,QAAA,GAAW,WAAA,CAAY,IAAA,EAAM,CAAA,CAAE,QAAQ,EAAE,CAAA;AAE/C,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM,QAAA,CAAS,CAAC,CAAA,IAAK,CAAA,CAAA,EAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAE,CAAA;AAC7D,EAAA,MAAM,WAAW,CAAC,GAAG,IAAI,GAAA,CAAI,IAAI,CAAC,CAAA;AAClC,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAO,EAAE,UAAA,CAAW,GAAG,CAAA,GAAI,IAAA,GAAO,CAAE,CAAA;AAC9D,EAAA,MAAM,KAAA,GAAQ,EAAE,KAAA,IAAS,SAAA;AACzB,EAAA,MAAM,GAAA,GAAM,SAAA,CAAU,GAAA,EAAK,CAAA,EAAG,KAAK,CAAA;AACnC,EAAA,MAAM,MAAM,SAAA,CAAU,GAAA,EAAK,GAAG,KAAA,KAAU,SAAA,GAAY,cAAc,SAAS,CAAA;AAC3E,EAAA,MAAM,EAAA,GAAK,IAAI,GAAA,CAAI,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM,CAAC,CAAA,EAAG,CAAC,CAAC,CAAC,CAAA;AACjD,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAC,GAAG,CAAA,KAAc;AACtC,IAAA,MAAM,CAAA,GAAI,EAAA,CAAG,GAAA,CAAI,IAAA,CAAK,CAAC,CAAW,CAAA;AAClC,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,CAAC,IAAA,CAAK,CAAC,CAAA,GAAI,CAAC,CAAA,EAAa,IAAA,CAAK,CAAC,CAAA,GAAI,CAAC,CAAW,CAAA;AAAA,MACvD,MAAA,EAAQ,CAAC,IAAA,CAAK,CAAC,CAAA,GAAI,CAAC,CAAA,EAAa,IAAA,CAAK,CAAC,CAAA,GAAI,CAAC,CAAW,CAAA;AAAA,MACvD,WAAA,EAAa,IAAA,CAAK,GAAA,CAAI,CAAC,CAAW,CAAA;AAAA,MAClC,WAAA,EAAa,IAAA,CAAK,GAAA,CAAI,CAAC,CAAW,CAAA;AAAA,MAClC,MAAM,QAAA,CAAS,CAAC,KAAK,KAAA,CAAM,IAAA,CAAK,CAAC,CAAC,CAAA;AAAA,MAClC,KAAA,EAAO;AAAA,KACT;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,EAAE,EAAA,IAAM,cAAA;AAAA,IACZ,IAAA;AAAA,IACA,iBAAA,EAAmB,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA;AAAA,IAC5B,iBAAA,EAAmB,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA;AAAA,IAC5B,cAAA,EAAgB,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA;AAAA,IACzB,cAAA,EAAgB,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA;AAAA,IACzB,QAAA,EAAU,KAAA;AAAA,IACV,UAAA,EAAY,QAAA;AAAA,IACZ,OAAA;AAAA,IACA,GAAI,EAAE,MAAA,KAAW,MAAA,GAAY,EAAC,GAAI,EAAE,SAAA,EAAW,CAAA,CAAE,MAAA,EAAO;AAAA,IACxD,GAAI,EAAE,IAAA,KAAS,MAAA,GAAY,EAAC,GAAI,EAAE,OAAA,EAAS,CAAA,CAAE,IAAA;AAAK,GACpD;AACF;AAWA,SAAS,MAAM,MAAA,EAA+B;AAC5C,EAAA,MAAM,MAAc,EAAC;AACrB,EAAA,IAAI,OAAa,EAAC;AAClB,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,MAAM,KAAA,GAAQ,KAAK,CAAC,CAAA;AACpB,IAAA,IAAA,CAAK,KAAK,CAAC,CAAA;AACX,IAAA,IAAI,UAAU,MAAA,EAAW;AACzB,IAAA,IAAI,CAAA,CAAE,CAAC,CAAA,KAAM,KAAA,CAAM,CAAC,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,KAAM,KAAA,CAAM,CAAC,CAAA,EAAG,IAAA,EAAA;AAAA,SAAA,IACnC,QAAQ,CAAA,EAAG;AAClB,MAAA,GAAA,CAAI,KAAK,IAAI,CAAA;AACb,MAAA,IAAA,GAAO,EAAC;AACR,MAAA,IAAA,GAAO,CAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,IAAI,IAAA,IAAQ,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA;AAC5B,EAAA,OAAO,GAAA;AACT;AAIA,IAAM,IAAA,GAAO,CAAC,CAAA,EAAO,CAAA,EAAO,CAAA,KAAA,CAAmB,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,KAAM,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,CAAA,GAAA,CAAM,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,KAAM,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,CAAA;AACzG,SAAS,WAAW,CAAA,EAA0B;AAC5C,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,QAAQ,CAAA,EAAA,EAAK;AACjC,IAAA,MAAM,CAAC,CAAA,EAAG,CAAC,CAAA,GAAI,CAAC,CAAA,CAAE,CAAC,CAAA,EAAS,CAAA,CAAA,CAAG,CAAA,GAAI,CAAA,IAAK,CAAA,CAAE,MAAM,CAAO,CAAA;AACvD,IAAA,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,IAAI,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA;AAAA,EAC/B;AACA,EAAA,OAAO,CAAA,GAAI,CAAA;AACb;AAKA,SAAS,MAAM,CAAA,EAA2B;AACxC,EAAA,IAAI,CAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAE,CAAA,GAAI;AAAA,IACrB,MAAA,CAAO,iBAAA;AAAA,IACP,MAAA,CAAO,iBAAA;AAAA,IACP,MAAA,CAAO,iBAAA;AAAA,IACP,MAAA,CAAO;AAAA,GACT;AACA,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,CAAA,IAAK,CAAA;AACnB,IAAA,CAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAE,CAAA,GAAI,CAAC,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,CAAC,CAAA,EAAG,IAAA,CAAK,IAAI,EAAA,EAAI,CAAC,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,CAAC,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,CAAC,CAAC,CAAA;AACxF,EAAA,OAAO,CAAA,CAAE,MAAA,GAAS,CAAA,IAAK,IAAA,CAAK,IAAI,UAAA,CAAW,CAAC,CAAC,CAAA,IAAK,IAAA,IAAA,CAAS,EAAA,GAAK,EAAA,KAAO,CAAA,GAAA,CAAK,KAAK,EAAA,KAAO,CAAA,CAAA;AAC1F;AAMA,SAAS,OAAO,CAAA,EAA0B;AACxC,EAAA,MAAM,IAAI,CAAA,CAAE,MAAA;AACZ,EAAA,MAAM,IAAA,GAAO,CAAC,CAAA,EAAO,CAAA,EAAO,CAAA,KAAkB,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,CAAA,EAAG,CAAA,EAAG,CAAC,CAAC,CAAA;AACrE,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA;AACrB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAG,CAAA,EAAA,EAAK;AAC9B,MAAA,IAAI,CAAA,KAAM,CAAA,IAAK,CAAA,KAAM,CAAA,GAAI,CAAA,EAAG;AAC5B,MAAA,MAAM,CAAC,GAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,CAAC,CAAA,CAAE,CAAC,CAAA,EAAS,CAAA,CAAA,CAAG,IAAI,CAAA,IAAK,CAAC,GAAS,CAAA,CAAE,CAAC,GAAS,CAAA,CAAA,CAAG,CAAA,GAAI,CAAA,IAAK,CAAC,CAAO,CAAA;AACxF,MAAA,IAAI,IAAA,CAAK,GAAG,CAAA,EAAG,CAAC,IAAI,IAAA,CAAK,CAAA,EAAG,GAAG,CAAC,CAAA,IAAK,KAAK,IAAA,CAAK,CAAA,EAAG,GAAG,CAAC,CAAA,GAAI,KAAK,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,IAAK,CAAA,EAAG;AAC9E,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,IAAK,IAAA,CAAK,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,IAAA,CAAK,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AACvD,MAAA,MAAM,CAAA,GAAQ,CAAC,CAAA,CAAE,CAAC,IAAI,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,IAAK,EAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,CAAE,CAAA;AACjE,MAAA,OAAO;AAAA,QACL,GAAG,MAAA,CAAO,CAAC,GAAG,CAAA,CAAE,MAAM,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA,EAAG,GAAG,GAAG,CAAA,CAAE,MAAM,CAAA,GAAI,CAAC,CAAC,CAAC,CAAA;AAAA,QACtD,GAAG,MAAA,CAAO,CAAC,CAAA,EAAG,GAAG,CAAA,CAAE,KAAA,CAAM,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAC,CAAC,CAAC;AAAA,OACzC;AAAA,IACF;AACF,EAAA,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;AAChB;AAEA,IAAM,KAAA,GAAQ,CAAC,CAAA,KACb,CAAA,CAAE,MAAA,CAAO,MAAA,GAAS,CAAA,IAClB,CAAA,CAAE,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,IAAK,MAAA,CAAO,QAAA,CAAS,CAAC,CAAC,CAAA,IACnE,OAAA,CAAQ,CAAA,CAAE,IAAI,CAAA,KAAM,CAAA;AAuBf,SAAS,YAAA,CACd,KAAA,EACA,MAAA,EACA,CAAA,GAA4B,EAAC,EACV;AACnB,EAAA,MAAM,EAAE,EAAA,GAAK,iBAAA,EAAmB,GAAG,MAAK,GAAI,CAAA;AAC5C,EAAA,MAAM,KAAA,GAAQA,OAAA,CAAc,KAAA,EAAO,MAAA,EAAQ,IAAoB,CAAA;AAE/D,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,QAAA,CAChB,MAAA,CAAO,CAAC,CAAA,KAA2B,CAAA,CAAE,IAAA,KAAS,SAAA,IAAa,KAAA,CAAM,CAAC,CAAC,CAAA,CACnE,OAAA;AAAA,IAAQ,CAAC,CAAA,KACR,KAAA,CAAM,CAAA,CAAE,MAAM,CAAA,CACX,OAAA,CAAQ,MAAM,CAAA,CACd,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,KAAA,CAAM,CAAC,CAAC,CAAA,CACvB,GAAA,CAAI,CAAC,OAAA,MAAyB,EAAE,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,OAAA,EAAS,SAAA,EAAW,IAAA,CAAK,CAAA,CAAE,IAAI,GAAE,CAAE;AAAA,GACtF;AACF,EAAA,OAAO;AAAA,IACL,EAAA;AAAA,IACA,IAAA;AAAA,IACA,UAAA,EAAY,CAAC,CAAA,KAAM,CAAA,CAAE,OAAA;AAAA,IACrB,YAAA,EAAc,CAAC,CAAA,KAAM,CAAA,CAAE,SAAA;AAAA,IACvB,gBAAA,EAAkB,WAAA;AAAA,IAClB,MAAA,EAAQ,IAAA;AAAA,IACR,OAAA,EAAS;AAAA,GACX;AACF","file":"deckgl.js","sourcesContent":["/**\n * The deck.gl adapter: team logos, team-coloured arcs and sporty playing surfaces as deck.gl layer props. Pure: it\n * never imports deck.gl (`@deck.gl/core` and `@deck.gl/layers` 9.4 or later are optional peers), so the props can be\n * built anywhere, a server included; pass them to the layer, as in `new IconLayer(logoIconLayer(rows, o))`. The props\n * are plain objects: the data rows, accessor functions that read them, and the layer's own settings. `surfaceLayer`\n * draws through `@sportsdataverse/sporty`, which this entry imports when it loads. Synchronous: call after\n * `loadLeague(league)` / `preloadAll()`. The Python package's `sdvplot.pydeck` builds the same props for pydeck; the\n * two are held to one shared fixture.\n */\nimport { type PolygonFeature, surface as sportySurface } from \"@sportsdataverse/sporty\";\nimport type { LeagueOf, OptionsOf, Sport } from \"@sportsdataverse/sporty\";\nimport { type Row, aspect, colorList, column, markPlacements } from \"./_web.js\";\nimport { hex6 } from \"./contrast.js\";\nimport { InputError, warn } from \"./errors.js\";\nimport { normValue } from \"./normalize.js\";\nimport { checkAlpha } from \"./placement.js\";\nimport { type Value, resolveSync } from \"./resolve.js\";\nimport { teamPalette } from \"./team-palette.js\";\nimport type { IdSystem, League, SeasonInput, Variant, Which } from \"./types.js\";\n\nexport type { Row } from \"./_web.js\";\n/** A deck.gl colour: `[r, g, b, a]`, each 0-255. */\nexport type Rgba = [r: number, g: number, b: number, a: number];\n/** An icon deck.gl fetches and packs into its atlas itself (an \"auto-packed\" icon), keyed by its URL. */\nexport interface LogoIcon {\n url: string;\n /** The icon's size in the atlas, px: 128 tall, as wide as the logo's aspect makes it. */\n width: number;\n height: number;\n /** Half the height: the logo is centred on its point. */\n anchorY: number;\n mask: false;\n}\n/** One `logoIconLayer` data row. `index` is the row's position in the input (left-out rows leave gaps). */\nexport interface IconRow {\n position: [x: number, y: number];\n icon: LogoIcon;\n /** The resolved team id. */\n team: string;\n index: number;\n}\n/**\n * One `passArcLayer` data row. `team` is the resolved team id, or the row's own value as text when it does not\n * resolve (a number without \".0\", a missing value empty).\n */\nexport interface ArcRow {\n source: [x: number, y: number];\n target: [x: number, y: number];\n sourceColor: Rgba;\n targetColor: Rgba;\n team: string;\n index: number;\n}\n/** One `surfaceLayer` data row: a closed loop of a sporty polygon feature. */\nexport interface SurfaceRow {\n name: string;\n /** One closed loop of the feature's path (deck.gl closes it). */\n polygon: (readonly [x: number, y: number])[];\n fillColor: Rgba;\n}\n/** `logoIconLayer`'s props, for deck.gl's `IconLayer`. */\nexport interface LogoIconLayerProps {\n id: string;\n data: IconRow[];\n getPosition: (d: IconRow) => [number, number];\n getIcon: (d: IconRow) => LogoIcon;\n getSize: number;\n sizeUnits: \"pixels\";\n opacity: number;\n}\n/** `passArcLayer`'s props, for deck.gl's `ArcLayer`. */\nexport interface PassArcLayerProps {\n id: string;\n data: ArcRow[];\n getSourcePosition: (d: ArcRow) => [number, number];\n getTargetPosition: (d: ArcRow) => [number, number];\n getSourceColor: (d: ArcRow) => Rgba;\n getTargetColor: (d: ArcRow) => Rgba;\n getWidth: number;\n widthUnits: \"pixels\";\n opacity: number;\n getHeight?: number;\n getTilt?: number;\n}\n/** `surfaceLayer`'s props, for deck.gl's `PolygonLayer`. */\nexport interface SurfaceLayerProps {\n id: string;\n data: SurfaceRow[];\n getPolygon: (d: SurfaceRow) => SurfaceRow[\"polygon\"];\n getFillColor: (d: SurfaceRow) => Rgba;\n coordinateSystem: \"cartesian\";\n filled: true;\n stroked: false;\n}\n\n/** `logoIconLayer` options. */\nexport interface LogoIconOptions {\n /** Name of the row column holding each logo's x position (a longitude on a map, or a surface's own x). */\n x: string;\n /** Name of the row column holding each logo's y position. */\n y: string;\n /** Name of the row column holding the team (abbreviation, name or id; see `idSystem`). */\n team: string;\n /** The league the teams belong to, e.g. \"nhl\". */\n league: League;\n /** A season (number or string) for every row, or the name of a row column holding each row's season. */\n season?: SeasonInput;\n /** Logo variant, e.g. \"dark\". Default \"default\". */\n variant?: Variant;\n /** How the `team` values are read. Default \"auto\". */\n idSystem?: IdSystem;\n /** The logo's height on screen in px, 1 or more (deck.gl's `getSize` in \"pixels\" units). Default 32. */\n size?: number;\n /** The layer's opacity in [0, 1]. Default 1. */\n alpha?: number;\n /** The layer id. Default \"sdvplot-logos\". */\n id?: string;\n}\n/** `passArcLayer` options. */\nexport interface PassArcOptions {\n /** Name of the row column holding each arc's source x. */\n x: string;\n /** Name of the row column holding each arc's source y. */\n y: string;\n /** Name of the row column holding each arc's target x. */\n xend: string;\n /** Name of the row column holding each arc's target y. */\n yend: string;\n /** Name of the row column holding the team the arc is coloured by. */\n team: string;\n /** The league the teams belong to, e.g. \"soccer\". */\n league: League;\n /** The season the teams are resolved for. */\n season?: SeasonInput;\n /** How the `team` values are read. Default \"auto\". */\n idSystem?: IdSystem;\n /** The colour at the source end, \"primary\" (default) or \"secondary\"; the target end takes the other. */\n which?: Which;\n /**\n * The background the arcs are drawn on. Given, each end's colour keeps 3:1 contrast against it (dark mode) and\n * aims to stay distinct (CIE76 ΔE of 20 or more) from every other team's colour at that end, through the shared team\n * palette, as `teamColorPalette` does in the other adapters. Caveat: a colour that does not read gives way to the\n * team's other colour, so when only one of a team's two colours reads on the background, both ends take it and the\n * arcs no longer show their direction (France's navy and mint on a dark pitch are both mint). Pick a background on\n * which both colours read (France's both read on a mid-tone green such as `#4a7f3a`), or check that\n * `sourceColor` and `targetColor` differ.\n */\n background?: string;\n /** The colour of a team that does not resolve, or has no colour. Default \"#808080\". */\n fallback?: string;\n /** The arc's width in px, 1 or more. Default 2. */\n width?: number;\n /** The layer's opacity in [0, 1]. Default 1. */\n alpha?: number;\n /**\n * deck.gl's `getHeight`, how high each arc rises for its length, 0 or more (0 draws a straight line). Default none:\n * deck.gl's 1. Lower, such as 0.3, keeps arcs laid flat (`tilt: 90`) close to their chord, inside the surface.\n */\n height?: number;\n /**\n * deck.gl's `getTilt`, degrees in [-90, 90]: 90 lays each arc flat on the surface, so a top-down 2D view (an\n * OrthographicView) shows the curve. Default none: deck.gl's upright arcs, for a pitched 3D view.\n */\n tilt?: number;\n /** The layer id. Default \"sdvplot-arcs\". */\n id?: string;\n}\n/** `surfaceLayer` options: sporty's own `surface()` options for the sport, plus the layer id. */\nexport type SurfaceLayerOptions<S extends Sport> = OptionsOf<S> & {\n /** The layer id. Default \"sdvplot-surface\". */\n id?: string;\n};\n\n/** The px height an icon is packed into deck.gl's atlas at (the logo is drawn at `size`, so this is its sharpness). */\nconst ICON_PX = 128;\nconst real = (v: unknown): v is number => typeof v === \"number\" && Number.isFinite(v);\nfunction checkPx(name: string, v: unknown): number {\n if (!real(v) || v < 1) throw new InputError(`${name} is in px, 1 or more, got ${String(v)}`);\n return v;\n}\n/** The alpha byte of `#rgb`, `#rgba`, `#rrggbb` or `#rrggbbaa` (255 when it gives none). */\nfunction alphaOf(color: string): number {\n let c = String(color).trim().replace(/^#+/, \"\");\n if (c.length === 4) c = [...c].map((ch) => ch + ch).join(\"\");\n return c.length === 8 ? Number.parseInt(c.slice(6), 16) : 255;\n}\n/** `#rgb`, `#rgba`, `#rrggbb` or `#rrggbbaa` as deck.gl's `[r, g, b, a]`. */\nfunction rgba(color: string): Rgba {\n const a = alphaOf(color);\n const [r, g, b] = [1, 3, 5].map((i) =>\n Number.parseInt(hex6(color, { dropAlpha: true }).slice(i, i + 2), 16),\n );\n return [r as number, g as number, b as number, a];\n}\n\n/**\n * deck.gl `IconLayer` props drawing each row's team logo at its (x, y). The logos are auto-packed icons: deck.gl\n * fetches each URL once and packs it into its own atlas, at 128 px tall and the logo's aspect, centred on the point.\n * A team with no logo (or one that does not resolve) is left out with one warning, as the other adapters do; so is a\n * row with a missing x or y. `x` and `y` are in the layer's coordinates: longitude and latitude on a map, or a\n * surface's own units on `surfaceLayer` (set `coordinateSystem: \"cartesian\"` on both, or use a non-geographic view).\n *\n * @example\n * ```ts\n * import { loadLeague } from \"@sportsdataverse/sdvplot\";\n * import { logoIconLayer } from \"@sportsdataverse/sdvplot/deckgl\";\n *\n * await loadLeague(\"nhl\");\n * // Edmonton's first shot of game 7 of the 2024 Stanley Cup Final (NHL api-web), in feet from centre ice\n * const shot = { team: \"EDM\", x: 82, y: -3 };\n * const props = logoIconLayer([shot], { x: \"x\", y: \"y\", team: \"team\", league: \"nhl\", size: 28 });\n * // in the browser: new IconLayer({ ...props, coordinateSystem: \"cartesian\" })\n * props.data[0]?.icon.url;\n * ```\n */\nexport function logoIconLayer(rows: readonly Row[], o: LogoIconOptions): LogoIconLayerProps {\n const size = checkPx(\"size\", o.size ?? 32);\n const opacity = checkAlpha(o.alpha ?? 1);\n const data = markPlacements(rows, \"logo\", o).map((p): IconRow => {\n const height = ICON_PX;\n return {\n position: [Number(p.x), Number(p.y)],\n icon: { url: p.url, width: Math.round(ICON_PX * aspect(p)), height, anchorY: height / 2, mask: false },\n team: p.id,\n index: p.index,\n };\n });\n return {\n id: o.id ?? \"sdvplot-logos\",\n data,\n getPosition: (d) => d.position,\n getIcon: (d) => d.icon,\n getSize: size,\n sizeUnits: \"pixels\",\n opacity,\n };\n}\n\n/** An unresolved team value as text, the same in Python: a number without \".0\", a missing one empty. */\nconst label = (t: unknown): string =>\n t === null || t === undefined ? \"\" : typeof t === \"number\" ? (normValue(t) ?? \"\") : String(t);\n\n/**\n * One colour per distinct team at one end of the arcs (`ids[j]` null for a team that did not resolve): the teams'\n * `which` colours, or the shared palette of them on `background`. A team that did not resolve takes the fallback and\n * stays out of the palette, so it never moves a real team's colour (and no warning names it).\n */\nfunction endColors(ids: readonly (string | null)[], o: PassArcOptions, which: Which): string[] {\n const fallback = hex6(o.fallback ?? \"#808080\");\n const co = { idSystem: \"team_id\" as const, ...(o.season === undefined ? {} : { season: o.season }) };\n const known = ids.filter((id): id is string => id !== null);\n const main = colorList(o.league, known, { ...co, which });\n const other = colorList(o.league, known, { ...co, which: which === \"primary\" ? \"secondary\" : \"primary\" });\n // a team with no `which` colour (often no secondary) takes its other colour, then the fallback\n let colors = main.map((c, i) => hex6(c ?? other[i] ?? fallback, { dropAlpha: true }));\n if (o.background !== undefined) colors = teamPalette(colors, other, hex6(o.background), known);\n let k = 0;\n return ids.map((id) => (id === null ? fallback : (colors[k++] as string)));\n}\n\n/**\n * deck.gl `ArcLayer` props: one arc per row from (x, y) to (xend, yend), in the team's colours: its primary colour at\n * the source and its secondary at the target (`which: \"secondary\"` swaps them), so the two ends tell the direction\n * apart where the two colours differ (see `background`). Each team keeps one colour per end, the teams taken in the\n * order they first appear. With `background`, every colour keeps 3:1 contrast against it and aims to stay distinct from\n * the other teams' (the shared team palette; when it cannot, it keeps the readable colour and warns once). A team that\n * does not resolve takes `fallback`, as given (its contrast is not checked); a row with a missing\n * coordinate is left out with one warning.\n *\n * @example\n * ```ts\n * import { loadLeague } from \"@sportsdataverse/sdvplot\";\n * import { passArcLayer } from \"@sportsdataverse/sdvplot/deckgl\";\n *\n * await loadLeague(\"soccer\");\n * // France's first completed pass of the 2018 World Cup final (StatsBomb open data through SPADL, metres from the\n * // corner); France is ESPN soccer team 478\n * const pass = { team: \"478\", start_x: 54.68750000000001, start_y: 6.375, end_x: 56.4375, end_y: 1.2750000000000057 };\n * const props = passArcLayer([pass], {\n * x: \"start_x\",\n * y: \"start_y\",\n * xend: \"end_x\",\n * yend: \"end_y\",\n * team: \"team\",\n * league: \"soccer\",\n * idSystem: \"team_id\",\n * tilt: 90,\n * });\n * // in the browser: new ArcLayer({ ...props, coordinateSystem: \"cartesian\" })\n * props.data[0]?.sourceColor;\n * ```\n */\nexport function passArcLayer(rows: readonly Row[], o: PassArcOptions): PassArcLayerProps {\n const width = checkPx(\"width\", o.width ?? 2);\n const opacity = checkAlpha(o.alpha ?? 1);\n if (o.tilt !== undefined && !(real(o.tilt) && o.tilt >= -90 && o.tilt <= 90))\n throw new InputError(`tilt is in degrees, in [-90, 90], got ${String(o.tilt)}`);\n if (o.height !== undefined && !(real(o.height) && o.height >= 0))\n throw new InputError(`height is an arc's height multiplier, 0 or more, got ${String(o.height)}`);\n const cols = [o.x, o.y, o.xend, o.yend].map((c, k) =>\n column(rows, c, [\"x\", \"y\", \"xend\", \"yend\"][k] as string),\n );\n const teams = column(rows, o.team, \"team\");\n const keep: number[] = [];\n const missing: Value[] = [];\n rows.forEach((_, i) => {\n if (cols.every((c) => real(c[i]))) keep.push(i);\n else missing.push(teams[i] as Value);\n });\n if (missing.length > 0) {\n const shown =\n missing.slice(0, 10).map(String).join(\", \") +\n (missing.length > 10 ? ` and ${missing.length - 10} more` : \"\");\n warn(\n `deckgl:arcs:${o.league}:missing:${shown}`,\n `skipped ${missing.length} arc(s) with a missing coordinate: ${shown}`,\n );\n }\n const ro = {\n ...(o.season === undefined ? {} : { season: o.season }),\n ...(o.idSystem === undefined ? {} : { idSystem: o.idSystem }),\n };\n const kept = keep.map((i) => teams[i] as Value);\n const resolved = resolveSync(kept, o.league, ro);\n // one colour per distinct team, in order of first appearance; an unresolved team is keyed by its own value\n const keys = kept.map((t, j) => resolved[j] ?? `?${label(t)}`);\n const distinct = [...new Set(keys)];\n const ids = distinct.map((k) => (k.startsWith(\"?\") ? null : k));\n const which = o.which ?? \"primary\";\n const src = endColors(ids, o, which);\n const tgt = endColors(ids, o, which === \"primary\" ? \"secondary\" : \"primary\");\n const at = new Map(distinct.map((k, j) => [k, j]));\n const data = keep.map((i, j): ArcRow => {\n const k = at.get(keys[j] as string) as number;\n return {\n source: [cols[0]?.[i] as number, cols[1]?.[i] as number],\n target: [cols[2]?.[i] as number, cols[3]?.[i] as number],\n sourceColor: rgba(src[k] as string),\n targetColor: rgba(tgt[k] as string),\n team: resolved[j] ?? label(kept[j]),\n index: i,\n };\n });\n return {\n id: o.id ?? \"sdvplot-arcs\",\n data,\n getSourcePosition: (d) => d.source,\n getTargetPosition: (d) => d.target,\n getSourceColor: (d) => d.sourceColor,\n getTargetColor: (d) => d.targetColor,\n getWidth: width,\n widthUnits: \"pixels\",\n opacity,\n ...(o.height === undefined ? {} : { getHeight: o.height }),\n ...(o.tilt === undefined ? {} : { getTilt: o.tilt }),\n };\n}\n\ntype Pt = readonly [x: number, y: number];\n/**\n * A feature's path as closed loops. sporty (after sportyR) draws some features as two loops in one path, such as a\n * faceoff circle's two half rings each closing back on its first point: an SVG or canvas fill draws that as it is, but\n * deck.gl triangulates a polygon as one simple ring and fills the wrong side of it. A loop ends where the path comes\n * back to that loop's first point, after at least two other points (a repeated first point does not end it). The\n * same rule is in sdvplot.pydeck. ponytail: a loop inside another would be filled, not cut out as a hole; sporty\n * builds every ring from two half rings, so none is.\n */\nfunction loops(points: readonly Pt[]): Pt[][] {\n const out: Pt[][] = [];\n let loop: Pt[] = [];\n let away = 0; // points of this loop that are not its first\n for (const p of points) {\n const first = loop[0];\n loop.push(p);\n if (first === undefined) continue;\n if (p[0] !== first[0] || p[1] !== first[1]) away++;\n else if (away >= 2) {\n out.push(loop);\n loop = [];\n away = 0;\n }\n }\n if (away >= 2) out.push(loop); // an open path, closed by deck.gl\n return out;\n}\n\n// Copied from ./three/surface.ts (PR #79), where the three.js surface needs the same split: kept here so this PR stands\n// alone. ponytail: one shared internal module (src/rings.ts) for both once both have merged.\nconst turn = (a: Pt, b: Pt, c: Pt): number => (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]);\nfunction signedArea(r: readonly Pt[]): number {\n let s = 0;\n for (let i = 0; i < r.length; i++) {\n const [a, b] = [r[i] as Pt, r[(i + 1) % r.length] as Pt];\n s += a[0] * b[1] - b[0] * a[1];\n }\n return s / 2;\n}\n/**\n * No area to fill: a path that goes out along a line and back along it (the NLL goal fan), which a fill leaves\n * invisible, as sporty's own SVG does, or the sliver left where a ring touched itself.\n */\nfunction empty(r: readonly Pt[]): boolean {\n let [x0, y0, x1, y1] = [\n Number.POSITIVE_INFINITY,\n Number.POSITIVE_INFINITY,\n Number.NEGATIVE_INFINITY,\n Number.NEGATIVE_INFINITY,\n ];\n for (const [x, y] of r)\n [x0, y0, x1, y1] = [Math.min(x0, x), Math.min(y0, y), Math.max(x1, x), Math.max(y1, y)];\n return r.length < 3 || Math.abs(signedArea(r)) <= 1e-9 * ((x1 - x0) ** 2 + (y1 - y0) ** 2);\n}\n/**\n * A ring that crosses itself split at each crossing into rings that do not, each to be filled: what an SVG (nonzero)\n * fill shows of a figure-of-eight, and what deck.gl's earcut cannot triangulate. sporty has a few: the NHL goaltender's\n * trapezoids and some faceoff hash marks twist at their corners by an inch.\n */\nfunction simple(r: readonly Pt[]): Pt[][] {\n const n = r.length;\n const side = (a: Pt, b: Pt, c: Pt): number => Math.sign(turn(a, b, c));\n for (let i = 0; i < n; i++)\n for (let j = i + 2; j < n; j++) {\n if (i === 0 && j === n - 1) continue; // neighbours across the closing edge\n const [a, b, c, d] = [r[i] as Pt, r[(i + 1) % n] as Pt, r[j] as Pt, r[(j + 1) % n] as Pt];\n if (side(a, b, c) * side(a, b, d) >= 0 || side(c, d, a) * side(c, d, b) >= 0) continue;\n const s = turn(c, d, a) / (turn(c, d, a) - turn(c, d, b)); // where the crossing is along a -> b\n const x: Pt = [a[0] + s * (b[0] - a[0]), a[1] + s * (b[1] - a[1])];\n return [\n ...simple([...r.slice(0, i + 1), x, ...r.slice(j + 1)]),\n ...simple([x, ...r.slice(i + 1, j + 1)]),\n ];\n }\n return [[...r]];\n}\n\nconst drawn = (f: PolygonFeature): boolean =>\n f.points.length > 0 &&\n f.points.every(([x, y]) => Number.isFinite(x) && Number.isFinite(y)) &&\n alphaOf(f.fill) !== 0;\n\n/**\n * deck.gl `PolygonLayer` props drawing sporty's playing surface for `sport` and `league` (sporty's own league keys,\n * e.g. `surfaceLayer(\"hockey\", \"nhl\")`, `surfaceLayer(\"soccer\", \"fifa\")`), in the surface's own coordinates: deck.gl's\n * `\"cartesian\"` coordinate system, in the surface's units (feet for a rink, metres for a pitch) with the origin at its\n * centre, the frame sporty draws in and NHL api-web's shot coordinates are in. Each closed loop of a polygon feature\n * is one data row (a faceoff circle is two: its half rings; a loop that crosses itself is split at the crossing into\n * rings that do not, and a loop with no area is left out), in sporty's drawing order, filled with its colour (alpha\n * included). sporty's default strokes equal their fills, so\n * the layer is fill-only; a hidden feature (a `#rrggbb00` fill) and text features (a football field's yard numbers)\n * are left out. `o` is passed to sporty's `surface()` (`updates`, `colorUpdates`, `units`, `rotation`, ...); sporty's\n * own errors escape unwrapped. Draw it with deck.gl's OrthographicView.\n *\n * @example\n * ```ts\n * import { surfaceLayer } from \"@sportsdataverse/sdvplot/deckgl\";\n *\n * const rink = surfaceLayer(\"hockey\", \"nhl\");\n * // in the browser: new PolygonLayer(rink), in a Deck with views: new OrthographicView({ flipY: false })\n * rink.data.length;\n * ```\n */\nexport function surfaceLayer<S extends Sport>(\n sport: S,\n league: LeagueOf<S>,\n o: SurfaceLayerOptions<S> = {} as SurfaceLayerOptions<S>,\n): SurfaceLayerProps {\n const { id = \"sdvplot-surface\", ...opts } = o;\n const scene = sportySurface(sport, league, opts as OptionsOf<S>);\n // ponytail: features draw in array order (sporty's zIndex is its position); sort here if that ever changes\n const data = scene.features\n .filter((f): f is PolygonFeature => f.kind === \"polygon\" && drawn(f))\n .flatMap((f) =>\n loops(f.points)\n .flatMap(simple)\n .filter((r) => !empty(r))\n .map((polygon): SurfaceRow => ({ name: f.name, polygon, fillColor: rgba(f.fill) })),\n );\n return {\n id,\n data,\n getPolygon: (d) => d.polygon,\n getFillColor: (d) => d.fillColor,\n coordinateSystem: \"cartesian\",\n filled: true,\n stroked: false,\n };\n}\n"]}
package/dist/echarts.js CHANGED
@@ -1,8 +1,8 @@
1
- import { axisLetter, axisPlacements, imageSources, aspect, colorList, markPlacements } from './chunk-SEBO35DV.js';
2
- export { embedSources } from './chunk-SEBO35DV.js';
3
- import { checkHeight, checkAlpha } from './chunk-RMT2GMFH.js';
4
- import './chunk-KKH6ABMA.js';
5
- import './chunk-TAXO3VXH.js';
1
+ import { axisLetter, axisPlacements, imageSources, aspect, colorList, markPlacements } from './chunk-UL5M6KDE.js';
2
+ export { embedSources } from './chunk-UL5M6KDE.js';
3
+ import { checkHeight, checkAlpha } from './chunk-7ULOCCFL.js';
4
+ import './chunk-ZAEQXFJM.js';
5
+ import './chunk-J6R2LEJ7.js';
6
6
  import { InputError, UnsupportedTargetError } from './chunk-E7G7VSLV.js';
7
7
 
8
8
  // src/echarts.ts
package/dist/g2.d.ts ADDED
@@ -0,0 +1,251 @@
1
+ import { R as Row, a as DrawnMark } from './_web-D7Aa5Rd8.js';
2
+ export { e as embedSources } from './_web-D7Aa5Rd8.js';
3
+ import { E as EspnHeadshotLeague } from './headshots-B2J_LOO8.js';
4
+ import { L as League, S as SeasonInput, V as Variant, M as MarkType, I as IdSystem, W as Which, H as HeadshotIdSystem } from './types-C7n6gJF3.js';
5
+ import './resolve-CQW-jzvr.js';
6
+
7
+ /**
8
+ * The G2 5 adapter, and so Ant Design Charts (`@ant-design/plots`), whose configs are G2 specs underneath: team colours
9
+ * as a `scale.color` (`teamColorScale`) or a list (`teamColorPalette`), logos / wordmarks / headshots as G2 `image`
10
+ * marks (`logoMark`, `wordmarkMark`, `headshotMark`), and logos as a band axis' labels (`axisLogos`). Each returns
11
+ * plain spec pieces: a mark goes in a view's `children` (`chart.options(...)`) or an Ant Design Charts config's
12
+ * `annotations`, a scale in `scale.color`, the axis labels in `axis.x`. Pure: @antv/g2 is never imported (the types
13
+ * are structural, checked against G2 5.4's own). Call after `loadLeague(league)` / `preloadAll()`.
14
+ */
15
+
16
+ /** `teamColorPalette` / `teamColorScale` options. */
17
+ interface G2ColorOptions {
18
+ /** "primary" (default) or "secondary" colour. */
19
+ which?: Which;
20
+ /** The season the teams are resolved for (a number or string). */
21
+ season?: SeasonInput;
22
+ /** How the team values are read. Default "auto". */
23
+ idSystem?: IdSystem;
24
+ /** The colour of an unresolved team. Default "#808080". */
25
+ fallback?: string;
26
+ /**
27
+ * The chart's background. Given, a team colour under 3:1 contrast against it is swapped for the team's other
28
+ * colour, else moved towards white (on a dark background) or black (a light one) until it reads: dark mode. A
29
+ * colour that would then sit too close to an earlier team's (CIE76 ΔE under 20) takes the team's other colour, or
30
+ * the nearest colour to its own that is distinct and still reads; failing that it is kept, with one warning.
31
+ */
32
+ background?: string;
33
+ }
34
+ /**
35
+ * One colour per team, in order, for anything that takes colours by position. With `background`, every colour keeps
36
+ * 3:1 contrast against it (dark mode) and aims to stay distinct from the others. `teamColorScale` puts the same
37
+ * colours on a G2 `scale.color`, keyed by team.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import { loadLeague } from "@sportsdataverse/sdvplot";
42
+ * import { teamColorPalette } from "@sportsdataverse/sdvplot/g2";
43
+ *
44
+ * await loadLeague("nfl");
45
+ * teamColorPalette("nfl", ["KC", "LAC", "DEN", "LV"], { background: "#141414" });
46
+ * ```
47
+ */
48
+ declare function teamColorPalette(league: League, teams: readonly unknown[], o?: G2ColorOptions): string[];
49
+ /** A G2 `scale.color`: an ordinal scale from each team value to its colour. */
50
+ interface G2ColorScale<T = unknown> {
51
+ /** Ordinal: a numeric team column (ESPN ids, say) keeps one colour per id, never a gradient. */
52
+ type: "ordinal";
53
+ /** The team values exactly as the data holds them (numbers stay numbers), each once and in order. */
54
+ domain: T[];
55
+ /** Their colours, in the same order. */
56
+ range: string[];
57
+ }
58
+ /**
59
+ * Team colours as a G2 `scale.color` (`{ type: "ordinal", domain, range }`): the mark's `encode.color` field holds the
60
+ * team values, and each draws in its own colour; the legend lists the teams in this order. With `background` the
61
+ * colours read on it (dark mode). Pass the teams as the data holds them: G2 matches the domain to the data by exact
62
+ * value, so a numeric id stays a number here (12, not "12"); a value given twice (also 12 and "12") is kept once.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * import { loadLeague } from "@sportsdataverse/sdvplot";
67
+ * import { teamColorScale } from "@sportsdataverse/sdvplot/g2";
68
+ *
69
+ * await loadLeague("nfl");
70
+ * // { type: "interval", encode: { x: "team", y: "wins", color: "team" }, scale: { color: <this> } }
71
+ * teamColorScale("nfl", ["KC", "LAC", "DEN", "LV"]);
72
+ * ```
73
+ */
74
+ declare function teamColorScale<T>(league: League, teams: readonly T[], o?: G2ColorOptions): G2ColorScale<T>;
75
+ interface Shared {
76
+ /** Image height in px, 1 or more (G2 sizes an image mark in px). Default 24. */
77
+ size?: number;
78
+ /** Opacity in [0, 1]. Default 1. */
79
+ alpha?: number;
80
+ /** url → data URI map from `embedSources`, to inline the images. */
81
+ embed?: ReadonlyMap<string, string>;
82
+ }
83
+ /** `logoMark` / `wordmarkMark` options. */
84
+ interface G2MarkOptions extends Shared {
85
+ /** Name of the row field holding each mark's x position (the field the chart's x channel encodes). */
86
+ x: string;
87
+ /** Name of the row field holding each mark's y position. */
88
+ y: string;
89
+ /** Name of the row field holding the team (abbreviation, name or id; see `idSystem`). */
90
+ team: string;
91
+ /** The league the teams belong to, e.g. "nfl". */
92
+ league: League;
93
+ /** A season (number or string) for every row, or the name of a row field holding each row's season. */
94
+ season?: SeasonInput;
95
+ /** Logo variant, e.g. "dark". Default "default". */
96
+ variant?: Variant;
97
+ /** How the `team` values are read. Default "auto". */
98
+ idSystem?: IdSystem;
99
+ }
100
+ /** `headshotMark` options. */
101
+ interface G2HeadshotOptions extends Shared {
102
+ /** Name of the row field holding each headshot's x position. */
103
+ x: string;
104
+ /** Name of the row field holding each headshot's y position. */
105
+ y: string;
106
+ /** Name of the row field holding the player id. */
107
+ player: string;
108
+ /** The league the players belong to, e.g. "nfl". */
109
+ league: EspnHeadshotLeague;
110
+ /** ESPN athlete ids, or nflverse gsis ids (needs `loadGsis()` first). Default "espn". */
111
+ idSystem?: HeadshotIdSystem;
112
+ }
113
+ /** One datum of an sdvplot image mark: the caller's row and what it draws. */
114
+ type G2ImageDatum = Row & {
115
+ /** The resolved team id or player id. */
116
+ sdv_id: string;
117
+ /** The image's URL (or data URI). */
118
+ sdv_src: string;
119
+ /** Its size in px. */
120
+ sdv_width: number;
121
+ sdv_height: number;
122
+ };
123
+ /**
124
+ * A G2 `image` mark (G2 5's `ImageMark`, structurally): one image per drawable row, centred on the row's (x, y) in
125
+ * the view's own scales. Out of the tooltip and the legend.
126
+ */
127
+ interface G2ImageMark {
128
+ type: "image";
129
+ data: G2ImageDatum[];
130
+ encode: {
131
+ x: string;
132
+ y: string;
133
+ src: "sdv_src";
134
+ };
135
+ style: {
136
+ width: (d: G2ImageDatum) => number;
137
+ height: (d: G2ImageDatum) => number;
138
+ opacity: number;
139
+ };
140
+ tooltip: false;
141
+ legend: false;
142
+ }
143
+ /**
144
+ * Team logos as a G2 `image` mark: one logo per row, `size` px tall, centred on the row's (`x`, `y`) fields in the
145
+ * view's scales. Put it last in a view's `children` (G2: `chart.options({ type: "view", children: [..., mark] })`), or
146
+ * in an Ant Design Charts config's `annotations`, which reach G2 as they are. A team with no logo draws nothing and
147
+ * warns once.
148
+ *
149
+ * @example
150
+ * ```ts
151
+ * import { loadLeague } from "@sportsdataverse/sdvplot";
152
+ * import { logoMark } from "@sportsdataverse/sdvplot/g2";
153
+ *
154
+ * await loadLeague("nfl");
155
+ * const rows = [
156
+ * { team: "KC", pf: 385, pa: 326 },
157
+ * { team: "LAC", pf: 402, pa: 301 },
158
+ * ];
159
+ * // chart.options({ type: "view", data: rows, children: [{ type: "point", encode: { x: "pf", y: "pa" } }, <this>] })
160
+ * logoMark(rows, { x: "pf", y: "pa", team: "team", league: "nfl", size: 32 });
161
+ * ```
162
+ */
163
+ declare function logoMark(rows: readonly Row[], o: G2MarkOptions): G2ImageMark;
164
+ /**
165
+ * Team wordmarks as a G2 `image` mark, `size` px tall at their own aspect ratio; as `logoMark` otherwise.
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * import { loadLeague } from "@sportsdataverse/sdvplot";
170
+ * import { drawnMarks, wordmarkMark } from "@sportsdataverse/sdvplot/g2";
171
+ *
172
+ * await loadLeague("nfl");
173
+ * // [team id, x, y, height in px, wordmark URL]: each wordmark 20 px tall, as wide as its own shape
174
+ * drawnMarks(wordmarkMark([{ team: "LV", wins: 4, week: 18 }], { x: "week", y: "wins", team: "team", league: "nfl", size: 20 }));
175
+ * ```
176
+ */
177
+ declare function wordmarkMark(rows: readonly Row[], o: G2MarkOptions): G2ImageMark;
178
+ /**
179
+ * ESPN player headshots as a G2 `image` mark, from the row's `player` field; an id with no headshot draws nothing and
180
+ * warns once. `idSystem: "gsis"` needs `loadGsis()` first.
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * import { headshotMark } from "@sportsdataverse/sdvplot/g2";
185
+ *
186
+ * // Patrick Mahomes (ESPN id 3139477) at his 2024 passing yards and touchdowns, 40 px tall
187
+ * const rows = [{ qb: "3139477", yards: 3928, tds: 26 }];
188
+ * headshotMark(rows, { x: "yards", y: "tds", player: "qb", league: "nfl", size: 40 }).data;
189
+ * ```
190
+ */
191
+ declare function headshotMark(rows: readonly Row[], o: G2HeadshotOptions): G2ImageMark;
192
+ /** `axisLogos` options: the axis' categories are the teams. */
193
+ interface G2AxisOptions {
194
+ /** The league the teams belong to, e.g. "nfl". */
195
+ league: League;
196
+ /** The season the axis' teams are resolved for. */
197
+ season?: SeasonInput;
198
+ /** Image height in px, 1 or more. Default 24. */
199
+ size?: number;
200
+ /** Logo variant, e.g. "dark". Default "default". */
201
+ variant?: Variant;
202
+ /** "logo" (default) or "wordmark". */
203
+ markType?: MarkType;
204
+ /** How the axis categories are read. Default "auto". */
205
+ idSystem?: IdSystem;
206
+ /** url → data URI map from `embedSources`, to inline the images. */
207
+ embed?: ReadonlyMap<string, string>;
208
+ }
209
+ /** What G2 hands an axis' `labelRender`: the subset read here. */
210
+ interface G2AxisDatum {
211
+ /** The tick's label: the category, as the axis' `labelFormatter` shows it. */
212
+ label?: unknown;
213
+ }
214
+ /** Axis options for a G2 band axis whose categories are teams: spread them into `axis.x`. */
215
+ interface G2AxisLabels {
216
+ /** HTML for each label: the team's logo, or the category's own text where it has none. */
217
+ labelRender: (datum: G2AxisDatum) => string;
218
+ /** G2's theme draws labels at 0.45 opacity: a logo is drawn whole. */
219
+ labelOpacity: 1;
220
+ /** No label is hidden or rotated: each logo box is one band wide, so they never overlap. */
221
+ labelAutoHide: false;
222
+ labelAutoRotate: false;
223
+ transform: [];
224
+ }
225
+ /**
226
+ * Team logos as a horizontal band axis' labels (a column chart's `axis.x`), through G2's `labelRender`: each label is
227
+ * HTML, the logo `size` px tall and centred on its tick. Needs `@antv/component` 2.1.12 or later (G2's axis package,
228
+ * an optional peer): 2.1.11 and earlier lay an HTML label out differently, and each logo would sit half a band left. A category with no logo keeps its text and warns once. G2
229
+ * lays an HTML label out one band wide along a horizontal axis only; for a vertical axis (a bar chart's, or under
230
+ * `transpose`) draw a `logoMark` at the axis' position instead. HTML labels are page elements over the chart, not
231
+ * pixels on its canvas: a `toDataURL` export leaves them out.
232
+ *
233
+ * @example
234
+ * ```ts
235
+ * import { loadLeague } from "@sportsdataverse/sdvplot";
236
+ * import { axisLogos } from "@sportsdataverse/sdvplot/g2";
237
+ *
238
+ * await loadLeague("nfl");
239
+ * // { type: "interval", encode: { x: "team", y: "wins" }, axis: { x: { ...<this>, title: false } } }
240
+ * axisLogos({ league: "nfl", size: 28 }).labelRender({ label: "KC" });
241
+ * ```
242
+ */
243
+ declare function axisLogos(o: G2AxisOptions): G2AxisLabels;
244
+ /**
245
+ * Test hook: [id, x, y, height in px, url] per image of every sdvplot mark in `spec`: a mark, a list of them, a G2
246
+ * spec (its `children`, at any depth) or an Ant Design Charts config (its `children` and `annotations`). The height is
247
+ * what the mark's own style hands G2.
248
+ */
249
+ declare function drawnMarks(spec: unknown): DrawnMark[];
250
+
251
+ export { DrawnMark, type G2AxisDatum, type G2AxisLabels, type G2AxisOptions, type G2ColorOptions, type G2ColorScale, type G2HeadshotOptions, type G2ImageDatum, type G2ImageMark, type G2MarkOptions, Row, axisLogos, drawnMarks, headshotMark, logoMark, teamColorPalette, teamColorScale, wordmarkMark };
package/dist/g2.js ADDED
@@ -0,0 +1,102 @@
1
+ import { colorPalette, aspect, imageSource, markPlacements } from './chunk-UL5M6KDE.js';
2
+ export { embedSources } from './chunk-UL5M6KDE.js';
3
+ import { placeSync, placedName, checkAlpha } from './chunk-7ULOCCFL.js';
4
+ import './chunk-ZAEQXFJM.js';
5
+ import './chunk-J6R2LEJ7.js';
6
+ import { InputError } from './chunk-E7G7VSLV.js';
7
+
8
+ // src/g2.ts
9
+ function teamColorPalette(league, teams, o = {}) {
10
+ return colorPalette(league, teams, o);
11
+ }
12
+ function teamColorScale(league, teams, o = {}) {
13
+ const seen = /* @__PURE__ */ new Map();
14
+ for (const t of teams) if (!seen.has(String(t))) seen.set(String(t), t);
15
+ return { type: "ordinal", domain: [...seen.values()], range: colorPalette(league, [...seen.keys()], o) };
16
+ }
17
+ function checkSize(size) {
18
+ if (!(typeof size === "number" && Number.isFinite(size) && size > 0))
19
+ throw new InputError(`size is an image height in px > 0, got ${String(size)}`);
20
+ if (size < 1)
21
+ throw new InputError(
22
+ `size is a height in px, not a fraction of the plot (echarts' \`height\`): got ${size}, which draws a sub-pixel image`
23
+ );
24
+ return size;
25
+ }
26
+ var width = (d) => d.sdv_width;
27
+ var height = (d) => d.sdv_height;
28
+ function imageMark(rows, kind, o) {
29
+ const h = checkSize(o.size ?? 24);
30
+ const opacity = checkAlpha(o.alpha ?? 1);
31
+ const ps = markPlacements(rows, kind, o);
32
+ return {
33
+ type: "image",
34
+ // the whole row, not only x and y: a view's encode (say color: "team") reaches this mark too, and a caller's own
35
+ // style callback on it (opacity by wins, say) reads the row's fields
36
+ data: ps.map((p) => ({
37
+ ...rows[p.index],
38
+ sdv_id: p.id,
39
+ sdv_src: imageSource(p, o.embed),
40
+ sdv_width: h * aspect(p),
41
+ sdv_height: h
42
+ })),
43
+ encode: { x: o.x, y: o.y, src: "sdv_src" },
44
+ style: { width, height, opacity },
45
+ tooltip: false,
46
+ legend: false
47
+ };
48
+ }
49
+ function logoMark(rows, o) {
50
+ return imageMark(rows, "logo", o);
51
+ }
52
+ function wordmarkMark(rows, o) {
53
+ return imageMark(rows, "wordmark", o);
54
+ }
55
+ function headshotMark(rows, o) {
56
+ return imageMark(rows, "headshot", o);
57
+ }
58
+ var escapeHtml = (s) => s.replace(/[&<>"']/g, (c) => `&#${c.charCodeAt(0)};`);
59
+ function axisLogos(o) {
60
+ const h = checkSize(o.size ?? 24);
61
+ const kind = o.markType ?? "logo";
62
+ return {
63
+ labelRender: (datum) => {
64
+ const value = datum.label;
65
+ const p = placeSync([0], [0], [value], {
66
+ league: o.league,
67
+ kind,
68
+ ...o.season === void 0 ? {} : { season: o.season },
69
+ ...o.variant === void 0 ? {} : { variant: o.variant },
70
+ ...o.idSystem === void 0 ? {} : { idSystem: o.idSystem }
71
+ })[0];
72
+ if (p === void 0)
73
+ return `<span style="display:block;width:max-content;transform:translateX(-50%)">${escapeHtml(String(value ?? ""))}</span>`;
74
+ const alt = escapeHtml(`${placedName(p, o.league, value)} ${kind}`);
75
+ const w = h * aspect(p);
76
+ return `<img src="${imageSource(p, o.embed)}" alt="${alt}" data-sdv-id="${escapeHtml(p.id)}" style="display:block;margin-left:${-w / 2}px;width:${w}px;height:${h}px">`;
77
+ },
78
+ labelOpacity: 1,
79
+ labelAutoHide: false,
80
+ labelAutoRotate: false,
81
+ transform: []
82
+ };
83
+ }
84
+ var isImageMark = (v) => typeof v === "object" && v !== null && v.type === "image" && Array.isArray(v.data) && v.encode?.src === "sdv_src";
85
+ function drawnMarks(spec) {
86
+ if (Array.isArray(spec)) return spec.flatMap(drawnMarks);
87
+ if (typeof spec !== "object" || spec === null) return [];
88
+ if (isImageMark(spec))
89
+ return spec.data.map((d) => [
90
+ d.sdv_id,
91
+ d[spec.encode.x],
92
+ d[spec.encode.y],
93
+ spec.style.height(d),
94
+ d.sdv_src
95
+ ]);
96
+ const { children, annotations } = spec;
97
+ return [...drawnMarks(children), ...drawnMarks(annotations)];
98
+ }
99
+
100
+ export { axisLogos, drawnMarks, headshotMark, logoMark, teamColorPalette, teamColorScale, wordmarkMark };
101
+ //# sourceMappingURL=g2.js.map
102
+ //# sourceMappingURL=g2.js.map
package/dist/g2.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/g2.ts"],"names":[],"mappings":"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","file":"g2.js","sourcesContent":["/**\n * The G2 5 adapter, and so Ant Design Charts (`@ant-design/plots`), whose configs are G2 specs underneath: team colours\n * as a `scale.color` (`teamColorScale`) or a list (`teamColorPalette`), logos / wordmarks / headshots as G2 `image`\n * marks (`logoMark`, `wordmarkMark`, `headshotMark`), and logos as a band axis' labels (`axisLogos`). Each returns\n * plain spec pieces: a mark goes in a view's `children` (`chart.options(...)`) or an Ant Design Charts config's\n * `annotations`, a scale in `scale.color`, the axis labels in `axis.x`. Pure: @antv/g2 is never imported (the types\n * are structural, checked against G2 5.4's own). Call after `loadLeague(league)` / `preloadAll()`.\n */\nimport {\n type DrawnMark,\n type Row,\n aspect,\n checkAlpha,\n colorPalette,\n imageSource,\n markPlacements,\n place,\n} from \"./_web.js\";\nimport { InputError } from \"./errors.js\";\nimport type { EspnHeadshotLeague } from \"./headshots.js\";\nimport { type Placement, placedName } from \"./placement.js\";\nimport type { Value } from \"./resolve.js\";\nimport type { HeadshotIdSystem, IdSystem, League, MarkType, SeasonInput, Variant, Which } from \"./types.js\";\nexport type { DrawnMark, Row } from \"./_web.js\";\nexport { embedSources } from \"./_web.js\"; // public: build `embed` with it, as for the other adapters\n\n/** `teamColorPalette` / `teamColorScale` options. */\nexport interface G2ColorOptions {\n /** \"primary\" (default) or \"secondary\" colour. */\n which?: Which;\n /** The season the teams are resolved for (a number or string). */\n season?: SeasonInput;\n /** How the team values are read. Default \"auto\". */\n idSystem?: IdSystem;\n /** The colour of an unresolved team. Default \"#808080\". */\n fallback?: string;\n /**\n * The chart's background. Given, a team colour under 3:1 contrast against it is swapped for the team's other\n * colour, else moved towards white (on a dark background) or black (a light one) until it reads: dark mode. A\n * colour that would then sit too close to an earlier team's (CIE76 ΔE under 20) takes the team's other colour, or\n * the nearest colour to its own that is distinct and still reads; failing that it is kept, with one warning.\n */\n background?: string;\n}\n/**\n * One colour per team, in order, for anything that takes colours by position. With `background`, every colour keeps\n * 3:1 contrast against it (dark mode) and aims to stay distinct from the others. `teamColorScale` puts the same\n * colours on a G2 `scale.color`, keyed by team.\n *\n * @example\n * ```ts\n * import { loadLeague } from \"@sportsdataverse/sdvplot\";\n * import { teamColorPalette } from \"@sportsdataverse/sdvplot/g2\";\n *\n * await loadLeague(\"nfl\");\n * teamColorPalette(\"nfl\", [\"KC\", \"LAC\", \"DEN\", \"LV\"], { background: \"#141414\" });\n * ```\n */\nexport function teamColorPalette(\n league: League,\n teams: readonly unknown[],\n o: G2ColorOptions = {},\n): string[] {\n return colorPalette(league, teams, o);\n}\n\n/** A G2 `scale.color`: an ordinal scale from each team value to its colour. */\nexport interface G2ColorScale<T = unknown> {\n /** Ordinal: a numeric team column (ESPN ids, say) keeps one colour per id, never a gradient. */\n type: \"ordinal\";\n /** The team values exactly as the data holds them (numbers stay numbers), each once and in order. */\n domain: T[];\n /** Their colours, in the same order. */\n range: string[];\n}\n/**\n * Team colours as a G2 `scale.color` (`{ type: \"ordinal\", domain, range }`): the mark's `encode.color` field holds the\n * team values, and each draws in its own colour; the legend lists the teams in this order. With `background` the\n * colours read on it (dark mode). Pass the teams as the data holds them: G2 matches the domain to the data by exact\n * value, so a numeric id stays a number here (12, not \"12\"); a value given twice (also 12 and \"12\") is kept once.\n *\n * @example\n * ```ts\n * import { loadLeague } from \"@sportsdataverse/sdvplot\";\n * import { teamColorScale } from \"@sportsdataverse/sdvplot/g2\";\n *\n * await loadLeague(\"nfl\");\n * // { type: \"interval\", encode: { x: \"team\", y: \"wins\", color: \"team\" }, scale: { color: <this> } }\n * teamColorScale(\"nfl\", [\"KC\", \"LAC\", \"DEN\", \"LV\"]);\n * ```\n */\nexport function teamColorScale<T>(\n league: League,\n teams: readonly T[],\n o: G2ColorOptions = {},\n): G2ColorScale<T> {\n const seen = new Map<string, T>(); // keyed by String(v): the first of 12 and \"12\" wins\n for (const t of teams) if (!seen.has(String(t))) seen.set(String(t), t);\n return { type: \"ordinal\", domain: [...seen.values()], range: colorPalette(league, [...seen.keys()], o) };\n}\n\ninterface Shared {\n /** Image height in px, 1 or more (G2 sizes an image mark in px). Default 24. */\n size?: number;\n /** Opacity in [0, 1]. Default 1. */\n alpha?: number;\n /** url → data URI map from `embedSources`, to inline the images. */\n embed?: ReadonlyMap<string, string>;\n}\n/** `logoMark` / `wordmarkMark` options. */\nexport interface G2MarkOptions extends Shared {\n /** Name of the row field holding each mark's x position (the field the chart's x channel encodes). */\n x: string;\n /** Name of the row field holding each mark's y position. */\n y: string;\n /** Name of the row field holding the team (abbreviation, name or id; see `idSystem`). */\n team: string;\n /** The league the teams belong to, e.g. \"nfl\". */\n league: League;\n /** A season (number or string) for every row, or the name of a row field holding each row's season. */\n season?: SeasonInput;\n /** Logo variant, e.g. \"dark\". Default \"default\". */\n variant?: Variant;\n /** How the `team` values are read. Default \"auto\". */\n idSystem?: IdSystem;\n}\n/** `headshotMark` options. */\nexport interface G2HeadshotOptions extends Shared {\n /** Name of the row field holding each headshot's x position. */\n x: string;\n /** Name of the row field holding each headshot's y position. */\n y: string;\n /** Name of the row field holding the player id. */\n player: string;\n /** The league the players belong to, e.g. \"nfl\". */\n league: EspnHeadshotLeague;\n /** ESPN athlete ids, or nflverse gsis ids (needs `loadGsis()` first). Default \"espn\". */\n idSystem?: HeadshotIdSystem;\n}\n\n/** One datum of an sdvplot image mark: the caller's row and what it draws. */\nexport type G2ImageDatum = Row & {\n /** The resolved team id or player id. */\n sdv_id: string;\n /** The image's URL (or data URI). */\n sdv_src: string;\n /** Its size in px. */\n sdv_width: number;\n sdv_height: number;\n};\n/**\n * A G2 `image` mark (G2 5's `ImageMark`, structurally): one image per drawable row, centred on the row's (x, y) in\n * the view's own scales. Out of the tooltip and the legend.\n */\nexport interface G2ImageMark {\n type: \"image\";\n data: G2ImageDatum[];\n encode: { x: string; y: string; src: \"sdv_src\" };\n style: {\n width: (d: G2ImageDatum) => number;\n height: (d: G2ImageDatum) => number;\n opacity: number;\n };\n tooltip: false;\n legend: false;\n}\n\nfunction checkSize(size: unknown): number {\n if (!(typeof size === \"number\" && Number.isFinite(size) && size > 0))\n throw new InputError(`size is an image height in px > 0, got ${String(size)}`);\n if (size < 1)\n throw new InputError(\n `size is a height in px, not a fraction of the plot (echarts' \\`height\\`): got ${size}, which draws a sub-pixel image`,\n );\n return size;\n}\nconst width = (d: G2ImageDatum): number => d.sdv_width;\nconst height = (d: G2ImageDatum): number => d.sdv_height;\n\nfunction imageMark(\n rows: readonly Row[],\n kind: \"logo\" | \"wordmark\" | \"headshot\",\n o: G2MarkOptions | G2HeadshotOptions,\n): G2ImageMark {\n const h = checkSize(o.size ?? 24);\n const opacity = checkAlpha(o.alpha ?? 1);\n // markPlacements reads the x/y fields only to drop rows with a missing one; G2 reads them itself, by field name\n const ps: Placement[] = markPlacements(rows, kind, o);\n return {\n type: \"image\",\n // the whole row, not only x and y: a view's encode (say color: \"team\") reaches this mark too, and a caller's own\n // style callback on it (opacity by wins, say) reads the row's fields\n data: ps.map((p) => ({\n ...rows[p.index],\n sdv_id: p.id,\n sdv_src: imageSource(p, o.embed),\n sdv_width: h * aspect(p),\n sdv_height: h,\n })),\n encode: { x: o.x, y: o.y, src: \"sdv_src\" },\n style: { width, height, opacity },\n tooltip: false,\n legend: false,\n };\n}\n\n/**\n * Team logos as a G2 `image` mark: one logo per row, `size` px tall, centred on the row's (`x`, `y`) fields in the\n * view's scales. Put it last in a view's `children` (G2: `chart.options({ type: \"view\", children: [..., mark] })`), or\n * in an Ant Design Charts config's `annotations`, which reach G2 as they are. A team with no logo draws nothing and\n * warns once.\n *\n * @example\n * ```ts\n * import { loadLeague } from \"@sportsdataverse/sdvplot\";\n * import { logoMark } from \"@sportsdataverse/sdvplot/g2\";\n *\n * await loadLeague(\"nfl\");\n * const rows = [\n * { team: \"KC\", pf: 385, pa: 326 },\n * { team: \"LAC\", pf: 402, pa: 301 },\n * ];\n * // chart.options({ type: \"view\", data: rows, children: [{ type: \"point\", encode: { x: \"pf\", y: \"pa\" } }, <this>] })\n * logoMark(rows, { x: \"pf\", y: \"pa\", team: \"team\", league: \"nfl\", size: 32 });\n * ```\n */\nexport function logoMark(rows: readonly Row[], o: G2MarkOptions): G2ImageMark {\n return imageMark(rows, \"logo\", o);\n}\n/**\n * Team wordmarks as a G2 `image` mark, `size` px tall at their own aspect ratio; as `logoMark` otherwise.\n *\n * @example\n * ```ts\n * import { loadLeague } from \"@sportsdataverse/sdvplot\";\n * import { drawnMarks, wordmarkMark } from \"@sportsdataverse/sdvplot/g2\";\n *\n * await loadLeague(\"nfl\");\n * // [team id, x, y, height in px, wordmark URL]: each wordmark 20 px tall, as wide as its own shape\n * drawnMarks(wordmarkMark([{ team: \"LV\", wins: 4, week: 18 }], { x: \"week\", y: \"wins\", team: \"team\", league: \"nfl\", size: 20 }));\n * ```\n */\nexport function wordmarkMark(rows: readonly Row[], o: G2MarkOptions): G2ImageMark {\n return imageMark(rows, \"wordmark\", o);\n}\n/**\n * ESPN player headshots as a G2 `image` mark, from the row's `player` field; an id with no headshot draws nothing and\n * warns once. `idSystem: \"gsis\"` needs `loadGsis()` first.\n *\n * @example\n * ```ts\n * import { headshotMark } from \"@sportsdataverse/sdvplot/g2\";\n *\n * // Patrick Mahomes (ESPN id 3139477) at his 2024 passing yards and touchdowns, 40 px tall\n * const rows = [{ qb: \"3139477\", yards: 3928, tds: 26 }];\n * headshotMark(rows, { x: \"yards\", y: \"tds\", player: \"qb\", league: \"nfl\", size: 40 }).data;\n * ```\n */\nexport function headshotMark(rows: readonly Row[], o: G2HeadshotOptions): G2ImageMark {\n return imageMark(rows, \"headshot\", o);\n}\n\n/** `axisLogos` options: the axis' categories are the teams. */\nexport interface G2AxisOptions {\n /** The league the teams belong to, e.g. \"nfl\". */\n league: League;\n /** The season the axis' teams are resolved for. */\n season?: SeasonInput;\n /** Image height in px, 1 or more. Default 24. */\n size?: number;\n /** Logo variant, e.g. \"dark\". Default \"default\". */\n variant?: Variant;\n /** \"logo\" (default) or \"wordmark\". */\n markType?: MarkType;\n /** How the axis categories are read. Default \"auto\". */\n idSystem?: IdSystem;\n /** url → data URI map from `embedSources`, to inline the images. */\n embed?: ReadonlyMap<string, string>;\n}\n/** What G2 hands an axis' `labelRender`: the subset read here. */\nexport interface G2AxisDatum {\n /** The tick's label: the category, as the axis' `labelFormatter` shows it. */\n label?: unknown;\n}\n/** Axis options for a G2 band axis whose categories are teams: spread them into `axis.x`. */\nexport interface G2AxisLabels {\n /** HTML for each label: the team's logo, or the category's own text where it has none. */\n labelRender: (datum: G2AxisDatum) => string;\n /** G2's theme draws labels at 0.45 opacity: a logo is drawn whole. */\n labelOpacity: 1;\n /** No label is hidden or rotated: each logo box is one band wide, so they never overlap. */\n labelAutoHide: false;\n labelAutoRotate: false;\n transform: [];\n}\n\nconst escapeHtml = (s: string): string => s.replace(/[&<>\"']/g, (c) => `&#${c.charCodeAt(0)};`);\n\n/**\n * Team logos as a horizontal band axis' labels (a column chart's `axis.x`), through G2's `labelRender`: each label is\n * HTML, the logo `size` px tall and centred on its tick. Needs `@antv/component` 2.1.12 or later (G2's axis package,\n * an optional peer): 2.1.11 and earlier lay an HTML label out differently, and each logo would sit half a band left. A category with no logo keeps its text and warns once. G2\n * lays an HTML label out one band wide along a horizontal axis only; for a vertical axis (a bar chart's, or under\n * `transpose`) draw a `logoMark` at the axis' position instead. HTML labels are page elements over the chart, not\n * pixels on its canvas: a `toDataURL` export leaves them out.\n *\n * @example\n * ```ts\n * import { loadLeague } from \"@sportsdataverse/sdvplot\";\n * import { axisLogos } from \"@sportsdataverse/sdvplot/g2\";\n *\n * await loadLeague(\"nfl\");\n * // { type: \"interval\", encode: { x: \"team\", y: \"wins\" }, axis: { x: { ...<this>, title: false } } }\n * axisLogos({ league: \"nfl\", size: 28 }).labelRender({ label: \"KC\" });\n * ```\n */\nexport function axisLogos(o: G2AxisOptions): G2AxisLabels {\n const h = checkSize(o.size ?? 24);\n const kind = o.markType ?? \"logo\";\n return {\n labelRender: (datum) => {\n const value = datum.label as Value;\n const p = place([0], [0], [value], {\n league: o.league,\n kind,\n ...(o.season === undefined ? {} : { season: o.season }),\n ...(o.variant === undefined ? {} : { variant: o.variant }),\n ...(o.idSystem === undefined ? {} : { idSystem: o.idSystem }),\n })[0];\n // G2's axis (@antv/component 2.1.12) puts an HTML label's box with its left edge on the tick: each label shifts\n // itself left by half its own width to centre there. (2.1.11 and earlier centred the box: see the guide.)\n if (p === undefined)\n return `<span style=\"display:block;width:max-content;transform:translateX(-50%)\">${escapeHtml(String(value ?? \"\"))}</span>`;\n const alt = escapeHtml(`${placedName(p, o.league, value)} ${kind}`);\n const w = h * aspect(p);\n // G2 reads the label's height from its inline style; imageSource escapes quotes and angle brackets\n return `<img src=\"${imageSource(p, o.embed)}\" alt=\"${alt}\" data-sdv-id=\"${escapeHtml(p.id)}\" style=\"display:block;margin-left:${-w / 2}px;width:${w}px;height:${h}px\">`;\n },\n labelOpacity: 1,\n labelAutoHide: false,\n labelAutoRotate: false,\n transform: [],\n };\n}\n\nconst isImageMark = (v: unknown): v is G2ImageMark =>\n typeof v === \"object\" &&\n v !== null &&\n (v as { type?: unknown }).type === \"image\" &&\n Array.isArray((v as { data?: unknown }).data) &&\n (v as { encode?: { src?: unknown } }).encode?.src === \"sdv_src\";\n/**\n * Test hook: [id, x, y, height in px, url] per image of every sdvplot mark in `spec`: a mark, a list of them, a G2\n * spec (its `children`, at any depth) or an Ant Design Charts config (its `children` and `annotations`). The height is\n * what the mark's own style hands G2.\n */\nexport function drawnMarks(spec: unknown): DrawnMark[] {\n if (Array.isArray(spec)) return spec.flatMap(drawnMarks);\n if (typeof spec !== \"object\" || spec === null) return [];\n if (isImageMark(spec))\n return spec.data.map((d) => [\n d.sdv_id,\n d[spec.encode.x],\n d[spec.encode.y],\n spec.style.height(d),\n d.sdv_src,\n ]);\n const { children, annotations } = spec as { children?: unknown; annotations?: unknown };\n return [...drawnMarks(children), ...drawnMarks(annotations)];\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -3,9 +3,10 @@ export { E as EXPLICIT_ONLY, H as HeadshotIdSystem, d as INDEX_VERSION, I as IdS
3
3
  import { R as ResolveOptions, V as Value } from './resolve-CQW-jzvr.js';
4
4
  export { a as Resolved, r as resolve, b as resolveSync, s as suggest } from './resolve-CQW-jzvr.js';
5
5
  export { C as ColorOptions, a as ColorResult, L as LogoUrlOptions, S as SelectOptions, l as logoUrl, b as logoUrlSync, m as marks, p as palette, s as selectMark, c as selectMarkSync, t as teamColors, d as teamColorsSync } from './marks-DH-tQIP-.js';
6
- export { K as Kind, b as PlaceOptions, P as Placement, c as TIERS_SUBTITLE, d as TIER_DESC, e as TIER_THEMES, a as TierRow, f as Tiers, T as TiersOptions, g as checkAlpha, h as checkHeight, p as place, i as placeSync, j as prepareTiers, w as wrapLabel } from './tiers-B6pUBPcE.js';
6
+ export { K as Kind, a as PlaceOptions, P as Placement, c as checkAlpha, b as checkHeight, p as place, d as placeSync } from './placement-UWkqUzpa.js';
7
7
  export { a as ESPN_HEADSHOT_LEAGUES, E as EspnHeadshotLeague, H as HEADSHOT_ASPECT, h as headshotUrl, l as loadGsis, m as mlbHeadshotUrl, n as nbaHeadshotUrl, b as nhlHeadshotUrl, w as wnbaHeadshotUrl } from './headshots-B2J_LOO8.js';
8
8
  export { C as Cursor, R as RowFilter, b as SelectionPatch, a as SelectionState, S as SelectionStore, c as createSelection, f as focusIds, s as sameCursor, d as sameIds, t as toId } from './selection-D4T3PkRt.js';
9
+ export { b as TIERS_SUBTITLE, c as TIER_DESC, d as TIER_THEMES, a as TierRow, e as Tiers, T as TiersOptions, p as prepareTiers, w as wrapLabel } from './tiers-BN4md-GB.js';
9
10
 
10
11
  declare const MANIFEST_URL = "https://sdv.nyc3.cdn.digitaloceanspaces.com/assets/public/manifest/marks.csv";
11
12
  interface ManifestRow {
package/dist/index.js CHANGED
@@ -1,10 +1,9 @@
1
- export { VERSION, matchupColors, matchupColorsSync, rowsFrom, teams, versions } from './chunk-JJFTD4VB.js';
2
- export { TIERS_SUBTITLE, TIER_DESC, TIER_THEMES, prepareTiers, wrapLabel } from './chunk-NLPH2VZT.js';
1
+ export { VERSION, matchupColors, matchupColorsSync, rowsFrom, teams, versions } from './chunk-J4P4HDBF.js';
2
+ export { TIERS_SUBTITLE, TIER_DESC, TIER_THEMES, prepareTiers, wrapLabel } from './chunk-DYMUVE6K.js';
3
3
  export { createSelection, focusIds, sameCursor, sameIds, toId } from './chunk-4C3GX6QO.js';
4
- export { checkAlpha, checkHeight, place, placeSync } from './chunk-RMT2GMFH.js';
5
- export { MANIFEST_URL, compareMarks, fetchManifest, logoUrl, logoUrlSync, manifestMarks, marks, parseManifestCsv, resetManifestCache, selectMark, selectMarkSync } from './chunk-KKH6ABMA.js';
4
+ export { MANIFEST_URL, checkAlpha, checkHeight, compareMarks, fetchManifest, logoUrl, logoUrlSync, manifestMarks, marks, parseManifestCsv, place, placeSync, resetManifestCache, selectMark, selectMarkSync } from './chunk-7ULOCCFL.js';
5
+ export { ESPN_HEADSHOT_LEAGUES, EXPLICIT_ONLY, HEADSHOT_ASPECT, INDEX_VERSION, LEAGUES, PRIORITY, VARIANTS, headshotUrl, latestSeason, loadGsis, loadLeague, mlbHeadshotUrl, nbaHeadshotUrl, nhlHeadshotUrl, normSeason, normValue, palette, preloadAll, resolve, resolveSync, seasonBounds, suggest, teamColors, teamColorsSync, wnbaHeadshotUrl } from './chunk-ZAEQXFJM.js';
6
6
  export { contrast, hex6, luminance, mix, onColor, solid } from './chunk-J6R2LEJ7.js';
7
- export { ESPN_HEADSHOT_LEAGUES, EXPLICIT_ONLY, HEADSHOT_ASPECT, INDEX_VERSION, LEAGUES, PRIORITY, VARIANTS, headshotUrl, latestSeason, loadGsis, loadLeague, mlbHeadshotUrl, nbaHeadshotUrl, nhlHeadshotUrl, normSeason, normValue, palette, preloadAll, resolve, resolveSync, seasonBounds, suggest, teamColors, teamColorsSync, wnbaHeadshotUrl } from './chunk-TAXO3VXH.js';
8
7
  export { DownloadError, InputError, OfflineError, OptionalDependencyError, SdvplotError, UnresolvedTeamError, UnsupportedTargetError, resetWarnings, setWarningHandler, warn } from './chunk-E7G7VSLV.js';
9
8
  //# sourceMappingURL=index.js.map
10
9
  //# sourceMappingURL=index.js.map