prographs 0.12.0 → 0.13.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 (269) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/README.md +6 -4
  3. package/dist/AutoGraph-PDPEAIXL.cjs +145 -0
  4. package/dist/GraphType.js +19 -0
  5. package/dist/autograph/chartIndex.js +521 -0
  6. package/dist/autograph/chartModules.js +2 -1
  7. package/dist/autograph/index.cjs +98 -93
  8. package/dist/catalog-DI4XZ46L.cjs +142 -0
  9. package/dist/catalog.js +2 -1
  10. package/dist/charts/biologycharts/BiologySamples.js +59 -0
  11. package/dist/charts/biologycharts/PunnettSquare.js +342 -0
  12. package/dist/charts/biologycharts/biologyEnums.js +22 -1
  13. package/dist/charts/biologycharts/index.js +5 -3
  14. package/dist/charts/doecharts/DoeSamples.js +78 -0
  15. package/dist/charts/doecharts/SipocDiagram.js +453 -0
  16. package/dist/charts/doecharts/index.js +4 -2
  17. package/dist/charts/fieldcharts/SpeciesAccumulationCurve.js +350 -0
  18. package/dist/charts/fieldcharts/fieldEnums.js +8 -1
  19. package/dist/charts/fieldcharts/index.js +5 -3
  20. package/dist/charts/signals/AntennaPatternChart.js +492 -0
  21. package/dist/charts/signals/SignalSamples.js +17 -0
  22. package/dist/charts/signals/index.js +5 -3
  23. package/dist/charts/softwarediagrams/ComponentDiagram.js +504 -0
  24. package/dist/charts/softwarediagrams/DeploymentDiagram.js +419 -0
  25. package/dist/charts/softwarediagrams/SoftwareSamples.js +283 -1
  26. package/dist/charts/softwarediagrams/index.js +7 -3
  27. package/dist/charts/softwarediagrams/softwareEnums.js +45 -1
  28. package/dist/charts/sportscharts/PowerDurationCurve.js +301 -0
  29. package/dist/charts/sportscharts/SportsSamples.js +102 -0
  30. package/dist/charts/sportscharts/TrainingLoadChart.js +325 -0
  31. package/dist/charts/sportscharts/index.js +6 -2
  32. package/dist/charts/strategycharts/BassDiffusionChart.js +362 -0
  33. package/dist/charts/strategycharts/BassModel.js +96 -0
  34. package/dist/charts/strategycharts/BurnRunwayChart.js +284 -0
  35. package/dist/charts/strategycharts/CapTableChart.js +366 -0
  36. package/dist/charts/strategycharts/KanbanBoard.js +324 -0
  37. package/dist/charts/strategycharts/OkrTree.js +339 -0
  38. package/dist/charts/strategycharts/StrategyPane.js +27 -0
  39. package/dist/charts/strategycharts/StrategySamples.js +251 -0
  40. package/dist/charts/strategycharts/index.js +15 -3
  41. package/dist/charts/threefields/BsfcMap3DChart.js +231 -0
  42. package/dist/charts/threefields/CompressorMap3DChart.js +217 -0
  43. package/dist/charts/threefields/FieldGrid.js +50 -0
  44. package/dist/charts/threefields/LossLandscape3DChart.js +201 -0
  45. package/dist/charts/threefields/MapSheet.js +77 -0
  46. package/dist/charts/threefields/TerrainRoute3DChart.js +201 -0
  47. package/dist/charts/threefields/TerrainRouteMath.js +40 -0
  48. package/dist/charts/threefields/ThreeFieldBase.js +117 -0
  49. package/dist/charts/threefields/ThreeFieldsSamples.js +80 -0
  50. package/dist/charts/threefields/WaferMap3DChart.js +218 -0
  51. package/dist/charts/threefields/index.js +19 -0
  52. package/dist/charts/threesurfaces/index.js +2 -2
  53. package/dist/charts/tradingcharts/KeltnerChannelChart.js +171 -0
  54. package/dist/charts/tradingcharts/TradingMath.js +20 -0
  55. package/dist/charts/tradingcharts/index.js +4 -2
  56. package/dist/{chunk-ZL6XDXMK.cjs → chunk-26PSLEP4.cjs} +8 -8
  57. package/dist/{chunk-W3US6EFP.cjs → chunk-2BO5DZUP.cjs} +12 -12
  58. package/dist/{chunk-5DP7OUSE.cjs → chunk-2GG5YYSC.cjs} +6 -6
  59. package/dist/{chunk-7FG4JSVO.cjs → chunk-2GL2VNJU.cjs} +253 -33
  60. package/dist/{chunk-LCWMRCLF.cjs → chunk-2PYOI7OY.cjs} +21 -21
  61. package/dist/{chunk-JFWJAEBD.cjs → chunk-3U4MCSKI.cjs} +4 -4
  62. package/dist/{chunk-CUPLHZRR.cjs → chunk-3ZMM3FSK.cjs} +4 -4
  63. package/dist/{chunk-L2AV62DP.cjs → chunk-4767WQJ7.cjs} +6 -6
  64. package/dist/{chunk-DA2EYIIP.cjs → chunk-4E7FSSBF.cjs} +1210 -168
  65. package/dist/{chunk-VS5LQEZB.cjs → chunk-526STI2S.cjs} +5 -5
  66. package/dist/{chunk-RXIMEK6C.cjs → chunk-55767YPI.cjs} +20 -20
  67. package/dist/{chunk-JXLSKIUV.cjs → chunk-5FBQOMMT.cjs} +26 -26
  68. package/dist/{chunk-27PZV5BR.cjs → chunk-5N4Z7MTS.cjs} +4 -4
  69. package/dist/{chunk-KEWCUIQA.cjs → chunk-5WEV6YWA.cjs} +22 -22
  70. package/dist/chunk-5XOVVC5X.cjs +3281 -0
  71. package/dist/{chunk-HK5J7Q2W.cjs → chunk-6HLXVWXU.cjs} +9 -9
  72. package/dist/{chunk-7JG47RW4.cjs → chunk-6LQT4WJ5.cjs} +25 -25
  73. package/dist/{chunk-OCVTI6X4.cjs → chunk-6YTWOUFD.cjs} +329 -36
  74. package/dist/{chunk-W7IQCAVN.cjs → chunk-7F6W6HKL.cjs} +11 -11
  75. package/dist/{chunk-F2DCJXDM.cjs → chunk-7L6KYU5A.cjs} +21 -21
  76. package/dist/{chunk-GTGR6LPR.cjs → chunk-A4GIN4FE.cjs} +17 -17
  77. package/dist/{chunk-B2CETSR6.cjs → chunk-A4US7SA7.cjs} +5 -5
  78. package/dist/{chunk-3DIF2YYW.cjs → chunk-AOXPBLPW.cjs} +10 -10
  79. package/dist/{chunk-7TTR4UF5.cjs → chunk-ATI45Z4M.cjs} +2 -2
  80. package/dist/{chunk-5BFCIX2V.cjs → chunk-CPPMO4IQ.cjs} +434 -148
  81. package/dist/{chunk-AYZZQ6AC.cjs → chunk-CZ5KGF6Q.cjs} +9 -9
  82. package/dist/{chunk-7THJ3ZBK.cjs → chunk-D4I35MCE.cjs} +2 -2
  83. package/dist/{chunk-MCPPFRLN.cjs → chunk-DCGAAN3Z.cjs} +2 -2
  84. package/dist/{chunk-VABL6CVX.cjs → chunk-DEY36N37.cjs} +21 -21
  85. package/dist/{chunk-RNCKGJCC.cjs → chunk-DXHXD3DK.cjs} +3 -3
  86. package/dist/{chunk-A56ZGMVZ.cjs → chunk-E7B45DBZ.cjs} +11 -11
  87. package/dist/{chunk-DOR6L4MT.cjs → chunk-EJC6EAC5.cjs} +18 -18
  88. package/dist/{chunk-UPGNM7MA.cjs → chunk-EULJOOMA.cjs} +11 -11
  89. package/dist/{chunk-G4AZL4GO.cjs → chunk-EYM6LEIF.cjs} +474 -70
  90. package/dist/{chunk-NJ4X6XGV.cjs → chunk-EZTYX2GH.cjs} +5 -5
  91. package/dist/chunk-FDD4UP73.cjs +521 -0
  92. package/dist/{chunk-WJ3VH2Q4.cjs → chunk-GEAIGM3J.cjs} +110 -615
  93. package/dist/{chunk-P3SBHF43.cjs → chunk-GRUYVXTS.cjs} +2 -2
  94. package/dist/{chunk-NX4Z5LMS.cjs → chunk-H3SZXND5.cjs} +5 -5
  95. package/dist/{chunk-EE4S4TOE.cjs → chunk-HS45TOFJ.cjs} +21 -21
  96. package/dist/chunk-INGOG6OV.cjs +899 -0
  97. package/dist/{chunk-UDKA6DGT.cjs → chunk-J3CDXZHF.cjs} +4 -4
  98. package/dist/{chunk-YO6G7TKI.cjs → chunk-JAU5ADEU.cjs} +11 -11
  99. package/dist/{chunk-22LBK4GA.cjs → chunk-JQEBSHX3.cjs} +4 -4
  100. package/dist/{chunk-RXX3U7VQ.cjs → chunk-KLXGLMFU.cjs} +10 -10
  101. package/dist/chunk-KVOX36J3.cjs +327 -0
  102. package/dist/chunk-L6BGNHFL.cjs +139 -0
  103. package/dist/{chunk-GMER35L3.cjs → chunk-L7TB7PU5.cjs} +20 -20
  104. package/dist/{chunk-AFXYNBL2.cjs → chunk-LBTRYEM2.cjs} +4 -4
  105. package/dist/{chunk-WYYCKIOD.cjs → chunk-LLULNJSP.cjs} +11 -11
  106. package/dist/{chunk-J27XOSLP.cjs → chunk-LSO46AFV.cjs} +8 -8
  107. package/dist/{chunk-5XJO45ES.cjs → chunk-LZ2KJ7ZX.cjs} +11 -11
  108. package/dist/chunk-M4IQ5LIZ.cjs +422 -0
  109. package/dist/{chunk-Y2KIUKJF.cjs → chunk-MPDHDKYZ.cjs} +11 -11
  110. package/dist/{chunk-4EMPKRZU.cjs → chunk-MRQ42ZJE.cjs} +3 -3
  111. package/dist/{chunk-EU5D2MF4.cjs → chunk-MYV4KZWP.cjs} +9 -9
  112. package/dist/{chunk-XD7KN4UN.cjs → chunk-MZXVLC24.cjs} +6 -6
  113. package/dist/{chunk-PPSONARU.cjs → chunk-NLBVDFIR.cjs} +41 -2
  114. package/dist/{chunk-L3PEGMGM.cjs → chunk-NY3TBZY4.cjs} +33 -33
  115. package/dist/{chunk-6YNYXXB6.cjs → chunk-OGVVSFAR.cjs} +3 -3
  116. package/dist/{chunk-MLV7QLB6.cjs → chunk-OMTQIQMN.cjs} +6 -6
  117. package/dist/{chunk-BEEOSNK7.cjs → chunk-PEJJ6TXJ.cjs} +15 -144
  118. package/dist/{chunk-SOKOWUF5.cjs → chunk-PPGWHIU7.cjs} +2 -2
  119. package/dist/{chunk-IELWOM2J.cjs → chunk-PPO6SDAN.cjs} +6 -6
  120. package/dist/{chunk-6JTZZCSL.cjs → chunk-PUMKX5F2.cjs} +3 -3
  121. package/dist/{chunk-RFOXFY2U.cjs → chunk-PXBYWCNB.cjs} +190 -799
  122. package/dist/{chunk-3BYXOISI.cjs → chunk-Q3HB3IX6.cjs} +4 -4
  123. package/dist/{chunk-RXCOVONX.cjs → chunk-RBMUOIXE.cjs} +289 -34
  124. package/dist/{chunk-MSBNHCSE.cjs → chunk-RJHGCUUD.cjs} +6 -6
  125. package/dist/{chunk-I6VG7F6Z.cjs → chunk-RSONDMYW.cjs} +708 -141
  126. package/dist/{chunk-GZDNPHMT.cjs → chunk-SHMPFCUE.cjs} +19 -19
  127. package/dist/{chunk-ZIBVCOW6.cjs → chunk-SN4FCXFC.cjs} +19 -19
  128. package/dist/{chunk-7KM52NMN.cjs → chunk-SN5T7WYO.cjs} +2 -2
  129. package/dist/{chunk-7MSZR65Z.cjs → chunk-SQJZGVDR.cjs} +7 -7
  130. package/dist/chunk-SYABFMD7.cjs +633 -0
  131. package/dist/{chunk-2RRFEYFH.cjs → chunk-TICB3MAC.cjs} +16 -16
  132. package/dist/{chunk-AOOKHUV5.cjs → chunk-U7Z7XYR2.cjs} +5 -5
  133. package/dist/{chunk-JEWQAXVG.cjs → chunk-UA2THQFV.cjs} +6 -6
  134. package/dist/{chunk-LHZPAHU3.cjs → chunk-VIK4L2YF.cjs} +112 -521
  135. package/dist/{chunk-4YWMAQ4J.cjs → chunk-VM2Y6BDY.cjs} +4 -4
  136. package/dist/{chunk-IRRKE2ZE.cjs → chunk-VMS3KWYI.cjs} +21 -21
  137. package/dist/{chunk-4SLARW6F.cjs → chunk-VU5NUD46.cjs} +17 -17
  138. package/dist/{chunk-XHY6TVYG.cjs → chunk-VV5CVOF7.cjs} +13 -13
  139. package/dist/{chunk-CCIBPGPZ.cjs → chunk-VYSAWPSS.cjs} +57 -57
  140. package/dist/{chunk-TTNEMQ2A.cjs → chunk-W7YRWEWQ.cjs} +22 -22
  141. package/dist/{chunk-C7MUOGEW.cjs → chunk-X7R5SY62.cjs} +6 -6
  142. package/dist/{chunk-ILR5KBMB.cjs → chunk-XOK3KTSS.cjs} +6 -6
  143. package/dist/{chunk-2CZM2I3T.cjs → chunk-XUIX45VU.cjs} +19 -19
  144. package/dist/{chunk-TGRMPS3A.cjs → chunk-XWH46PVJ.cjs} +165 -43
  145. package/dist/{chunk-WQYXXECR.cjs → chunk-Y5XVMK3K.cjs} +6 -6
  146. package/dist/{chunk-AK4TX2WG.cjs → chunk-YCNKEDTG.cjs} +13 -13
  147. package/dist/{chunk-PJJB24DU.cjs → chunk-YEF7SE3X.cjs} +20 -20
  148. package/dist/{chunk-RVLV4XW6.cjs → chunk-YMTVPMU3.cjs} +22 -22
  149. package/dist/data/index.cjs +2 -2
  150. package/dist/entries/autograph-lazy.cjs +2 -2
  151. package/dist/entries/charts/acoustictransport.cjs +3 -3
  152. package/dist/entries/charts/analysischarts.cjs +3 -3
  153. package/dist/entries/charts/astrocharts.cjs +3 -3
  154. package/dist/entries/charts/bars.cjs +3 -3
  155. package/dist/entries/charts/bayesiancharts.cjs +3 -3
  156. package/dist/entries/charts/biocharts.cjs +3 -3
  157. package/dist/entries/charts/biologycharts.cjs +11 -3
  158. package/dist/entries/charts/biologycharts.d.ts +1 -1
  159. package/dist/entries/charts/biologycharts.js +3 -2
  160. package/dist/entries/charts/business.cjs +3 -3
  161. package/dist/entries/charts/carecharts.cjs +3 -3
  162. package/dist/entries/charts/chemistrycharts.cjs +3 -3
  163. package/dist/entries/charts/civicscharts.cjs +3 -3
  164. package/dist/entries/charts/clinicalcharts.cjs +3 -3
  165. package/dist/entries/charts/comparison.cjs +3 -3
  166. package/dist/entries/charts/demography.cjs +3 -3
  167. package/dist/entries/charts/density.cjs +3 -3
  168. package/dist/entries/charts/diagrams.cjs +3 -3
  169. package/dist/entries/charts/distribution.cjs +3 -3
  170. package/dist/entries/charts/doecharts.cjs +13 -3
  171. package/dist/entries/charts/doecharts.d.ts +1 -1
  172. package/dist/entries/charts/doecharts.js +2 -1
  173. package/dist/entries/charts/earthscience.cjs +3 -3
  174. package/dist/entries/charts/economicscharts.cjs +3 -3
  175. package/dist/entries/charts/energycharts.cjs +3 -3
  176. package/dist/entries/charts/engineering.cjs +3 -3
  177. package/dist/entries/charts/fieldcharts.cjs +7 -3
  178. package/dist/entries/charts/fieldcharts.d.ts +1 -1
  179. package/dist/entries/charts/fieldcharts.js +3 -2
  180. package/dist/entries/charts/financial.cjs +3 -3
  181. package/dist/entries/charts/flow.cjs +3 -3
  182. package/dist/entries/charts/frameworks.cjs +3 -3
  183. package/dist/entries/charts/genomics.cjs +3 -3
  184. package/dist/entries/charts/geoflows.cjs +3 -3
  185. package/dist/entries/charts/geomaps.cjs +3 -3
  186. package/dist/entries/charts/geosciencecharts.cjs +3 -3
  187. package/dist/entries/charts/hierarchy.cjs +3 -3
  188. package/dist/entries/charts/indicators.cjs +3 -3
  189. package/dist/entries/charts/inferencecharts.cjs +3 -3
  190. package/dist/entries/charts/layoutcharts.cjs +3 -3
  191. package/dist/entries/charts/lifescience.cjs +4 -4
  192. package/dist/entries/charts/linesareas.cjs +3 -3
  193. package/dist/entries/charts/logisticscharts.cjs +3 -3
  194. package/dist/entries/charts/machinecharts.cjs +7 -3
  195. package/dist/entries/charts/machinecharts.d.ts +1 -1
  196. package/dist/entries/charts/machinecharts.js +2 -1
  197. package/dist/entries/charts/massive.cjs +3 -3
  198. package/dist/entries/charts/mathematical.cjs +3 -3
  199. package/dist/entries/charts/matrix.cjs +3 -3
  200. package/dist/entries/charts/medicalcharts.cjs +4 -4
  201. package/dist/entries/charts/mlcharts.cjs +4 -4
  202. package/dist/entries/charts/modelcharts.cjs +6 -5
  203. package/dist/entries/charts/multivariate.cjs +3 -3
  204. package/dist/entries/charts/musiccharts.cjs +3 -3
  205. package/dist/entries/charts/network.cjs +3 -3
  206. package/dist/entries/charts/physicscharts.cjs +3 -3
  207. package/dist/entries/charts/pictorial.cjs +4 -4
  208. package/dist/entries/charts/portfoliocharts.cjs +3 -3
  209. package/dist/entries/charts/productcharts.cjs +3 -3
  210. package/dist/entries/charts/proportion.cjs +3 -3
  211. package/dist/entries/charts/qualitycharts.cjs +3 -3
  212. package/dist/entries/charts/radial.cjs +3 -3
  213. package/dist/entries/charts/reliabilitycharts.cjs +5 -3
  214. package/dist/entries/charts/scatter.cjs +3 -3
  215. package/dist/entries/charts/scientific.cjs +3 -3
  216. package/dist/entries/charts/seriescharts.cjs +3 -3
  217. package/dist/entries/charts/signals.cjs +7 -3
  218. package/dist/entries/charts/signals.d.ts +1 -1
  219. package/dist/entries/charts/signals.js +2 -1
  220. package/dist/entries/charts/softwarediagrams.cjs +21 -3
  221. package/dist/entries/charts/softwarediagrams.d.ts +1 -1
  222. package/dist/entries/charts/softwarediagrams.js +4 -2
  223. package/dist/entries/charts/sportscharts.cjs +13 -3
  224. package/dist/entries/charts/sportscharts.d.ts +1 -1
  225. package/dist/entries/charts/sportscharts.js +3 -1
  226. package/dist/entries/charts/statistics.cjs +6 -6
  227. package/dist/entries/charts/strategycharts.cjs +30 -3
  228. package/dist/entries/charts/strategycharts.d.ts +1 -1
  229. package/dist/entries/charts/strategycharts.js +6 -1
  230. package/dist/entries/charts/structure.cjs +3 -3
  231. package/dist/entries/charts/surveycharts.cjs +3 -3
  232. package/dist/entries/charts/systemscharts.cjs +3 -3
  233. package/dist/entries/charts/textcharts.cjs +5 -5
  234. package/dist/entries/charts/thematicmaps.cjs +4 -4
  235. package/dist/entries/charts/threebars.cjs +3 -3
  236. package/dist/entries/charts/threefields.cjs +53 -0
  237. package/dist/entries/charts/threefields.d.ts +1 -0
  238. package/dist/entries/charts/threefields.js +6 -0
  239. package/dist/entries/charts/threeglobe.cjs +3 -3
  240. package/dist/entries/charts/threenetwork.cjs +3 -3
  241. package/dist/entries/charts/threestrata.cjs +3 -3
  242. package/dist/entries/charts/threesurfaces.cjs +7 -3
  243. package/dist/entries/charts/threesurfaces.d.ts +1 -1
  244. package/dist/entries/charts/threesurfaces.js +2 -1
  245. package/dist/entries/charts/threevolume.cjs +4 -4
  246. package/dist/entries/charts/timeline.cjs +3 -3
  247. package/dist/entries/charts/tracecharts.cjs +3 -3
  248. package/dist/entries/charts/trackscharts.cjs +3 -3
  249. package/dist/entries/charts/tradingcharts.cjs +6 -4
  250. package/dist/entries/charts/tradingcharts.d.ts +1 -1
  251. package/dist/entries/charts/tradingcharts.js +2 -1
  252. package/dist/entries/three.cjs +60 -20
  253. package/dist/entries/three.d.ts +1 -1
  254. package/dist/entries/three.js +7 -1
  255. package/dist/index.cjs +258 -97
  256. package/dist/index.d.cts +1953 -10
  257. package/dist/index.d.ts +1953 -10
  258. package/dist/index.js +26 -5
  259. package/dist/page/index.cjs +2 -2
  260. package/dist/react/components.js +58 -1
  261. package/dist/react/index.cjs +135 -92
  262. package/dist/react/index.d.ts +1 -1
  263. package/dist/react/index.js +2 -2
  264. package/package.json +1 -1
  265. package/dist/AutoGraph-XLBJQDRB.cjs +0 -140
  266. package/dist/catalog-O7XGDD2H.cjs +0 -137
  267. package/dist/chunk-77K2HTRC.cjs +0 -3220
  268. package/dist/chunk-XEK47TVD.cjs +0 -323
  269. /package/dist/{chunk-UMEKIIHJ.cjs → chunk-LNWTC72Y.cjs} +0 -0
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12; var _class13; var _class14; var _class15; var _class16; var _class17; var _class18; var _class19;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12; var _class13; var _class14; var _class15; var _class16; var _class17; var _class18; var _class19; var _class20;
2
2
 
3
3
  var _chunk6KYVL5HYcjs = require('./chunk-6KYVL5HY.cjs');
4
4
 
@@ -6,10 +6,14 @@ var _chunk6KYVL5HYcjs = require('./chunk-6KYVL5HY.cjs');
6
6
  var _chunkXX2YTCORcjs = require('./chunk-XX2YTCOR.cjs');
7
7
 
8
8
 
9
+
10
+ var _chunkEEF5WRRZcjs = require('./chunk-EEF5WRRZ.cjs');
11
+
12
+
9
13
  var _chunkPY4R3IFFcjs = require('./chunk-PY4R3IFF.cjs');
10
14
 
11
15
 
12
- var _chunkUMEKIIHJcjs = require('./chunk-UMEKIIHJ.cjs');
16
+ var _chunkLNWTC72Ycjs = require('./chunk-LNWTC72Y.cjs');
13
17
 
14
18
 
15
19
  var _chunkANNBM27Zcjs = require('./chunk-ANNBM27Z.cjs');
@@ -46,7 +50,7 @@ var SignalWavelet = /* @__PURE__ */ ((SignalWavelet2) => {
46
50
  return SignalWavelet2;
47
51
  })(SignalWavelet || {});
48
52
 
49
- // src/charts/signals/AudiogramChart.ts
53
+ // src/charts/signals/AntennaPatternChart.ts
50
54
  var _d3 = require('d3');
51
55
 
52
56
  // src/charts/signals/SignalChart.ts
@@ -532,7 +536,356 @@ var SignalChart = (_class = class extends _chunkXX2YTCORcjs.CartesianChart {cons
532
536
  }
533
537
  }, _class);
534
538
 
539
+ // src/charts/signals/SignalSamples.ts
540
+ var TAU2 = Math.PI * 2;
541
+ var SignalSamples = class {
542
+ /** Zero-mean, unit-variance noise per series, from the steps of a random walk. */
543
+ static noise(seed, samples, channels) {
544
+ const rows = _chunkLNWTC72Ycjs.SampleData.timeSeries(seed, samples + 1, channels), names = [...new Set(rows.map((row) => String(row.series)))];
545
+ return names.map((name) => {
546
+ const walk = rows.filter((row) => row.series === name).map((row) => +row.value);
547
+ const steps = walk.slice(1).map((value, i) => value - walk[i]), mean2 = steps.reduce((sum, step) => sum + step, 0) / steps.length;
548
+ const deviation = Math.sqrt(steps.reduce((sum, step) => sum + (step - mean2) ** 2, 0) / steps.length) || 1;
549
+ return { name, noise: steps.map((step) => (step - mean2) / deviation) };
550
+ });
551
+ }
552
+ static rows(seed, samples, channels, rate, shape) {
553
+ return this.noise(seed, samples, channels).flatMap(({ name, noise }, channel) => {
554
+ const phase = Math.abs(noise[0]) % TAU2;
555
+ return noise.map((step, i) => ({ t: +(i / rate).toFixed(6), series: name, value: +shape(i / rate, channel, step, phase).toFixed(5) }));
556
+ });
557
+ }
558
+ /** Plucked notes with harmonics, in a phrase: the demo for waveforms and spectra. */
559
+ static notes(seed = 1, samples = 2048, channels = 2, rate = 8e3) {
560
+ const duration = samples / rate, starts = [0, 0.22, 0.47, 0.68].map((start) => start * duration);
561
+ return this.rows(seed, samples, channels, rate, (t, channel, noise, phase) => {
562
+ const note = starts.reduce((held, start, i) => t >= start ? i : held, 0), since = t - starts[note];
563
+ const pitch = (220 + 45 * channel) * [1, 1.5, 1.25, 2][note];
564
+ const tone = Math.sin(TAU2 * pitch * t + phase) + 0.5 * Math.sin(TAU2 * 2 * pitch * t) + 0.25 * Math.sin(TAU2 * 3 * pitch * t + phase);
565
+ return (0.82 - channel * 0.22) * Math.exp(-since * 14 / duration * 0.5) * Math.min(1, since * 400) * tone * 0.58 + 2e-3 * noise;
566
+ });
567
+ }
568
+ /** A rising chirp, a steady tone and a click: shows off time-frequency views. */
569
+ static chirp(seed = 1, samples = 4096, channels = 1, rate = 8e3) {
570
+ const duration = samples / rate;
571
+ return this.rows(seed, samples, channels, rate, (t, channel, noise, phase) => {
572
+ const x = t / duration, sweep = 150 * t + 1500 * t * t / (2 * duration);
573
+ const click = Math.exp(-(((x - 0.72) / 4e-3) ** 2)) * Math.sin(TAU2 * 2600 * t);
574
+ return 0.7 * Math.sin(TAU2 * sweep + phase + channel) * Math.sin(Math.PI * x) ** 0.5 + 0.28 * Math.sin(TAU2 * 900 * t) * (x > 0.15 && x < 0.55 ? 1 : 0) + 0.5 * click + 2e-3 * noise;
575
+ });
576
+ }
577
+ /** A pulse train with formant-like harmonics: a voiced sound with a clear pitch. */
578
+ static voiced(seed = 1, samples = 2048, channels = 1, rate = 8e3) {
579
+ const pitch = 142;
580
+ return this.rows(seed, samples, channels, rate, (t, channel, noise, phase) => {
581
+ let sum = 0;
582
+ for (let k = 1; k <= 36; k++) {
583
+ const f = k * pitch * (1 + channel * 0.2);
584
+ if (f < rate / 2) sum += (Math.exp(-(((f - 650) / 420) ** 2)) + 0.45 * Math.exp(-(((f - 1700) / 520) ** 2)) + 0.04) * Math.sin(TAU2 * f * t + phase * k);
585
+ }
586
+ return sum * 0.5 + 0.01 * noise;
587
+ });
588
+ }
589
+ /** Rössler attractor sampled from a noise-chosen start; `value` per series holds x, y and z. */
590
+ static attractor(seed = 1, samples = 1600, channels = 2) {
591
+ const [{ noise }] = this.noise(seed, 8, 1);
592
+ let [x, y, z] = [1 + noise[0] * 0.3, 1 + noise[1] * 0.3, 0.1];
593
+ const dt = 0.03, trail = [];
594
+ const flow = (a, b, c) => [-b - c, a + 0.2 * b, 0.2 + c * (a - 5.7)];
595
+ for (let i = 0; i < samples + 600; i++) {
596
+ const k1 = flow(x, y, z), k2 = flow(x + dt / 2 * k1[0], y + dt / 2 * k1[1], z + dt / 2 * k1[2]);
597
+ const k3 = flow(x + dt / 2 * k2[0], y + dt / 2 * k2[1], z + dt / 2 * k2[2]), k4 = flow(x + dt * k3[0], y + dt * k3[1], z + dt * k3[2]);
598
+ x += dt / 6 * (k1[0] + 2 * k2[0] + 2 * k3[0] + k4[0]);
599
+ y += dt / 6 * (k1[1] + 2 * k2[1] + 2 * k3[1] + k4[1]);
600
+ z += dt / 6 * (k1[2] + 2 * k2[2] + 2 * k3[2] + k4[2]);
601
+ if (i >= 600) trail.push([x, y, z]);
602
+ }
603
+ return ["x", "y", "z"].slice(0, channels).flatMap((series, axis) => trail.map((point, i) => ({ t: +(i * dt).toFixed(3), series, value: +point[axis].toFixed(4) })));
604
+ }
605
+ /**
606
+ * `{ angle, gain, cut }`: gain in dBi every 2 degrees round the E-plane and H-plane of a small array of patch elements, boresight at 0.
607
+ * Each cut is a uniform array factor at half-wave spacing times an element pattern that leaks a little to the rear, with the walk's noise as ripple.
608
+ */
609
+ static antenna(seed = 1) {
610
+ const elements = [5 + seed % 4, 2 + seed % 2], peak = 10 * Math.log10(elements[0] * elements[1] * 3.2);
611
+ return this.noise(seed, 180, 2).flatMap(({ noise }, cut) => noise.map((ripple, i) => {
612
+ const angle = -180 + i * 2, theta = angle * Math.PI / 180, count = elements[cut], phase = Math.PI * Math.sin(theta) / 2;
613
+ const array = Math.abs(Math.sin(phase)) < 1e-9 ? 1 : (Math.sin(count * phase) / (count * Math.sin(phase))) ** 2;
614
+ const element = (0.92 * ((1 + Math.cos(theta)) / 2) ** 1.5 + 0.08) ** 2;
615
+ return { angle, cut: cut ? "H-plane" : "E-plane", gain: +(peak + 10 * Math.log10(array * element + 10 ** -4.5) + 0.12 * ripple).toFixed(2) };
616
+ }));
617
+ }
618
+ };
619
+
620
+ // src/charts/signals/AntennaPatternChart.ts
621
+ var AntennaPatternForm = /* @__PURE__ */ ((AntennaPatternForm2) => {
622
+ AntennaPatternForm2["Polar"] = "polar";
623
+ AntennaPatternForm2["Rectangular"] = "rectangular";
624
+ return AntennaPatternForm2;
625
+ })(AntennaPatternForm || {});
626
+ var RAD = Math.PI / 180;
627
+ var CHAR = 5.7;
628
+ var ROW = 12;
629
+ var DOT = 4;
630
+ var PROMINENCE = 1;
631
+ var HALF_POWER = 3;
632
+ var RING_LABELS_AT = 105;
633
+ var LEAST_PLOT = 190;
634
+ var RIM = 34;
635
+ var wrap = (angle) => ((angle + 180) % 360 + 360) % 360 - 180;
636
+ var degrees = (angle) => `${+wrap(angle).toFixed(1)}\xB0`;
637
+ var AntennaPatternChart = (_class2 = class _AntennaPatternChart extends _chunkEEF5WRRZcjs.Chart2D {
638
+ static __initStatic() {this.meta = {
639
+ id: "signal-antenna-pattern",
640
+ name: "Antenna radiation pattern",
641
+ family: "scientific" /* Scientific */,
642
+ dimension: 2 /* Two */,
643
+ shape: "table" /* Table */,
644
+ description: "Plots antenna gain in dB against angle for one or more cuts, normalised to the peak, on a polar or a rectangular plot, with the main lobe, half-power beamwidth, first side-lobe level and front-to-back ratio marked.",
645
+ tags: ["antenna", "rf", "radiation pattern", "beamwidth", "side lobe", "front-to-back", "e-plane", "h-plane", "polar"],
646
+ sample: (seed) => SignalSamples.antenna(seed),
647
+ variants: {
648
+ form: Object.values(AntennaPatternForm),
649
+ amplitude: Object.values(SignalAmplitude),
650
+ normalize: [true, false],
651
+ metrics: [true, false]
652
+ }
653
+ }}
654
+ defaults() {
655
+ return { x: "angle", y: "gain", series: "cut", form: "polar" /* Polar */, amplitude: "decibel" /* Decibel */, normalize: true, metrics: true, range: 40 };
656
+ }
657
+ plotMargin() {
658
+ return { top: 8, right: 12, bottom: 8, left: 12 };
659
+ }
660
+ /** True when sorted angles go all the way round, leaving no gap wider than their usual step. */
661
+ static closed(angles) {
662
+ const n = angles.length;
663
+ return n > 2 && 360 - (angles[n - 1] - angles[0]) <= 1.5 * (angles[n - 1] - angles[0]) / (n - 1);
664
+ }
665
+ /** Gain at `angle`, read between the two nearest samples and across the seam of a cut that goes all the way round. `null` outside an open cut. */
666
+ static gainAt(angles, gains, angle) {
667
+ const n = Math.min(angles.length, gains.length), after = angles.findIndex((value) => value >= angle), b = after < 0 ? 0 : after, a = (b + n - 1) % n;
668
+ if (!n) return null;
669
+ if (angles[b] === angle) return gains[b];
670
+ if (after <= 0 && !_AntennaPatternChart.closed(angles)) return null;
671
+ const from = angles[a] - (after === 0 ? 360 : 0), to = angles[b] + (after < 0 ? 360 : 0);
672
+ return gains[a] + (gains[b] - gains[a]) * (angle - from) / (to - from || 1);
673
+ }
674
+ /**
675
+ * Peak, half-power points, first side lobe and front-to-back ratio of a cut whose `angles` are sorted, in degrees from -180.
676
+ * Each side is walked out from the peak: to the first sample 3 dB down, then past the first null to the next maximum.
677
+ */
678
+ static metrics(angles, gains) {
679
+ const n = Math.min(angles.length, gains.length), closed = _AntennaPatternChart.closed(angles);
680
+ if (!n) return null;
681
+ let top = 0;
682
+ for (let i = 1; i < n; i++) if (gains[i] > gains[top]) top = i;
683
+ const peak = gains[top], reach = closed ? Math.floor(n / 2) : n - 1;
684
+ const has = (k) => closed || top + k >= 0 && top + k < n, gain = (k) => gains[((top + k) % n + n) % n];
685
+ const angle = (k) => angles[((top + k) % n + n) % n] + 360 * Math.floor((top + k) / n);
686
+ const edge = (side) => {
687
+ for (let k = 1; k <= reach && has(side * k); k++) {
688
+ if (gain(side * k) > peak - HALF_POWER) continue;
689
+ const before = gain(side * (k - 1)), t = (before - (peak - HALF_POWER)) / (before - gain(side * k));
690
+ return angle(side * (k - 1)) + (angle(side * k) - angle(side * (k - 1))) * t;
691
+ }
692
+ return null;
693
+ };
694
+ const lobe = (side) => {
695
+ let low = peak, best = 0;
696
+ for (let k = 1; k <= reach && has(side * k); k++) {
697
+ const here = gain(side * k);
698
+ if (!best) {
699
+ if (here < low) low = here;
700
+ else if (low <= peak - HALF_POWER && here > low + PROMINENCE) best = k;
701
+ } else if (here > gain(side * best)) best = k;
702
+ else if (here < gain(side * best) - PROMINENCE) break;
703
+ }
704
+ return best ? [{ angle: wrap(angle(side * best)), level: gain(side * best) - peak }] : [];
705
+ };
706
+ const left = edge(-1), right = edge(1), behind = wrap(angles[top] + 180), rear = _AntennaPatternChart.gainAt(angles, gains, behind);
707
+ return {
708
+ peak,
709
+ peakAngle: angles[top],
710
+ halfPower: left === null || right === null ? null : [left, right],
711
+ sideLobe: _nullishCoalesce([...lobe(-1), ...lobe(1)].sort((a, b) => b.level - a.level)[0], () => ( null)),
712
+ back: rear === null ? null : { angle: behind, ratio: peak - rear }
713
+ };
714
+ }
715
+ /** One cut per name, in the order the names first appear. */
716
+ get cuts() {
717
+ const { data, x, y, series } = this.options;
718
+ const rows = (Array.isArray(data) ? data : []).flatMap((row) => {
719
+ const cell = row === null || typeof row !== "object" ? null : row[x], turned = typeof cell === "number" || typeof cell === "string" && cell.trim() ? +cell : NaN;
720
+ return Number.isFinite(turned) ? [{ angle: wrap(turned), gain: row[y], cut: _nullishCoalesce(row[series], () => ( "Pattern")) }] : [];
721
+ });
722
+ return SignalParser.channels(rows, "angle", "gain", "cut").flatMap(({ name, t, v }) => {
723
+ const metrics = _AntennaPatternChart.metrics(t, v);
724
+ return metrics ? [{ name, angles: t, gains: v, closed: _AntennaPatternChart.closed(t), metrics }] : [];
725
+ });
726
+ }
727
+ /** Maps gain onto 0 to 1 from the bottom of the scale to its top, with the levels to rule and label. */
728
+ #levels(cuts) {
729
+ const { amplitude, normalize, range } = this.options;
730
+ const peak = cuts.length ? Math.max(...cuts.map((cut) => cut.metrics.peak)) : 0, base = normalize ? peak : 0;
731
+ const clamp = (value) => Math.max(0, Math.min(1, value));
732
+ if (amplitude === "linear" /* Linear */) {
733
+ const scale = _d3.scaleLinear.call(void 0, [0, normalize ? 1 : 10 ** (peak / 10)], [0, 1]);
734
+ if (!normalize) scale.nice(4);
735
+ return { unit: (gain) => clamp(scale(10 ** ((gain - base) / 10))), ticks: scale.ticks(4).map((tick) => ({ at: scale(tick), text: SignalScales.number(tick) })) };
736
+ }
737
+ const span = Math.max(5, Number.isFinite(range) ? range : 40), top = normalize ? 0 : Math.ceil(peak / 10) * 10, step = span <= 20 ? 5 : span <= 60 ? 10 : 20;
738
+ const ticks = Array.from({ length: Math.floor(span / step) + 1 }, (_, i) => ({ at: 1 - i * step / span, text: `${top - i * step}${i ? "" : " dB"}` }));
739
+ return { unit: (gain) => clamp((gain - base - (top - span)) / span), ticks };
740
+ }
741
+ draw(ctx) {
742
+ const cuts = this.cuts, levels = this.#levels(cuts), polar = this.options.form === "polar" /* Polar */, { width, height } = ctx.plot;
743
+ for (const cut of cuts) ctx.palette.color(cut.name);
744
+ const blocks = this.options.metrics ? cuts.map((cut) => [cut.name, ..._AntennaPatternChart.#figures(cut).map(([name, value]) => `${name} ${value}`)]) : [];
745
+ const column = Math.max(0, ...blocks.flat().map((line2) => _chunkEEF5WRRZcjs.TextFit.width(line2, CHAR))) + 16, listed = blocks.length > 0 && width - column >= LEAST_PLOT;
746
+ const wide = listed ? width - column : width, slack = listed && polar ? Math.max(0, wide - 2 * _AntennaPatternChart.#radius(wide, height) - 2 * RIM) : 0;
747
+ const room = { x: slack / 2, y: 0, width: wide - slack, height };
748
+ const frame = polar ? this.#dial(ctx, levels, room) : this.#axes(ctx, levels, cuts, room);
749
+ if (polar) this.#axes(ctx, levels, cuts, room, true);
750
+ else this.#dial(ctx, levels, room, true);
751
+ this.#marks(ctx, cuts, levels, frame);
752
+ let y = 10;
753
+ const lines = (listed ? blocks : []).flatMap((block, i) => {
754
+ if (y + block.length * ROW > height + 4) return [];
755
+ const placed = block.map((text, row) => ({ key: `${i}/${row}`, text, x: room.x + room.width + 14, y: y + row * ROW, anchor: "start", bold: !row, listed: true }));
756
+ y += block.length * ROW + 8;
757
+ return placed;
758
+ });
759
+ this.#write(ctx, "axis-figures", lines);
760
+ }
761
+ /** The largest dial that leaves room for its angle labels. */
762
+ static #radius(width, height) {
763
+ return Math.max(8, Math.min(width / 2 - RIM, height / 2 - 18));
764
+ }
765
+ static #figures({ metrics }) {
766
+ return [
767
+ ["Peak", `${metrics.peak.toFixed(1)} dB at ${degrees(metrics.peakAngle)}`],
768
+ ...metrics.halfPower ? [["HPBW", `${(metrics.halfPower[1] - metrics.halfPower[0]).toFixed(1)}\xB0`]] : [],
769
+ ...metrics.sideLobe ? [["SLL", `${metrics.sideLobe.level.toFixed(1)} dB`]] : [],
770
+ ...metrics.back ? [["F/B", `${metrics.back.ratio.toFixed(1)} dB`]] : []
771
+ ];
772
+ }
773
+ /** Text on a surface halo, so it stays legible over a cut. */
774
+ #write(ctx, name, labels) {
775
+ const { theme } = ctx;
776
+ const written = ctx.marks(name, "text", labels, (d) => d.key).attr("dy", (d) => d.listed ? null : "0.35em").attr("text-anchor", (d) => d.anchor).attr("font-weight", (d) => d.bold ? 600 : 400).attr("paint-order", "stroke").attr("stroke", theme.surface).attr("stroke-width", 3).attr("stroke-linejoin", "round").style("pointer-events", "none").text((d) => d.text);
777
+ ctx.text(written, 10).attr("fill", (d) => d.bold ? theme.ink : d.muted ? theme.inkMuted : theme.inkSecondary);
778
+ ctx.set(written, { x: (d) => d.x, y: (d) => d.y });
779
+ }
780
+ /** Rings, spokes and angle labels of the polar form. `clear` draws none, which removes what the other form left. */
781
+ #dial(ctx, levels, { x: start, width, height }, clear = false) {
782
+ const { theme } = ctx, cx = start + width / 2, cy = height / 2, radius = _AntennaPatternChart.#radius(width, height);
783
+ const turn = radius >= 70 ? 30 : radius >= 36 ? 45 : 90;
784
+ const around = (angle, r) => [cx + r * Math.sin(angle * RAD), cy - r * Math.cos(angle * RAD)];
785
+ const rings = clear ? [] : levels.ticks.filter((tick) => tick.at > 0), spokes = clear ? [] : Array.from({ length: 360 / turn }, (_, i) => -180 + turn + i * turn);
786
+ const circles = ctx.marks("axis-rings", "circle", rings, (d) => d.text).attr("fill", "none").attr("stroke", (d) => d.at === 1 ? theme.axis : theme.grid).attr("stroke-width", 1);
787
+ ctx.set(circles, { cx, cy, r: (d) => radius * d.at });
788
+ const lines = ctx.marks("axis-spokes", "line", spokes, (d) => d).attr("stroke", theme.grid).attr("stroke-width", 1);
789
+ ctx.set(lines, { x1: cx, y1: cy, x2: (d) => around(d, radius)[0], y2: (d) => around(d, radius)[1] });
790
+ const side = (angle) => Math.sin(angle * RAD) > 0.2 ? "start" : Math.sin(angle * RAD) < -0.2 ? "end" : "middle";
791
+ const named = spokes.map((angle) => ({ angle, text: `${angle}\xB0`, anchor: side(angle), at: around(angle, radius + 9) }));
792
+ const angles = ctx.text(ctx.marks("axis-angles", "text", named, (d) => d.angle)).attr("dy", "0.35em").attr("text-anchor", (d) => d.anchor).text((d) => d.text);
793
+ ctx.set(angles, { x: (d) => d.at[0], y: (d) => d.at[1] });
794
+ const gap = rings.length > 1 ? radius * (rings[0].at - rings[1].at) : radius, every = Math.max(1, Math.ceil((Math.max(0, ...rings.map((ring) => _chunkEEF5WRRZcjs.TextFit.width(ring.text, CHAR))) + 5) / gap));
795
+ const scale = ctx.text(ctx.marks("axis-levels", "text", rings.filter((ring, i) => i % every === 0 && radius * ring.at - _chunkEEF5WRRZcjs.TextFit.width(ring.text, CHAR) >= 6), (d) => d.text), 10, "muted").attr("dy", "0.35em").attr("text-anchor", "end").attr("paint-order", "stroke").attr("stroke", theme.surface).attr("stroke-width", 3).attr("stroke-linejoin", "round").text((d) => d.text);
796
+ ctx.set(scale, { x: (d) => around(RING_LABELS_AT, radius * d.at)[0] - 2, y: (d) => around(RING_LABELS_AT, radius * d.at)[1] });
797
+ return {
798
+ round: true,
799
+ point: (angle, level) => around(angle, radius * level),
800
+ tag: (angle, level) => {
801
+ const [x, y] = around(angle, Math.max(radius * level, radius * 0.24) + 11), anchor = side(angle);
802
+ return { x, y: y + (anchor === "middle" ? Math.cos(angle * RAD) > 0 ? -2 : 3 : 0), anchor };
803
+ },
804
+ beam: (edge, level, away) => {
805
+ const reach = Math.max(12, radius * Math.min(level, 0.78)), [x, y] = around(edge + away * 9 / (reach * RAD), reach), from = around(edge, reach)[0];
806
+ return { x, y, anchor: x > from + 1 ? "start" : x < from - 1 ? "end" : "middle" };
807
+ }
808
+ };
809
+ }
810
+ /** Level rules and the angle axis of the rectangular form. `clear` draws none, which removes what the other form left. */
811
+ #axes(ctx, levels, cuts, { x: start, width, height }, clear = false) {
812
+ const { theme } = ctx;
813
+ const left = start + Math.max(24, ...levels.ticks.map((tick) => _chunkEEF5WRRZcjs.TextFit.width(tick.text, 6.2) + 10)), right = start + width - 10, top = 6, bottom = Math.max(top + 10, height - 18);
814
+ const seen = cuts.flatMap((cut) => [cut.angles[0], cut.angles[cut.angles.length - 1]]);
815
+ let [low, high] = !cuts.length || cuts.some((cut) => cut.closed) ? [-180, 180] : [Math.min(...seen), Math.max(...seen)];
816
+ if (low === high) [low, high] = [low - 1, high + 1];
817
+ const x = _d3.scaleLinear.call(void 0, [low, high], [left, Math.max(left + 10, right)]), y = (level) => bottom - level * (bottom - top);
818
+ const step = _nullishCoalesce([30, 45, 60, 90, 180].find((size) => (x(high) - x(low)) * size / (high - low) >= 36), () => ( 360));
819
+ const ticks = clear ? [] : Array.from({ length: Math.floor(high / step) - Math.ceil(low / step) + 1 }, (_, i) => (Math.ceil(low / step) + i) * step);
820
+ const ruled = clear ? [] : levels.ticks;
821
+ const rules = ctx.marks("axis-rules", "line", ruled, (d) => d.text).attr("stroke", theme.grid).attr("stroke-width", 1);
822
+ ctx.set(rules, { x1: left, x2: x(high), y1: (d) => y(d.at), y2: (d) => y(d.at) });
823
+ const base = ctx.marks("axis-base", "line", clear ? [] : [0]).attr("stroke", theme.axis).attr("stroke-width", 1);
824
+ ctx.set(base, { x1: left, x2: x(high), y1: bottom, y2: bottom });
825
+ const levelText = ctx.text(ctx.marks("axis-level-ticks", "text", ruled, (d) => d.text)).attr("dy", "0.32em").attr("text-anchor", "end").text((d) => d.text);
826
+ ctx.set(levelText, { x: left - 6, y: (d) => y(d.at) });
827
+ const angleText = ctx.text(ctx.marks("axis-angle-ticks", "text", ticks, (d) => d)).attr("text-anchor", "middle").text((d) => `${d}\xB0`);
828
+ ctx.set(angleText, { x: (d) => x(d), y: bottom + 14 });
829
+ const across = (angle) => x(Math.max(low, Math.min(high, angle > high || angle < low ? wrap(angle) : angle)));
830
+ return {
831
+ round: false,
832
+ point: (angle, level) => [across(angle), y(level)],
833
+ tag: (angle, level, wide) => ({ x: Math.max(left + wide / 2 + 2, Math.min(x(high) - wide / 2 - 2, across(angle))), y: Math.max(top + 6, y(level) - 12), anchor: "middle" }),
834
+ beam: (edge, level, away) => ({ x: across(edge) + away * 9, y: y(level), anchor: away > 0 ? "start" : "end" })
835
+ };
836
+ }
837
+ #marks(ctx, cuts, levels, frame) {
838
+ const { theme, palette } = ctx;
839
+ const traced = cuts.map((cut) => {
840
+ const edge = !frame.round && cut.closed ? _AntennaPatternChart.gainAt(cut.angles, cut.gains, -180) : null;
841
+ const run = cut.angles.map((angle, i) => [angle, cut.gains[i]]);
842
+ const whole = edge === null ? run : [...run[0][0] > -180 ? [[-180, edge]] : [], ...run, [180, edge]];
843
+ return { cut, points: whole.map(([angle, gain]) => frame.point(angle, levels.unit(gain))) };
844
+ });
845
+ const outline = (points, shut) => points.length ? `M${points.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join("L")}${shut ? "Z" : ""}` : "";
846
+ const lead = this.options.metrics ? cuts[0] : void 0, found = _optionalChain([lead, 'optionalAccess', _9 => _9.metrics]), tint = lead ? palette.color(lead.name) : null;
847
+ const halfPower = levels.unit((_nullishCoalesce(_optionalChain([found, 'optionalAccess', _10 => _10.peak]), () => ( 0))) - HALF_POWER), [from, to] = _nullishCoalesce(_optionalChain([found, 'optionalAccess', _11 => _11.halfPower]), () => ( [0, 0]));
848
+ const guides = !_optionalChain([found, 'optionalAccess', _12 => _12.halfPower]) ? [] : [
849
+ ...frame.round || wrap(from) < wrap(to) ? [{ key: "arc", d: outline(Array.from({ length: 25 }, (_, i) => frame.point(from + (to - from) * i / 24, halfPower)), false) }] : [],
850
+ ...[from, to].map((angle, i) => ({ key: `edge-${i}`, d: outline([frame.point(angle, 0), frame.point(angle, halfPower)], false) }))
851
+ ];
852
+ const beams = ctx.marks("axis-beam", "path", guides, (d) => d.key).attr("fill", "none").attr("stroke", theme.inkMuted).attr("stroke-width", 1).attr("stroke-dasharray", (d) => d.key === "arc" ? null : "3 3");
853
+ ctx.set(beams, { d: (d) => d.d });
854
+ const paths = ctx.marks("cuts", "path", traced.filter((entry) => entry.points.length > 1), (d) => d.cut.name).attr("fill", "none").attr("stroke", (d) => palette.color(d.cut.name)).attr("stroke-width", 2).attr("stroke-linejoin", "round").attr("stroke-linecap", "round");
855
+ ctx.set(paths, { d: (d) => outline(d.points, frame.round && d.cut.closed) });
856
+ ctx.drawOn(paths);
857
+ ctx.hover(paths, (d) => ({ title: d.cut.name, color: palette.color(d.cut.name), rows: _AntennaPatternChart.#figures(d.cut) }));
858
+ const lone = ctx.marks("single", "circle", traced.filter((entry) => entry.points.length === 1 && entry.cut !== lead), (d) => d.cut.name).attr("fill", (d) => palette.color(d.cut.name)).attr("stroke", theme.surface).attr("stroke-width", 2);
859
+ ctx.set(lone, { cx: (d) => d.points[0][0], cy: (d) => d.points[0][1], r: DOT }, { r: 0 });
860
+ ctx.hover(lone, (d) => ({ title: d.cut.name, color: palette.color(d.cut.name), rows: _AntennaPatternChart.#figures(d.cut) }));
861
+ const read = (value) => `${value.toFixed(1)} dB`;
862
+ const spots = !found ? [] : [
863
+ { key: "peak", angle: found.peakAngle, gain: found.peak, name: "Main lobe", text: "", value: `${read(found.peak)} at ${degrees(found.peakAngle)}` },
864
+ ...(_nullishCoalesce(found.halfPower, () => ( []))).map((angle, i) => ({ key: `half-${i}`, angle, gain: found.peak - HALF_POWER, name: "Half power", text: "", value: degrees(angle) })),
865
+ ...found.sideLobe ? [{ key: "side", angle: found.sideLobe.angle, gain: found.peak + found.sideLobe.level, name: "First side lobe", text: "SLL", value: `${read(found.sideLobe.level)} at ${degrees(found.sideLobe.angle)}` }] : [],
866
+ ...found.back ? [{ key: "back", angle: found.back.angle, gain: found.peak - found.back.ratio, name: "Front to back", text: "F/B", value: read(found.back.ratio) }] : []
867
+ ].map((spot) => ({ ...spot, at: frame.point(spot.angle, levels.unit(spot.gain)), tag: frame.tag(spot.angle, levels.unit(spot.gain), _chunkEEF5WRRZcjs.TextFit.width(spot.text, CHAR)) }));
868
+ const dots = ctx.marks("markers", "circle", spots, (d) => d.key).attr("fill", tint).attr("stroke", theme.surface).attr("stroke-width", 2);
869
+ ctx.set(dots, { cx: (d) => d.at[0], cy: (d) => d.at[1], r: (d) => d.key.startsWith("half") ? DOT - 1 : DOT }, { r: 0 }, 30);
870
+ ctx.hover(dots, (d) => ({ title: d.name, color: _nullishCoalesce(tint, () => ( void 0)), rows: [[lead.name, d.value]] }));
871
+ const tagged = spots.filter((spot) => spot.text);
872
+ const leaders = !frame.round ? [] : tagged.flatMap((spot) => {
873
+ const far = Math.hypot(spot.tag.x - spot.at[0], spot.tag.y - spot.at[1]), along = (t) => [spot.at[0] + (spot.tag.x - spot.at[0]) * t, spot.at[1] + (spot.tag.y - spot.at[1]) * t];
874
+ return far > 24 ? [{ key: spot.key, from: along(7 / far), to: along(1 - 10 / far) }] : [];
875
+ });
876
+ const tails = ctx.marks("axis-leaders", "line", leaders, (d) => d.key).attr("stroke", theme.axis).attr("stroke-width", 1);
877
+ ctx.set(tails, { x1: (d) => d.from[0], y1: (d) => d.from[1], x2: (d) => d.to[0], y2: (d) => d.to[1] });
878
+ const sideLobe = _optionalChain([found, 'optionalAccess', _13 => _13.sideLobe]) ? wrap(found.sideLobe.angle - found.peakAngle) : -1;
879
+ this.#write(ctx, "axis-tags", [
880
+ ...tagged.map((spot) => ({ key: spot.key, text: spot.text, ...spot.tag })),
881
+ ..._optionalChain([found, 'optionalAccess', _14 => _14.halfPower]) ? [{ key: "beam", text: "HPBW", ...sideLobe > 0 ? frame.beam(from, halfPower, -1) : frame.beam(to, halfPower, 1) }] : [],
882
+ ...cuts.length ? [] : [{ key: "empty", text: "No pattern", x: 4, y: 12, anchor: "start", muted: true }]
883
+ ]);
884
+ }
885
+ }, _class2.__initStatic(), _class2);
886
+
535
887
  // src/charts/signals/AudiogramChart.ts
888
+
536
889
  var AudiogramLayout = /* @__PURE__ */ ((AudiogramLayout2) => {
537
890
  AudiogramLayout2["Combined"] = "combined";
538
891
  AudiogramLayout2["Separate"] = "separate-ears";
@@ -547,8 +900,8 @@ var FREQUENCIES = [250, 500, 1e3, 2e3, 4e3, 8e3];
547
900
  var ZONES = [[-10, 25, "Normal"], [25, 40, "Mild"], [40, 70, "Moderate"], [70, 90, "Severe"], [90, 120, "Profound"]];
548
901
  var BANANA = [[250, 28, 48], [500, 22, 52], [1e3, 20, 55], [2e3, 22, 58], [4e3, 28, 55], [6e3, 34, 48]];
549
902
  var GUTTER = 22;
550
- var AudiogramChart = (_class2 = class extends SignalChart {
551
- static __initStatic() {this.meta = {
903
+ var AudiogramChart = (_class3 = class extends SignalChart {
904
+ static __initStatic2() {this.meta = {
552
905
  id: "signal-audiogram",
553
906
  name: "Audiogram",
554
907
  family: "scientific" /* Scientific */,
@@ -557,7 +910,7 @@ var AudiogramChart = (_class2 = class extends SignalChart {
557
910
  description: "Plots hearing thresholds per ear against test frequency, with hearing level increasing downward.",
558
911
  tags: ["hearing", "audiometry", "dB HL", "speech banana"],
559
912
  sample: (seed) => {
560
- const rows = _chunkUMEKIIHJcjs.SampleData.categories(seed, 6, 4), slope = [8, 10, 16, 28, 48, 62];
913
+ const rows = _chunkLNWTC72Ycjs.SampleData.categories(seed, 6, 4), slope = [8, 10, 16, 28, 48, 62];
561
914
  return rows.map((row, i) => {
562
915
  const at = Math.floor(i / 4), kind = i % 4, ear = kind % 2 ? "Left" : "Right", bone = kind > 1;
563
916
  const level = slope[at] + (kind % 2 ? 6 : 0) - (bone ? Math.min(slope[at] * 0.4, 18) : 0) + (+row.value - 60) / 80 * 10;
@@ -659,84 +1012,14 @@ var AudiogramChart = (_class2 = class extends SignalChart {
659
1012
  }
660
1013
  connect(ctx, inner, key, list, x, y) {
661
1014
  const ordered = [...list].sort((a, b) => a.freq - b.freq);
662
- if (_optionalChain([ordered, 'access', _9 => _9[0], 'optionalAccess', _10 => _10.bone])) return;
1015
+ if (_optionalChain([ordered, 'access', _15 => _15[0], 'optionalAccess', _16 => _16.bone])) return;
663
1016
  const line2 = this.stroke(inner, `air-${key.replace(/\W/g, "")}`, [ordered], () => key, (items) => this.path(items.map((item) => [item.freq, item.level]), x, y), () => ctx.palette.color(ordered[0].ear), 2);
664
1017
  line2.attr("opacity", 0.9);
665
1018
  }
666
- }, _class2.__initStatic(), _class2);
1019
+ }, _class3.__initStatic2(), _class3);
667
1020
 
668
1021
  // src/charts/signals/CepstrumChart.ts
669
1022
 
670
-
671
- // src/charts/signals/SignalSamples.ts
672
- var TAU2 = Math.PI * 2;
673
- var SignalSamples = class {
674
- /** Zero-mean, unit-variance noise per series, from the steps of a random walk. */
675
- static noise(seed, samples, channels) {
676
- const rows = _chunkUMEKIIHJcjs.SampleData.timeSeries(seed, samples + 1, channels), names = [...new Set(rows.map((row) => String(row.series)))];
677
- return names.map((name) => {
678
- const walk = rows.filter((row) => row.series === name).map((row) => +row.value);
679
- const steps = walk.slice(1).map((value, i) => value - walk[i]), mean2 = steps.reduce((sum, step) => sum + step, 0) / steps.length;
680
- const deviation = Math.sqrt(steps.reduce((sum, step) => sum + (step - mean2) ** 2, 0) / steps.length) || 1;
681
- return { name, noise: steps.map((step) => (step - mean2) / deviation) };
682
- });
683
- }
684
- static rows(seed, samples, channels, rate, shape) {
685
- return this.noise(seed, samples, channels).flatMap(({ name, noise }, channel) => {
686
- const phase = Math.abs(noise[0]) % TAU2;
687
- return noise.map((step, i) => ({ t: +(i / rate).toFixed(6), series: name, value: +shape(i / rate, channel, step, phase).toFixed(5) }));
688
- });
689
- }
690
- /** Plucked notes with harmonics, in a phrase: the demo for waveforms and spectra. */
691
- static notes(seed = 1, samples = 2048, channels = 2, rate = 8e3) {
692
- const duration = samples / rate, starts = [0, 0.22, 0.47, 0.68].map((start) => start * duration);
693
- return this.rows(seed, samples, channels, rate, (t, channel, noise, phase) => {
694
- const note = starts.reduce((held, start, i) => t >= start ? i : held, 0), since = t - starts[note];
695
- const pitch = (220 + 45 * channel) * [1, 1.5, 1.25, 2][note];
696
- const tone = Math.sin(TAU2 * pitch * t + phase) + 0.5 * Math.sin(TAU2 * 2 * pitch * t) + 0.25 * Math.sin(TAU2 * 3 * pitch * t + phase);
697
- return (0.82 - channel * 0.22) * Math.exp(-since * 14 / duration * 0.5) * Math.min(1, since * 400) * tone * 0.58 + 2e-3 * noise;
698
- });
699
- }
700
- /** A rising chirp, a steady tone and a click: shows off time-frequency views. */
701
- static chirp(seed = 1, samples = 4096, channels = 1, rate = 8e3) {
702
- const duration = samples / rate;
703
- return this.rows(seed, samples, channels, rate, (t, channel, noise, phase) => {
704
- const x = t / duration, sweep = 150 * t + 1500 * t * t / (2 * duration);
705
- const click = Math.exp(-(((x - 0.72) / 4e-3) ** 2)) * Math.sin(TAU2 * 2600 * t);
706
- return 0.7 * Math.sin(TAU2 * sweep + phase + channel) * Math.sin(Math.PI * x) ** 0.5 + 0.28 * Math.sin(TAU2 * 900 * t) * (x > 0.15 && x < 0.55 ? 1 : 0) + 0.5 * click + 2e-3 * noise;
707
- });
708
- }
709
- /** A pulse train with formant-like harmonics: a voiced sound with a clear pitch. */
710
- static voiced(seed = 1, samples = 2048, channels = 1, rate = 8e3) {
711
- const pitch = 142;
712
- return this.rows(seed, samples, channels, rate, (t, channel, noise, phase) => {
713
- let sum = 0;
714
- for (let k = 1; k <= 36; k++) {
715
- const f = k * pitch * (1 + channel * 0.2);
716
- if (f < rate / 2) sum += (Math.exp(-(((f - 650) / 420) ** 2)) + 0.45 * Math.exp(-(((f - 1700) / 520) ** 2)) + 0.04) * Math.sin(TAU2 * f * t + phase * k);
717
- }
718
- return sum * 0.5 + 0.01 * noise;
719
- });
720
- }
721
- /** Rössler attractor sampled from a noise-chosen start; `value` per series holds x, y and z. */
722
- static attractor(seed = 1, samples = 1600, channels = 2) {
723
- const [{ noise }] = this.noise(seed, 8, 1);
724
- let [x, y, z] = [1 + noise[0] * 0.3, 1 + noise[1] * 0.3, 0.1];
725
- const dt = 0.03, trail = [];
726
- const flow = (a, b, c) => [-b - c, a + 0.2 * b, 0.2 + c * (a - 5.7)];
727
- for (let i = 0; i < samples + 600; i++) {
728
- const k1 = flow(x, y, z), k2 = flow(x + dt / 2 * k1[0], y + dt / 2 * k1[1], z + dt / 2 * k1[2]);
729
- const k3 = flow(x + dt / 2 * k2[0], y + dt / 2 * k2[1], z + dt / 2 * k2[2]), k4 = flow(x + dt * k3[0], y + dt * k3[1], z + dt * k3[2]);
730
- x += dt / 6 * (k1[0] + 2 * k2[0] + 2 * k3[0] + k4[0]);
731
- y += dt / 6 * (k1[1] + 2 * k2[1] + 2 * k3[1] + k4[1]);
732
- z += dt / 6 * (k1[2] + 2 * k2[2] + 2 * k3[2] + k4[2]);
733
- if (i >= 600) trail.push([x, y, z]);
734
- }
735
- return ["x", "y", "z"].slice(0, channels).flatMap((series, axis) => trail.map((point, i) => ({ t: +(i * dt).toFixed(3), series, value: +point[axis].toFixed(4) })));
736
- }
737
- };
738
-
739
- // src/charts/signals/CepstrumChart.ts
740
1023
  var CepstrumKind = /* @__PURE__ */ ((CepstrumKind2) => {
741
1024
  CepstrumKind2["Real"] = "real";
742
1025
  CepstrumKind2["Power"] = "power";
@@ -753,8 +1036,8 @@ var CepstrumMark = /* @__PURE__ */ ((CepstrumMark2) => {
753
1036
  CepstrumMark2["Stem"] = "stem";
754
1037
  return CepstrumMark2;
755
1038
  })(CepstrumMark || {});
756
- var CepstrumChart = (_class3 = class extends SignalChart {
757
- static __initStatic2() {this.meta = {
1039
+ var CepstrumChart = (_class4 = class extends SignalChart {
1040
+ static __initStatic3() {this.meta = {
758
1041
  id: "signal-cepstrum",
759
1042
  name: "Cepstrum",
760
1043
  family: "scientific" /* Scientific */,
@@ -801,7 +1084,7 @@ var CepstrumChart = (_class3 = class extends SignalChart {
801
1084
  const x = _d3.scaleLog.call(void 0, [low, high], [0, width]);
802
1085
  return { x: SignalScales.labelled(x, SignalScales.sparse(x, low, high), SignalScales.hertz), y };
803
1086
  }
804
- return { x: _d3.scaleLinear.call(void 0, [_optionalChain([points, 'access', _11 => _11[0], 'optionalAccess', _12 => _12.quefrency]) * 1e3 || 0, (_nullishCoalesce(_optionalChain([points, 'access', _13 => _13[points.length - 1], 'optionalAccess', _14 => _14.quefrency]), () => ( 0.02))) * 1e3], [0, width]), y };
1087
+ return { x: _d3.scaleLinear.call(void 0, [_optionalChain([points, 'access', _17 => _17[0], 'optionalAccess', _18 => _18.quefrency]) * 1e3 || 0, (_nullishCoalesce(_optionalChain([points, 'access', _19 => _19[points.length - 1], 'optionalAccess', _20 => _20.quefrency]), () => ( 0.02))) * 1e3], [0, width]), y };
805
1088
  }
806
1089
  plotMarks(ctx, { x, y }) {
807
1090
  const { mark, lifter, pitchRange } = this.options, { width, height } = ctx.plot, base = y(0);
@@ -813,7 +1096,7 @@ var CepstrumChart = (_class3 = class extends SignalChart {
813
1096
  }
814
1097
  this.rule(ctx, "zero", [0], y);
815
1098
  if (mark === "stem" /* Stem */) {
816
- const stride = Math.max(1, Math.ceil((_nullishCoalesce(_optionalChain([traces, 'access', _15 => _15[0], 'optionalAccess', _16 => _16.points, 'access', _17 => _17.length]), () => ( 1))) / (width / 5)));
1099
+ const stride = Math.max(1, Math.ceil((_nullishCoalesce(_optionalChain([traces, 'access', _21 => _21[0], 'optionalAccess', _22 => _22.points, 'access', _23 => _23.length]), () => ( 1))) / (width / 5)));
817
1100
  const strongest = (points) => points.filter((_, i) => i % stride === 0).map((_, n) => points.slice(n * stride, (n + 1) * stride).reduce((best, point) => Math.abs(point.value) > Math.abs(best.value) ? point : best));
818
1101
  const rods = traces.flatMap((trace) => strongest(trace.points).map((point) => ({ point, trace })));
819
1102
  const marks = ctx.marks("rods", "line", rods, (rod) => `${rod.trace.name}${rod.point.key}`).attr("stroke", (rod) => rod.trace.color).attr("stroke-width", 2);
@@ -839,7 +1122,7 @@ var CepstrumChart = (_class3 = class extends SignalChart {
839
1122
  ctx.text(ctx.marks("pitch-text", "text", [0]).attr("x", px + (flip ? -9 : 9)).attr("y", Math.max(11, py + 4)).attr("text-anchor", flip ? "end" : "start").text(`Pitch ${SignalScales.hertz(1 / top.quefrency)} Hz`), 11, "ink");
840
1123
  }
841
1124
  }
842
- }, _class3.__initStatic2(), _class3);
1125
+ }, _class4.__initStatic3(), _class4);
843
1126
 
844
1127
  // src/charts/signals/ECGChart.ts
845
1128
 
@@ -866,8 +1149,8 @@ var LEADS = [["II", 1], ["I", 0.7], ["III", 0.45], ["aVR", -0.8], ["aVL", 0.3],
866
1149
  var WAVES = [[-0.2, 0.024, 0.14], [-0.04, 9e-3, -0.14], [0, 0.011, 1.15], [0.04, 0.011, -0.24], [0.26, 0.05, 0.3]];
867
1150
  var MINOR = 0.04;
868
1151
  var RATE = 200;
869
- var ECGChart = (_class4 = class extends SignalChart {
870
- static __initStatic3() {this.meta = {
1152
+ var ECGChart = (_class5 = class extends SignalChart {
1153
+ static __initStatic4() {this.meta = {
871
1154
  id: "signal-ecg",
872
1155
  name: "ECG",
873
1156
  family: "scientific" /* Scientific */,
@@ -1032,7 +1315,7 @@ var ECGChart = (_class4 = class extends SignalChart {
1032
1315
  ctx.set(dots, { cx: (pair) => x(pair.a), cy: (pair) => y(pair.b), r: 4.5 }, { r: 0 }, 20);
1033
1316
  ctx.hover(dots, (pair) => ({ title: "Successive beats", color, rows: [["RR\u2099", `${Math.round(pair.a)} ms`], ["RR\u2099\u208A\u2081", `${Math.round(pair.b)} ms`]] }));
1034
1317
  }
1035
- }, _class4.__initStatic3(), _class4);
1318
+ }, _class5.__initStatic4(), _class5);
1036
1319
 
1037
1320
  // src/charts/signals/EnvelopeChart.ts
1038
1321
 
@@ -1049,8 +1332,8 @@ var EnvelopeShape = /* @__PURE__ */ ((EnvelopeShape2) => {
1049
1332
  return EnvelopeShape2;
1050
1333
  })(EnvelopeShape || {});
1051
1334
  var FLOOR = -60;
1052
- var EnvelopeChart = (_class5 = class extends SignalChart {
1053
- static __initStatic4() {this.meta = {
1335
+ var EnvelopeChart = (_class6 = class extends SignalChart {
1336
+ static __initStatic5() {this.meta = {
1054
1337
  id: "signal-envelope",
1055
1338
  name: "Signal envelope",
1056
1339
  family: "scientific" /* Scientific */,
@@ -1137,7 +1420,7 @@ var EnvelopeChart = (_class5 = class extends SignalChart {
1137
1420
  const span = marks[1].at - marks[0].at, flip = marks[1].at > ctx.plot.width - 90;
1138
1421
  if (span > 0) ctx.text(ctx.marks("decay-text", "text", [0]).attr("x", marks[1].at + (flip ? -8 : 8)).attr("y", Math.max(12, marks[1].height - 8)).attr("text-anchor", flip ? "end" : "start").text(`\u221220 dB in ${SignalScales.number(t[after] - t[top])} s`), 11, "ink");
1139
1422
  }
1140
- }, _class5.__initStatic4(), _class5);
1423
+ }, _class6.__initStatic5(), _class6);
1141
1424
 
1142
1425
  // src/charts/signals/FilterResponseChart.ts
1143
1426
 
@@ -1205,8 +1488,8 @@ var chebyshev = (order, ripple) => {
1205
1488
  return butterworth(order).map(([re, im]) => [re * Math.sinh(mu), im * Math.cosh(mu)]);
1206
1489
  };
1207
1490
  var BESSEL = [[-0.6573, 0.8302], [-0.6573, -0.8302], [-0.9047, 0.2711], [-0.9047, -0.2711]].map(([re, im]) => [re * 1.2, im * 1.2]);
1208
- var FilterResponseChart = (_class6 = class extends SignalChart {
1209
- static __initStatic5() {this.meta = {
1491
+ var FilterResponseChart = (_class7 = class extends SignalChart {
1492
+ static __initStatic6() {this.meta = {
1210
1493
  id: "signal-filter-response",
1211
1494
  name: "Filter response",
1212
1495
  family: "scientific" /* Scientific */,
@@ -1215,7 +1498,7 @@ var FilterResponseChart = (_class6 = class extends SignalChart {
1215
1498
  description: "Shows the gain, phase and delay of a filter across frequency as a Bode plot, group delay or Nyquist diagram.",
1216
1499
  tags: ["bode", "nyquist", "group delay", "butterworth", "chebyshev"],
1217
1500
  sample: (seed) => {
1218
- const cutoff = 400 + +_chunkUMEKIIHJcjs.SampleData.categories(seed, 1, 1)[0].value * 6;
1501
+ const cutoff = 400 + +_chunkLNWTC72Ycjs.SampleData.categories(seed, 1, 1)[0].value * 6;
1219
1502
  const designs = [["Butterworth", butterworth(4)], ["Chebyshev", chebyshev(4, 1)], ["Bessel", BESSEL]];
1220
1503
  return designs.flatMap(([series, poles]) => {
1221
1504
  const phase = unwrapped(Array.from({ length: SAMPLE_POINTS }, (_, i) => response(poles, 0.02 * 500 ** (i / (SAMPLE_POINTS - 1)))[1]));
@@ -1354,7 +1637,7 @@ var FilterResponseChart = (_class6 = class extends SignalChart {
1354
1637
  }
1355
1638
  /** One stop per plotted frequency of the first sweep, read across every sweep at its nearest frequency, as the probe reads it. */
1356
1639
  keyBins(sweeps, plotted, spot) {
1357
- const shown = _nullishCoalesce(_optionalChain([sweeps, 'access', _18 => _18[0], 'optionalAccess', _19 => _19.freq, 'access', _20 => _20.filter, 'call', _21 => _21(plotted)]), () => ( []));
1640
+ const shown = _nullishCoalesce(_optionalChain([sweeps, 'access', _24 => _24[0], 'optionalAccess', _25 => _25.freq, 'access', _26 => _26.filter, 'call', _27 => _27(plotted)]), () => ( []));
1358
1641
  if (!shown.length) return;
1359
1642
  const nearest = (sweep, freq) => sweep.freq.reduce((best, value, i) => Math.abs(value - freq) < Math.abs(sweep.freq[best] - freq) ? i : best, 0);
1360
1643
  const filled = sweeps.filter((sweep) => sweep.freq.length);
@@ -1368,7 +1651,7 @@ var FilterResponseChart = (_class6 = class extends SignalChart {
1368
1651
  }
1369
1652
  cutoff(ctx, sweeps, x, y) {
1370
1653
  const first = sweeps[0];
1371
- if (!_optionalChain([first, 'optionalAccess', _22 => _22.freq, 'access', _23 => _23.length])) return;
1654
+ if (!_optionalChain([first, 'optionalAccess', _28 => _28.freq, 'access', _29 => _29.length])) return;
1372
1655
  const reference = first.gain[0], hit = first.gain.findIndex((value) => value <= reference - 3);
1373
1656
  if (hit <= 0) return;
1374
1657
  const at = x(first.freq[hit]), bottom = y.range()[0];
@@ -1388,7 +1671,7 @@ var FilterResponseChart = (_class6 = class extends SignalChart {
1388
1671
  this.stroke(ctx, "curve", sweeps, (sweep) => sweep.name, (sweep) => this.path(points(sweep), x, y), (sweep) => ctx.palette.color(sweep.name));
1389
1672
  this.stroke(ctx, "mirror", sweeps, (sweep) => sweep.name, (sweep) => this.path(points(sweep).map(([re, im]) => [re, -im]), x, y), (sweep) => ctx.palette.color(sweep.name), 1).attr("stroke-dasharray", "3 3");
1390
1673
  }
1391
- }, _class6.__initStatic5(), _class6);
1674
+ }, _class7.__initStatic6(), _class7);
1392
1675
 
1393
1676
  // src/charts/signals/ImpulseResponseChart.ts
1394
1677
 
@@ -1406,8 +1689,8 @@ var ImpulseMark = /* @__PURE__ */ ((ImpulseMark2) => {
1406
1689
  })(ImpulseMark || {});
1407
1690
  var FLOOR2 = -70;
1408
1691
  var STEMS = 48;
1409
- var ImpulseResponseChart = (_class7 = class extends SignalChart {
1410
- static __initStatic6() {this.meta = {
1692
+ var ImpulseResponseChart = (_class8 = class extends SignalChart {
1693
+ static __initStatic7() {this.meta = {
1411
1694
  id: "signal-impulse-response",
1412
1695
  name: "Impulse response",
1413
1696
  family: "scientific" /* Scientific */,
@@ -1521,7 +1804,7 @@ var ImpulseResponseChart = (_class7 = class extends SignalChart {
1521
1804
  ctx.set(dot, { cx: px, cy: py, r: 4 }, { r: 0 });
1522
1805
  ctx.text(ctx.marks("note-text", "text", [0]).attr("x", px + (flip ? -9 : 9)).attr("y", Math.max(11, Math.min(height - 5, py - 7))).attr("text-anchor", flip ? "end" : "start").text(label), 11, "ink");
1523
1806
  }
1524
- }, _class7.__initStatic6(), _class7);
1807
+ }, _class8.__initStatic7(), _class8);
1525
1808
 
1526
1809
  // src/charts/signals/LogicAnalyzerChart.ts
1527
1810
 
@@ -1538,8 +1821,8 @@ var LogicEdge = /* @__PURE__ */ ((LogicEdge2) => {
1538
1821
  })(LogicEdge || {});
1539
1822
  var BUS = "Bus";
1540
1823
  var SAMPLE_BITS = ["CLK", "D0", "D1", "D2", "D3"];
1541
- var LogicAnalyzerChart = (_class8 = class extends SignalChart {
1542
- static __initStatic7() {this.meta = {
1824
+ var LogicAnalyzerChart = (_class9 = class extends SignalChart {
1825
+ static __initStatic8() {this.meta = {
1543
1826
  id: "signal-logic-analyzer",
1544
1827
  name: "Logic analyzer",
1545
1828
  family: "scientific" /* Scientific */,
@@ -1584,7 +1867,7 @@ var LogicAnalyzerChart = (_class8 = class extends SignalChart {
1584
1867
  times.forEach((start, i) => {
1585
1868
  const value = lines.reduce((sum, channel, bit) => {
1586
1869
  const run = this.runs(channel).find((item) => start >= item.start && start < item.end);
1587
- return sum + (_nullishCoalesce(_optionalChain([run, 'optionalAccess', _24 => _24.level]), () => ( 0))) * 2 ** bit;
1870
+ return sum + (_nullishCoalesce(_optionalChain([run, 'optionalAccess', _30 => _30.level]), () => ( 0))) * 2 ** bit;
1588
1871
  }, 0);
1589
1872
  words.push({ key: `w${i}`, start, end: _nullishCoalesce(times[i + 1], () => ( this.span[1])), value });
1590
1873
  });
@@ -1614,7 +1897,7 @@ var LogicAnalyzerChart = (_class8 = class extends SignalChart {
1614
1897
  if (display !== "bus" /* Bus */) this.placeSample = (channel, i) => [x(channel.t[i]), (_nullishCoalesce(y(channel.name), () => ( 0))) + (channel.v[i] > this.options.threshold ? 0 : thick)];
1615
1898
  this.probe(ctx, (px) => {
1616
1899
  const time = x.invert(px);
1617
- const rows = this.channels.map((channel) => [channel.name, _nullishCoalesce(_optionalChain([this, 'access', _25 => _25.runs, 'call', _26 => _26(channel), 'access', _27 => _27.find, 'call', _28 => _28((run) => time >= run.start && time < run.end), 'optionalAccess', _29 => _29.level]), () => ( 0))]);
1900
+ const rows = this.channels.map((channel) => [channel.name, _nullishCoalesce(_optionalChain([this, 'access', _31 => _31.runs, 'call', _32 => _32(channel), 'access', _33 => _33.find, 'call', _34 => _34((run) => time >= run.start && time < run.end), 'optionalAccess', _35 => _35.level]), () => ( 0))]);
1618
1901
  return { x: px, tip: { title: `${SignalScales.number(time)}`, rows }, datum: { t: time } };
1619
1902
  });
1620
1903
  }
@@ -1634,7 +1917,7 @@ var LogicAnalyzerChart = (_class8 = class extends SignalChart {
1634
1917
  const named = words.filter((word) => x(word.end) - x(word.start) > 15);
1635
1918
  ctx.marks("bus-text", "text", named, (word) => word.key).attr("x", (word) => (x(word.start) + x(word.end)) / 2).attr("y", middle + 4).attr("text-anchor", "middle").attr("font-size", 11).attr("font-family", ctx.theme.fontFamily).attr("fill", ctx.palette.inkOn(color)).text((word) => word.value.toString(16).toUpperCase());
1636
1919
  }
1637
- }, _class8.__initStatic7(), _class8);
1920
+ }, _class9.__initStatic8(), _class9);
1638
1921
 
1639
1922
  // src/charts/signals/OscilloscopeChart.ts
1640
1923
 
@@ -1668,8 +1951,8 @@ var ceilStep = (value) => {
1668
1951
  return (_nullishCoalesce([1, 2, 5, 10].find((step) => step >= unit - 1e-9), () => ( 10))) * power;
1669
1952
  };
1670
1953
  var seconds = (value) => value >= 1 ? `${+value.toFixed(2)} s` : value >= 1e-3 ? `${+(value * 1e3).toFixed(2)} ms` : `${+(value * 1e6).toFixed(1)} \xB5s`;
1671
- var OscilloscopeChart = (_class9 = class extends SignalChart {
1672
- static __initStatic8() {this.meta = {
1954
+ var OscilloscopeChart = (_class10 = class extends SignalChart {
1955
+ static __initStatic9() {this.meta = {
1673
1956
  id: "signal-oscilloscope",
1674
1957
  name: "Oscilloscope",
1675
1958
  family: "scientific" /* Scientific */,
@@ -1797,7 +2080,7 @@ var OscilloscopeChart = (_class9 = class extends SignalChart {
1797
2080
  envelope(ctx, sweeps, x, y) {
1798
2081
  const names = [...new Set(sweeps.map((sweep) => sweep.name))];
1799
2082
  const bands = names.map((name) => {
1800
- const mine = sweeps.filter((sweep) => sweep.name === name), reference = _nullishCoalesce(_optionalChain([mine, 'access', _30 => _30[0], 'optionalAccess', _31 => _31.points]), () => ( []));
2083
+ const mine = sweeps.filter((sweep) => sweep.name === name), reference = _nullishCoalesce(_optionalChain([mine, 'access', _36 => _36[0], 'optionalAccess', _37 => _37.points]), () => ( []));
1801
2084
  const rows = reference.map(([at]) => {
1802
2085
  const values = mine.map((sweep) => SignalDsp.interpolate(sweep.points.map((point) => point[0]), sweep.points.map((point) => point[1]), at));
1803
2086
  return { at, low: _d3.min.call(void 0, values), high: _d3.max.call(void 0, values) };
@@ -1816,7 +2099,7 @@ var OscilloscopeChart = (_class9 = class extends SignalChart {
1816
2099
  const points = Array.from({ length: span }, (_, i) => [ax[i], ay[i]]);
1817
2100
  this.stroke(ctx, "figure", [points], () => 0, (list) => this.path(list, x, y), () => ctx.palette.color(a.name), this.options.display === "persistence" /* Persistence */ ? 1 : 2);
1818
2101
  }
1819
- }, _class9.__initStatic8(), _class9);
2102
+ }, _class10.__initStatic9(), _class10);
1820
2103
 
1821
2104
  // src/charts/signals/PeriodogramChart.ts
1822
2105
 
@@ -1851,8 +2134,8 @@ var PeriodogramAbscissa = /* @__PURE__ */ ((PeriodogramAbscissa2) => {
1851
2134
  })(PeriodogramAbscissa || {});
1852
2135
  var chiSquared = (dof, z) => dof * (1 - 2 / (9 * dof) + z * Math.sqrt(2 / (9 * dof))) ** 3;
1853
2136
  var CAP = 512;
1854
- var PeriodogramChart = (_class10 = class extends SpectralChart {
1855
- static __initStatic9() {this.meta = {
2137
+ var PeriodogramChart = (_class11 = class extends SpectralChart {
2138
+ static __initStatic10() {this.meta = {
1856
2139
  id: "signal-periodogram",
1857
2140
  name: "Periodogram",
1858
2141
  family: "scientific" /* Scientific */,
@@ -1936,7 +2219,7 @@ var PeriodogramChart = (_class10 = class extends SpectralChart {
1936
2219
  this.stroke(ctx, "trace", estimates, (estimate) => estimate.name, (estimate) => this.path(points(estimate).map((point) => [point.value, Math.max(floor, Math.min(top, point.level))]), x, y), (estimate) => estimate.color, 1.5);
1937
2220
  this.probe(ctx, (px) => {
1938
2221
  const at = x.invert(px), first = estimates[0];
1939
- if (!_optionalChain([first, 'optionalAccess', _32 => _32.x, 'access', _33 => _33.length])) return null;
2222
+ if (!_optionalChain([first, 'optionalAccess', _38 => _38.x, 'access', _39 => _39.length])) return null;
1940
2223
  const nearest = first.x.reduce((best, value, i) => Math.abs(value - at) < Math.abs(first.x[best] - at) ? i : best, 0);
1941
2224
  return { x: x(first.x[nearest]), tip: { title: SignalScales.number(first.x[nearest]), rows: estimates.map((estimate) => [estimate.name, SignalScales.number(this.level(estimate.power[nearest]))]) }, datum: { x: first.x[nearest] } };
1942
2225
  });
@@ -1954,7 +2237,7 @@ var PeriodogramChart = (_class10 = class extends SpectralChart {
1954
2237
  return { title: period ? `${+(value * 1e3).toPrecision(3)} ms` : `${SignalScales.hertz(value)} Hz`, rows: all.map((estimate) => [estimate.name, SignalScales.number(this.level(estimate.power[at]))]) };
1955
2238
  }, (bin) => all.map((estimate) => [x(first.x[order[bin]]), clamp(this.level(estimate.power[order[bin]]))]));
1956
2239
  }
1957
- }, _class10.__initStatic9(), _class10);
2240
+ }, _class11.__initStatic10(), _class11);
1958
2241
 
1959
2242
  // src/charts/signals/PhaseSpace3DChart.ts
1960
2243
 
@@ -1990,8 +2273,8 @@ var Phase3DStyle = /* @__PURE__ */ ((Phase3DStyle2) => {
1990
2273
  })(Phase3DStyle || {});
1991
2274
  var MAX_STEPS = 900;
1992
2275
  var FLOOR3 = -0.82;
1993
- var PhaseSpace3DChart = (_class11 = class extends _chunk6KYVL5HYcjs.Chart3D {
1994
- static __initStatic10() {this.meta = {
2276
+ var PhaseSpace3DChart = (_class12 = class extends _chunk6KYVL5HYcjs.Chart3D {
2277
+ static __initStatic11() {this.meta = {
1995
2278
  id: "signal-phase-space-3d",
1996
2279
  name: "3D phase space",
1997
2280
  family: "scientific" /* Scientific */,
@@ -2094,7 +2377,7 @@ var PhaseSpace3DChart = (_class11 = class extends _chunk6KYVL5HYcjs.Chart3D {
2094
2377
  holder.rotation.y = Math.sin(seconds2 * 0.2) * 0.06;
2095
2378
  });
2096
2379
  }
2097
- }, _class11.__initStatic10(), _class11);
2380
+ }, _class12.__initStatic11(), _class12);
2098
2381
 
2099
2382
  // src/charts/signals/PhaseSpaceChart.ts
2100
2383
  var _d3hexbin = require('d3-hexbin');
@@ -2113,8 +2396,8 @@ var PhaseMark = /* @__PURE__ */ ((PhaseMark2) => {
2113
2396
  })(PhaseMark || {});
2114
2397
  var SEGMENTS = 24;
2115
2398
  var POINTS = 180;
2116
- var PhaseSpaceChart = (_class12 = class extends SignalChart {
2117
- static __initStatic11() {this.meta = {
2399
+ var PhaseSpaceChart = (_class13 = class extends SignalChart {
2400
+ static __initStatic12() {this.meta = {
2118
2401
  id: "signal-phase-space",
2119
2402
  name: "Phase space plot",
2120
2403
  family: "scientific" /* Scientific */,
@@ -2143,7 +2426,7 @@ var PhaseSpaceChart = (_class12 = class extends SignalChart {
2143
2426
  return false;
2144
2427
  }
2145
2428
  get points() {
2146
- const { coordinates, delay } = this.options, { v, rate } = this.first, b = _optionalChain([this, 'access', _34 => _34.channels, 'access', _35 => _35[1], 'optionalAccess', _36 => _36.v]);
2429
+ const { coordinates, delay } = this.options, { v, rate } = this.first, b = _optionalChain([this, 'access', _40 => _40.channels, 'access', _41 => _41[1], 'optionalAccess', _42 => _42.v]);
2147
2430
  if (coordinates === "channels" /* Channels */ && b) return v.slice(0, b.length).map((value, i) => [value, b[i]]);
2148
2431
  if (coordinates === "derivative" /* Derivative */) return v.slice(1, -1).map((value, i) => [value, (v[i + 2] - v[i]) * rate / 2]);
2149
2432
  return v.slice(0, Math.max(0, v.length - delay)).map((value, i) => [value, v[i + delay]]);
@@ -2190,7 +2473,7 @@ var PhaseSpaceChart = (_class12 = class extends SignalChart {
2190
2473
  ctx.set(dots, { cx: x(at), cy: (hit) => y(hit.y), r: 4 }, { r: 0 }, 8);
2191
2474
  ctx.hover(dots, (hit) => ({ title: "Section crossing", rows: [["y", SignalScales.number(hit.y)]] }));
2192
2475
  }
2193
- }, _class12.__initStatic11(), _class12);
2476
+ }, _class13.__initStatic12(), _class13);
2194
2477
 
2195
2478
  // src/charts/signals/SeismogramChart.ts
2196
2479
 
@@ -2215,8 +2498,8 @@ var P = 7.6;
2215
2498
  var S = 4.3;
2216
2499
  var RATE2 = 20;
2217
2500
  var DURATION = 100;
2218
- var SeismogramChart = (_class13 = class extends SignalChart {
2219
- static __initStatic12() {this.meta = {
2501
+ var SeismogramChart = (_class14 = class extends SignalChart {
2502
+ static __initStatic13() {this.meta = {
2220
2503
  id: "signal-seismogram",
2221
2504
  name: "Seismogram",
2222
2505
  family: "scientific" /* Scientific */,
@@ -2356,7 +2639,7 @@ var SeismogramChart = (_class13 = class extends SignalChart {
2356
2639
  return { x: px, tip: { title: trace.label, rows: [["Time", `${SignalScales.number(time)} s`], ["Amplitude", SignalScales.number(SignalDsp.interpolate(trace.channel.t, trace.channel.v, time))]] }, datum: { station: trace.label, t: time } };
2357
2640
  });
2358
2641
  }
2359
- }, _class13.__initStatic12(), _class13);
2642
+ }, _class14.__initStatic13(), _class14);
2360
2643
 
2361
2644
  // src/charts/signals/SpectrumChart.ts
2362
2645
 
@@ -2366,8 +2649,8 @@ var SpectrumMark = /* @__PURE__ */ ((SpectrumMark2) => {
2366
2649
  SpectrumMark2["Bands"] = "third-octave-bands";
2367
2650
  return SpectrumMark2;
2368
2651
  })(SpectrumMark || {});
2369
- var SpectrumChart = (_class14 = class extends SpectralChart {
2370
- static __initStatic13() {this.meta = {
2652
+ var SpectrumChart = (_class15 = class extends SpectralChart {
2653
+ static __initStatic14() {this.meta = {
2371
2654
  id: "signal-spectrum",
2372
2655
  name: "Frequency spectrum",
2373
2656
  family: "scientific" /* Scientific */,
@@ -2400,7 +2683,7 @@ var SpectrumChart = (_class14 = class extends SpectralChart {
2400
2683
  }
2401
2684
  scales(ctx) {
2402
2685
  const traces = this.traces(ctx), { width, height } = ctx.plot;
2403
- const x = this.frequencyAxis(_nullishCoalesce(_optionalChain([traces, 'access', _37 => _37.find, 'call', _38 => _38((trace) => trace.spectrum.freq.length), 'optionalAccess', _39 => _39.spectrum, 'access', _40 => _40.freq]), () => ( [])), width);
2686
+ const x = this.frequencyAxis(_nullishCoalesce(_optionalChain([traces, 'access', _43 => _43.find, 'call', _44 => _44((trace) => trace.spectrum.freq.length), 'optionalAccess', _45 => _45.spectrum, 'access', _46 => _46.freq]), () => ( [])), width);
2404
2687
  const banded = this.options.mark === "third-octave-bands" /* Bands */ ? _d3.max.call(void 0, this.bands(traces, x.domain()[1]), (band) => band.level) : void 0;
2405
2688
  const top = _nullishCoalesce(_nullishCoalesce(banded, () => ( _d3.max.call(void 0, traces, (trace) => _d3.max.call(void 0, trace.level)))), () => ( 1));
2406
2689
  return { x, y: _d3.scaleLinear.call(void 0, this.decibel ? [this.options.floor, Math.max(top, this.options.floor + 10)] : [0, top || 1], [height, 0]).nice(5) };
@@ -2439,23 +2722,23 @@ var SpectrumChart = (_class14 = class extends SpectralChart {
2439
2722
  const reading = (freq) => ({ title: `${SignalScales.hertz(freq)} Hz`, rows: traces.map((trace) => [trace.name, SignalScales.number(SignalDsp.interpolate(trace.spectrum.freq, trace.level, freq))]) });
2440
2723
  this.probe(ctx, (px) => {
2441
2724
  const freq = x.invert(px), first = traces[0];
2442
- if (!_optionalChain([first, 'optionalAccess', _41 => _41.spectrum, 'access', _42 => _42.freq, 'access', _43 => _43.length])) return null;
2725
+ if (!_optionalChain([first, 'optionalAccess', _47 => _47.spectrum, 'access', _48 => _48.freq, 'access', _49 => _49.length])) return null;
2443
2726
  return { x: px, tip: reading(freq), datum: { frequency: freq } };
2444
2727
  });
2445
- const shown = _nullishCoalesce(_optionalChain([traces, 'access', _44 => _44[0], 'optionalAccess', _45 => _45.spectrum, 'access', _46 => _46.freq, 'access', _47 => _47.filter, 'call', _48 => _48((freq) => freq >= x.domain()[0])]), () => ( []));
2728
+ const shown = _nullishCoalesce(_optionalChain([traces, 'access', _50 => _50[0], 'optionalAccess', _51 => _51.spectrum, 'access', _52 => _52.freq, 'access', _53 => _53.filter, 'call', _54 => _54((freq) => freq >= x.domain()[0])]), () => ( []));
2446
2729
  if (shown.length) this.bins = SignalBins.line(shown.length, (bin) => reading(shown[bin]), (bin) => traces.map((trace) => [x(shown[bin]), y(SignalDsp.interpolate(trace.spectrum.freq, trace.level, shown[bin]))]));
2447
2730
  }
2448
2731
  /** Labels the strongest peak of the first channel. */
2449
2732
  mark(ctx, traces, x, y) {
2450
2733
  const trace = traces[0];
2451
- if (!_optionalChain([trace, 'optionalAccess', _49 => _49.level, 'access', _50 => _50.length])) return;
2734
+ if (!_optionalChain([trace, 'optionalAccess', _55 => _55.level, 'access', _56 => _56.length])) return;
2452
2735
  const index = trace.level.indexOf(Math.max(...trace.level)), freq = trace.spectrum.freq[index], px = x(freq), py = y(trace.level[index]);
2453
2736
  const dots = ctx.marks("peak", "circle", [0]).attr("fill", trace.color).attr("stroke", ctx.theme.surface).attr("stroke-width", 2);
2454
2737
  ctx.set(dots, { cx: px, cy: py, r: 4 }, { r: 0 });
2455
2738
  const flip = px > ctx.plot.width - 70;
2456
2739
  ctx.text(ctx.marks("peak-label", "text", [0]).attr("x", px + (flip ? -8 : 8)).attr("y", Math.max(11, py + 3)).attr("text-anchor", flip ? "end" : "start").text(`${SignalScales.hertz(freq)} Hz`), 11, "ink");
2457
2740
  }
2458
- }, _class14.__initStatic13(), _class14);
2741
+ }, _class15.__initStatic14(), _class15);
2459
2742
 
2460
2743
  // src/charts/signals/StemSignalChart.ts
2461
2744
 
@@ -2466,8 +2749,8 @@ var StemReconstruction = /* @__PURE__ */ ((StemReconstruction2) => {
2466
2749
  return StemReconstruction2;
2467
2750
  })(StemReconstruction || {});
2468
2751
  var sinc = (x) => Math.abs(x) < 1e-9 ? 1 : Math.sin(Math.PI * x) / (Math.PI * x);
2469
- var StemSignalChart = (_class15 = class extends SignalChart {
2470
- static __initStatic14() {this.meta = {
2752
+ var StemSignalChart = (_class16 = class extends SignalChart {
2753
+ static __initStatic15() {this.meta = {
2471
2754
  id: "signal-stem",
2472
2755
  name: "Stem plot",
2473
2756
  family: "scientific" /* Scientific */,
@@ -2487,7 +2770,7 @@ var StemSignalChart = (_class15 = class extends SignalChart {
2487
2770
  return { ...super.defaults(), xLabel: "Sample n", yLabel: "x[n]", orientation: "vertical" /* Vertical */, marker: "circle" /* Circle */, layout: "lanes" /* Lanes */, reconstruction: "none" /* None */, limit: 64 };
2488
2771
  }
2489
2772
  constructor(options) {
2490
- super(options.orientation === "horizontal" /* Horizontal */ ? { xLabel: "x[n]", yLabel: "Sample n", ...options } : options);_class15.prototype.__init3.call(this);;
2773
+ super(options.orientation === "horizontal" /* Horizontal */ ? { xLabel: "x[n]", yLabel: "Sample n", ...options } : options);_class16.prototype.__init3.call(this);;
2491
2774
  }
2492
2775
  __init3() {this.along = 300}
2493
2776
  get vertical() {
@@ -2554,7 +2837,7 @@ var StemSignalChart = (_class15 = class extends SignalChart {
2554
2837
  const d = (curve) => this.vertical ? this.path(curve.points, time, curve.origin) : this.path(curve.points.map(([a, b]) => [b, a]), curve.origin, time);
2555
2838
  this.stroke(ctx, "rebuilt", curves, (curve) => curve.name, d, (curve) => ctx.palette.color(curve.name), 1.5).attr("opacity", 0.55);
2556
2839
  }
2557
- }, _class15.__initStatic14(), _class15);
2840
+ }, _class16.__initStatic15(), _class16);
2558
2841
 
2559
2842
  // src/charts/signals/TimeDomainDiffChart.ts
2560
2843
 
@@ -2571,8 +2854,8 @@ var DiffMetric = /* @__PURE__ */ ((DiffMetric2) => {
2571
2854
  return DiffMetric2;
2572
2855
  })(DiffMetric || {});
2573
2856
  var COLUMNS = 360;
2574
- var TimeDomainDiffChart = (_class16 = class extends SignalChart {
2575
- static __initStatic15() {this.meta = {
2857
+ var TimeDomainDiffChart = (_class17 = class extends SignalChart {
2858
+ static __initStatic16() {this.meta = {
2576
2859
  id: "signal-time-domain-diff",
2577
2860
  name: "Time domain diff",
2578
2861
  family: "scientific" /* Scientific */,
@@ -2687,7 +2970,7 @@ var TimeDomainDiffChart = (_class16 = class extends SignalChart {
2687
2970
  const [first, second] = this.channels, lag = this.lag;
2688
2971
  this.placeSample = (channel, i) => [x(channel.t[i] - (second && channel === second && channel !== first ? lag : 0)), y(channel.v[i])];
2689
2972
  }
2690
- }, _class16.__initStatic15(), _class16);
2973
+ }, _class17.__initStatic16(), _class17);
2691
2974
 
2692
2975
  // src/charts/signals/WaterfallSpectrum.ts
2693
2976
 
@@ -2708,8 +2991,8 @@ var WaterfallOrder = /* @__PURE__ */ ((WaterfallOrder2) => {
2708
2991
  return WaterfallOrder2;
2709
2992
  })(WaterfallOrder || {});
2710
2993
  var SHEAR = 0.16;
2711
- var WaterfallSpectrum = (_class17 = class extends SpectralChart {
2712
- static __initStatic16() {this.meta = {
2994
+ var WaterfallSpectrum = (_class18 = class extends SpectralChart {
2995
+ static __initStatic17() {this.meta = {
2713
2996
  id: "signal-waterfall-spectrum",
2714
2997
  name: "Waterfall spectrum",
2715
2998
  family: "scientific" /* Scientific */,
@@ -2776,7 +3059,7 @@ var WaterfallSpectrum = (_class17 = class extends SpectralChart {
2776
3059
  const freq = x.invert(px - ridge.shift);
2777
3060
  return { x: px, tip: { title: `${SignalScales.number(ridge.time)} s`, rows: [["Frequency", `${SignalScales.hertz(freq)} Hz`], ["Peak", SignalScales.number(ridge.peak)]] }, datum: { t: ridge.time, frequency: freq } };
2778
3061
  });
2779
- const across = _nullishCoalesce(_optionalChain([ridges, 'access', _51 => _51[0], 'optionalAccess', _52 => _52.points, 'access', _53 => _53.length]), () => ( 0)), range = this.options.range;
3062
+ const across = _nullishCoalesce(_optionalChain([ridges, 'access', _57 => _57[0], 'optionalAccess', _58 => _58.points, 'access', _59 => _59.length]), () => ( 0)), range = this.options.range;
2780
3063
  if (across && ridges.every((ridge) => ridge.points.length === across)) {
2781
3064
  this.bins = SignalBins.grid(ridges.length, across, ["frame", "Bin"], (row, bin) => {
2782
3065
  const ridge = ridges[row], [freq, level] = ridge.points[bin];
@@ -2787,7 +3070,7 @@ var WaterfallSpectrum = (_class17 = class extends SpectralChart {
2787
3070
  });
2788
3071
  }
2789
3072
  }
2790
- }, _class17.__initStatic16(), _class17);
3073
+ }, _class18.__initStatic17(), _class18);
2791
3074
 
2792
3075
  // src/charts/signals/WaveformChart.ts
2793
3076
 
@@ -2801,8 +3084,8 @@ var WaveformStyle = /* @__PURE__ */ ((WaveformStyle2) => {
2801
3084
  })(WaveformStyle || {});
2802
3085
  var FLOOR4 = 60;
2803
3086
  var BAR = 5;
2804
- var WaveformChart = (_class18 = class extends SignalChart {
2805
- static __initStatic17() {this.meta = {
3087
+ var WaveformChart = (_class19 = class extends SignalChart {
3088
+ static __initStatic18() {this.meta = {
2806
3089
  id: "signal-waveform",
2807
3090
  name: "Waveform",
2808
3091
  family: "scientific" /* Scientific */,
@@ -2900,7 +3183,7 @@ var WaveformChart = (_class18 = class extends SignalChart {
2900
3183
  ctx.set(marks, { x: (bar) => bar.at, width: thick, y: (bar) => bar.top, height: (bar) => Math.max(thick, bar.bottom - bar.top) }, { y: (bar) => (bar.top + bar.bottom) / 2, height: 0 }, 1);
2901
3184
  ctx.hover(marks, (bar) => ({ title: `${SignalScales.number(bar.bucket.t)} s`, color: bar.item.color, rows: [["Peak", SignalScales.number(bar.bucket.max)], ["RMS", SignalScales.number(bar.bucket.rms)]] }));
2902
3185
  }
2903
- }, _class18.__initStatic17(), _class18);
3186
+ }, _class19.__initStatic18(), _class19);
2904
3187
 
2905
3188
  // src/charts/signals/WaveletScalogram.ts
2906
3189
 
@@ -3000,8 +3283,8 @@ var WaveletAxis = /* @__PURE__ */ ((WaveletAxis2) => {
3000
3283
  return WaveletAxis2;
3001
3284
  })(WaveletAxis || {});
3002
3285
  var SLOT = 12;
3003
- var WaveletScalogram = (_class19 = class extends TimeFrequencyChart {
3004
- static __initStatic18() {this.meta = {
3286
+ var WaveletScalogram = (_class20 = class extends TimeFrequencyChart {
3287
+ static __initStatic19() {this.meta = {
3005
3288
  id: "signal-wavelet-scalogram",
3006
3289
  name: "Wavelet scalogram",
3007
3290
  family: "scientific" /* Scientific */,
@@ -3028,7 +3311,7 @@ var WaveletScalogram = (_class19 = class extends TimeFrequencyChart {
3028
3311
 
3029
3312
  get transform() {
3030
3313
  const channel = this.channel, key = `${this.options.wavelet}|${channel.name}|${channel.v.length}|${channel.v[0]}`;
3031
- if (_optionalChain([this, 'access', _54 => _54.cache, 'optionalAccess', _55 => _55.key]) !== key) this.cache = { key, field: SignalDsp.wavelet(channel.v, channel.rate, this.options.wavelet) };
3314
+ if (_optionalChain([this, 'access', _60 => _60.cache, 'optionalAccess', _61 => _61.key]) !== key) this.cache = { key, field: SignalDsp.wavelet(channel.v, channel.rate, this.options.wavelet) };
3032
3315
  return this.cache.field;
3033
3316
  }
3034
3317
  get byPeriod() {
@@ -3095,7 +3378,7 @@ var WaveletScalogram = (_class19 = class extends TimeFrequencyChart {
3095
3378
  this.fill(ctx, "cone", [points], () => 0, (list) => _nullishCoalesce(shape(list), () => ( "")), () => ctx.theme.surface, 0.62);
3096
3379
  this.stroke(ctx, "cone-edge", [points], () => 0, (list) => this.path(list.map((point) => [point.t, point.at]), x, (value) => value), () => ctx.theme.ink, 1);
3097
3380
  }
3098
- }, _class19.__initStatic18(), _class19);
3381
+ }, _class20.__initStatic19(), _class20);
3099
3382
 
3100
3383
  // src/charts/signals/index.ts
3101
3384
  var signalsCatalog = [
@@ -3116,7 +3399,8 @@ var signalsCatalog = [
3116
3399
  ECGChart,
3117
3400
  LogicAnalyzerChart,
3118
3401
  PhaseSpaceChart,
3119
- PhaseSpace3DChart
3402
+ PhaseSpace3DChart,
3403
+ AntennaPatternChart
3120
3404
  ];
3121
3405
 
3122
3406
 
@@ -3182,4 +3466,6 @@ var signalsCatalog = [
3182
3466
 
3183
3467
 
3184
3468
 
3185
- exports.SignalWindow = SignalWindow; exports.SignalFrequencyScale = SignalFrequencyScale; exports.SignalAmplitude = SignalAmplitude; exports.SignalLayout = SignalLayout; exports.SignalWavelet = SignalWavelet; exports.AudiogramLayout = AudiogramLayout; exports.AudiogramSpacing = AudiogramSpacing; exports.AudiogramChart = AudiogramChart; exports.CepstrumKind = CepstrumKind; exports.CepstrumAxis = CepstrumAxis; exports.CepstrumMark = CepstrumMark; exports.CepstrumChart = CepstrumChart; exports.EcgView = EcgView; exports.EcgLayout = EcgLayout; exports.EcgAnnotation = EcgAnnotation; exports.ECGChart = ECGChart; exports.EnvelopeMethod = EnvelopeMethod; exports.EnvelopeShape = EnvelopeShape; exports.EnvelopeChart = EnvelopeChart; exports.FilterView = FilterView; exports.FilterResponseChart = FilterResponseChart; exports.ImpulseView = ImpulseView; exports.ImpulseMark = ImpulseMark; exports.ImpulseResponseChart = ImpulseResponseChart; exports.LogicDisplay = LogicDisplay; exports.LogicEdge = LogicEdge; exports.LogicAnalyzerChart = LogicAnalyzerChart; exports.ScopeMode = ScopeMode; exports.ScopeTrigger = ScopeTrigger; exports.ScopeDisplay = ScopeDisplay; exports.ScopeCoupling = ScopeCoupling; exports.OscilloscopeChart = OscilloscopeChart; exports.PeriodogramMethod = PeriodogramMethod; exports.PeriodogramAbscissa = PeriodogramAbscissa; exports.PeriodogramChart = PeriodogramChart; exports.Phase3DCoordinates = Phase3DCoordinates; exports.Phase3DStyle = Phase3DStyle; exports.PhaseSpace3DChart = PhaseSpace3DChart; exports.PhaseCoordinates = PhaseCoordinates; exports.PhaseMark = PhaseMark; exports.PhaseSpaceChart = PhaseSpaceChart; exports.SeismogramLayout = SeismogramLayout; exports.SeismogramFill = SeismogramFill; exports.SeismogramGain = SeismogramGain; exports.SeismogramChart = SeismogramChart; exports.SpectrumMark = SpectrumMark; exports.SpectrumChart = SpectrumChart; exports.StemReconstruction = StemReconstruction; exports.StemSignalChart = StemSignalChart; exports.DiffView = DiffView; exports.DiffMetric = DiffMetric; exports.TimeDomainDiffChart = TimeDomainDiffChart; exports.WaterfallFill = WaterfallFill; exports.WaterfallProjection = WaterfallProjection; exports.WaterfallOrder = WaterfallOrder; exports.WaterfallSpectrum = WaterfallSpectrum; exports.WaveformStyle = WaveformStyle; exports.WaveformChart = WaveformChart; exports.WaveletValue = WaveletValue; exports.WaveletAxis = WaveletAxis; exports.WaveletScalogram = WaveletScalogram; exports.signalsCatalog = signalsCatalog;
3469
+
3470
+
3471
+ exports.SignalWindow = SignalWindow; exports.SignalFrequencyScale = SignalFrequencyScale; exports.SignalAmplitude = SignalAmplitude; exports.SignalLayout = SignalLayout; exports.SignalWavelet = SignalWavelet; exports.AntennaPatternForm = AntennaPatternForm; exports.AntennaPatternChart = AntennaPatternChart; exports.AudiogramLayout = AudiogramLayout; exports.AudiogramSpacing = AudiogramSpacing; exports.AudiogramChart = AudiogramChart; exports.CepstrumKind = CepstrumKind; exports.CepstrumAxis = CepstrumAxis; exports.CepstrumMark = CepstrumMark; exports.CepstrumChart = CepstrumChart; exports.EcgView = EcgView; exports.EcgLayout = EcgLayout; exports.EcgAnnotation = EcgAnnotation; exports.ECGChart = ECGChart; exports.EnvelopeMethod = EnvelopeMethod; exports.EnvelopeShape = EnvelopeShape; exports.EnvelopeChart = EnvelopeChart; exports.FilterView = FilterView; exports.FilterResponseChart = FilterResponseChart; exports.ImpulseView = ImpulseView; exports.ImpulseMark = ImpulseMark; exports.ImpulseResponseChart = ImpulseResponseChart; exports.LogicDisplay = LogicDisplay; exports.LogicEdge = LogicEdge; exports.LogicAnalyzerChart = LogicAnalyzerChart; exports.ScopeMode = ScopeMode; exports.ScopeTrigger = ScopeTrigger; exports.ScopeDisplay = ScopeDisplay; exports.ScopeCoupling = ScopeCoupling; exports.OscilloscopeChart = OscilloscopeChart; exports.PeriodogramMethod = PeriodogramMethod; exports.PeriodogramAbscissa = PeriodogramAbscissa; exports.PeriodogramChart = PeriodogramChart; exports.Phase3DCoordinates = Phase3DCoordinates; exports.Phase3DStyle = Phase3DStyle; exports.PhaseSpace3DChart = PhaseSpace3DChart; exports.PhaseCoordinates = PhaseCoordinates; exports.PhaseMark = PhaseMark; exports.PhaseSpaceChart = PhaseSpaceChart; exports.SeismogramLayout = SeismogramLayout; exports.SeismogramFill = SeismogramFill; exports.SeismogramGain = SeismogramGain; exports.SeismogramChart = SeismogramChart; exports.SpectrumMark = SpectrumMark; exports.SpectrumChart = SpectrumChart; exports.StemReconstruction = StemReconstruction; exports.StemSignalChart = StemSignalChart; exports.DiffView = DiffView; exports.DiffMetric = DiffMetric; exports.TimeDomainDiffChart = TimeDomainDiffChart; exports.WaterfallFill = WaterfallFill; exports.WaterfallProjection = WaterfallProjection; exports.WaterfallOrder = WaterfallOrder; exports.WaterfallSpectrum = WaterfallSpectrum; exports.WaveformStyle = WaveformStyle; exports.WaveformChart = WaveformChart; exports.WaveletValue = WaveletValue; exports.WaveletAxis = WaveletAxis; exports.WaveletScalogram = WaveletScalogram; exports.signalsCatalog = signalsCatalog;