qsharp-lang 1.23.1-dev → 1.23.2-dev

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 (342) hide show
  1. package/dist/browser.d.ts +1 -1
  2. package/dist/katas-content.generated.js +1 -1
  3. package/dist/katas-content.generated.md.js +1 -1
  4. package/dist/main.d.ts +1 -0
  5. package/dist/samples.generated.js +1 -1
  6. package/docs/Microsoft.Quantum.Core/IsRangeEmpty.md +1 -1
  7. package/docs/Microsoft.Quantum.Core/Length.md +1 -1
  8. package/docs/Microsoft.Quantum.Core/RangeEnd.md +1 -1
  9. package/docs/Microsoft.Quantum.Core/RangeStart.md +1 -1
  10. package/docs/Microsoft.Quantum.Core/Repeated.md +1 -1
  11. package/docs/Microsoft.Quantum.Core/index.md +1 -1
  12. package/docs/Std.Arithmetic/AddLE.md +1 -1
  13. package/docs/Std.Arithmetic/ApplyIfEqualL.md +1 -1
  14. package/docs/Std.Arithmetic/ApplyIfEqualLE.md +1 -1
  15. package/docs/Std.Arithmetic/ApplyIfGreaterL.md +1 -1
  16. package/docs/Std.Arithmetic/ApplyIfGreaterLE.md +1 -1
  17. package/docs/Std.Arithmetic/ApplyIfGreaterOrEqualL.md +1 -1
  18. package/docs/Std.Arithmetic/ApplyIfGreaterOrEqualLE.md +1 -1
  19. package/docs/Std.Arithmetic/ApplyIfLessL.md +1 -1
  20. package/docs/Std.Arithmetic/ApplyIfLessLE.md +1 -1
  21. package/docs/Std.Arithmetic/ApplyIfLessOrEqualL.md +1 -1
  22. package/docs/Std.Arithmetic/ApplyIfLessOrEqualLE.md +1 -1
  23. package/docs/Std.Arithmetic/FourierTDIncByLE.md +1 -1
  24. package/docs/Std.Arithmetic/IncByI.md +1 -1
  25. package/docs/Std.Arithmetic/IncByIUsingIncByLE.md +1 -1
  26. package/docs/Std.Arithmetic/IncByL.md +1 -1
  27. package/docs/Std.Arithmetic/IncByLE.md +1 -1
  28. package/docs/Std.Arithmetic/IncByLEUsingAddLE.md +1 -1
  29. package/docs/Std.Arithmetic/IncByLUsingIncByLE.md +1 -1
  30. package/docs/Std.Arithmetic/LookAheadDKRSAddLE.md +1 -1
  31. package/docs/Std.Arithmetic/MAJ.md +1 -1
  32. package/docs/Std.Arithmetic/ReflectAboutInteger.md +1 -1
  33. package/docs/Std.Arithmetic/RippleCarryCGAddLE.md +1 -1
  34. package/docs/Std.Arithmetic/RippleCarryCGIncByLE.md +1 -1
  35. package/docs/Std.Arithmetic/RippleCarryTTKIncByLE.md +1 -1
  36. package/docs/Std.Arithmetic/index.md +1 -1
  37. package/docs/Std.Arrays/All.md +1 -1
  38. package/docs/Std.Arrays/Any.md +1 -1
  39. package/docs/Std.Arrays/Chunks.md +1 -1
  40. package/docs/Std.Arrays/CircularlyShifted.md +1 -1
  41. package/docs/Std.Arrays/ColumnAt.md +1 -1
  42. package/docs/Std.Arrays/Count.md +1 -1
  43. package/docs/Std.Arrays/Diagonal.md +1 -1
  44. package/docs/Std.Arrays/DrawMany.md +1 -1
  45. package/docs/Std.Arrays/Enumerated.md +1 -1
  46. package/docs/Std.Arrays/Excluding.md +1 -1
  47. package/docs/Std.Arrays/Filtered.md +1 -1
  48. package/docs/Std.Arrays/FlatMapped.md +1 -1
  49. package/docs/Std.Arrays/Flattened.md +1 -1
  50. package/docs/Std.Arrays/Fold.md +1 -1
  51. package/docs/Std.Arrays/ForEach.md +1 -1
  52. package/docs/Std.Arrays/Head.md +1 -1
  53. package/docs/Std.Arrays/HeadAndRest.md +1 -1
  54. package/docs/Std.Arrays/IndexOf.md +1 -1
  55. package/docs/Std.Arrays/IndexRange.md +1 -1
  56. package/docs/Std.Arrays/Interleaved.md +1 -1
  57. package/docs/Std.Arrays/IsEmpty.md +1 -1
  58. package/docs/Std.Arrays/IsRectangularArray.md +1 -1
  59. package/docs/Std.Arrays/IsSorted.md +1 -1
  60. package/docs/Std.Arrays/IsSquareArray.md +1 -1
  61. package/docs/Std.Arrays/Mapped.md +1 -1
  62. package/docs/Std.Arrays/MappedByIndex.md +1 -1
  63. package/docs/Std.Arrays/MappedOverRange.md +1 -1
  64. package/docs/Std.Arrays/Most.md +1 -1
  65. package/docs/Std.Arrays/MostAndTail.md +1 -1
  66. package/docs/Std.Arrays/Padded.md +1 -1
  67. package/docs/Std.Arrays/Partitioned.md +1 -1
  68. package/docs/Std.Arrays/Rest.md +1 -1
  69. package/docs/Std.Arrays/Reversed.md +1 -1
  70. package/docs/Std.Arrays/SequenceI.md +1 -1
  71. package/docs/Std.Arrays/SequenceL.md +1 -1
  72. package/docs/Std.Arrays/Sorted.md +1 -1
  73. package/docs/Std.Arrays/Subarray.md +1 -1
  74. package/docs/Std.Arrays/Swapped.md +1 -1
  75. package/docs/Std.Arrays/Tail.md +1 -1
  76. package/docs/Std.Arrays/Transposed.md +1 -1
  77. package/docs/Std.Arrays/Unzipped.md +1 -1
  78. package/docs/Std.Arrays/Where.md +1 -1
  79. package/docs/Std.Arrays/Windows.md +1 -1
  80. package/docs/Std.Arrays/Zipped.md +1 -1
  81. package/docs/Std.Arrays/index.md +1 -1
  82. package/docs/Std.Canon/ApplyCNOTChain.md +1 -1
  83. package/docs/Std.Canon/ApplyControlledOnBitString.md +1 -1
  84. package/docs/Std.Canon/ApplyControlledOnInt.md +1 -1
  85. package/docs/Std.Canon/ApplyOperationPowerA.md +1 -1
  86. package/docs/Std.Canon/ApplyOperationPowerCA.md +1 -1
  87. package/docs/Std.Canon/ApplyP.md +1 -1
  88. package/docs/Std.Canon/ApplyPauli.md +1 -1
  89. package/docs/Std.Canon/ApplyPauliFromBitString.md +1 -1
  90. package/docs/Std.Canon/ApplyPauliFromInt.md +1 -1
  91. package/docs/Std.Canon/ApplyQFT.md +1 -1
  92. package/docs/Std.Canon/ApplyQPE.md +1 -1
  93. package/docs/Std.Canon/ApplyToEach.md +1 -1
  94. package/docs/Std.Canon/ApplyToEachA.md +1 -1
  95. package/docs/Std.Canon/ApplyToEachC.md +1 -1
  96. package/docs/Std.Canon/ApplyToEachCA.md +1 -1
  97. package/docs/Std.Canon/ApplyXorInPlace.md +1 -1
  98. package/docs/Std.Canon/ApplyXorInPlaceL.md +1 -1
  99. package/docs/Std.Canon/CX.md +1 -1
  100. package/docs/Std.Canon/CY.md +1 -1
  101. package/docs/Std.Canon/CZ.md +1 -1
  102. package/docs/Std.Canon/Fst.md +1 -1
  103. package/docs/Std.Canon/MapPauliAxis.md +1 -1
  104. package/docs/Std.Canon/Relabel.md +1 -1
  105. package/docs/Std.Canon/Snd.md +1 -1
  106. package/docs/Std.Canon/SwapReverseRegister.md +1 -1
  107. package/docs/Std.Canon/index.md +1 -1
  108. package/docs/Std.Convert/BigIntAsBoolArray.md +1 -1
  109. package/docs/Std.Convert/BigIntAsInt.md +1 -1
  110. package/docs/Std.Convert/BoolArrayAsBigInt.md +1 -1
  111. package/docs/Std.Convert/BoolArrayAsInt.md +1 -1
  112. package/docs/Std.Convert/BoolArrayAsResultArray.md +1 -1
  113. package/docs/Std.Convert/BoolAsResult.md +1 -1
  114. package/docs/Std.Convert/ComplexAsComplexPolar.md +1 -1
  115. package/docs/Std.Convert/ComplexPolarAsComplex.md +1 -1
  116. package/docs/Std.Convert/DoubleAsStringWithPrecision.md +1 -1
  117. package/docs/Std.Convert/IntAsBigInt.md +1 -1
  118. package/docs/Std.Convert/IntAsBoolArray.md +1 -1
  119. package/docs/Std.Convert/IntAsDouble.md +1 -1
  120. package/docs/Std.Convert/ResultArrayAsBoolArray.md +1 -1
  121. package/docs/Std.Convert/ResultArrayAsInt.md +1 -1
  122. package/docs/Std.Convert/ResultAsBool.md +1 -1
  123. package/docs/Std.Convert/index.md +1 -1
  124. package/docs/Std.Core/Complex.md +1 -1
  125. package/docs/Std.Core/Length.md +1 -1
  126. package/docs/Std.Core/Repeated.md +1 -1
  127. package/docs/Std.Core/index.md +1 -1
  128. package/docs/Std.Diagnostics/ApplyIdleNoise.md +1 -1
  129. package/docs/Std.Diagnostics/BitFlipNoise.md +1 -1
  130. package/docs/Std.Diagnostics/CheckAllZero.md +1 -1
  131. package/docs/Std.Diagnostics/CheckOperationsAreEqual.md +1 -1
  132. package/docs/Std.Diagnostics/CheckZero.md +1 -1
  133. package/docs/Std.Diagnostics/ConfigurePauliNoise.md +1 -1
  134. package/docs/Std.Diagnostics/ConfigureQubitLoss.md +1 -1
  135. package/docs/Std.Diagnostics/DepolarizingNoise.md +1 -1
  136. package/docs/Std.Diagnostics/DumpMachine.md +1 -1
  137. package/docs/Std.Diagnostics/DumpOperation.md +1 -1
  138. package/docs/Std.Diagnostics/DumpRegister.md +1 -1
  139. package/docs/Std.Diagnostics/Fact.md +1 -1
  140. package/docs/Std.Diagnostics/NoNoise.md +1 -1
  141. package/docs/Std.Diagnostics/PhaseFlipNoise.md +1 -1
  142. package/docs/Std.Diagnostics/StartCountingFunction.md +1 -1
  143. package/docs/Std.Diagnostics/StartCountingOperation.md +1 -1
  144. package/docs/Std.Diagnostics/StartCountingQubits.md +1 -1
  145. package/docs/Std.Diagnostics/StopCountingFunction.md +1 -1
  146. package/docs/Std.Diagnostics/StopCountingOperation.md +1 -1
  147. package/docs/Std.Diagnostics/StopCountingQubits.md +1 -1
  148. package/docs/Std.Diagnostics/index.md +1 -1
  149. package/docs/Std.Intrinsic/AND.md +1 -1
  150. package/docs/Std.Intrinsic/ApplyUnitary.md +1 -1
  151. package/docs/Std.Intrinsic/CCNOT.md +1 -1
  152. package/docs/Std.Intrinsic/CNOT.md +1 -1
  153. package/docs/Std.Intrinsic/Exp.md +1 -1
  154. package/docs/Std.Intrinsic/H.md +1 -1
  155. package/docs/Std.Intrinsic/I.md +1 -1
  156. package/docs/Std.Intrinsic/M.md +1 -1
  157. package/docs/Std.Intrinsic/Measure.md +1 -1
  158. package/docs/Std.Intrinsic/Message.md +1 -1
  159. package/docs/Std.Intrinsic/R.md +1 -1
  160. package/docs/Std.Intrinsic/R1.md +1 -1
  161. package/docs/Std.Intrinsic/R1Frac.md +1 -1
  162. package/docs/Std.Intrinsic/RFrac.md +1 -1
  163. package/docs/Std.Intrinsic/Reset.md +1 -1
  164. package/docs/Std.Intrinsic/ResetAll.md +1 -1
  165. package/docs/Std.Intrinsic/Rx.md +1 -1
  166. package/docs/Std.Intrinsic/Rxx.md +1 -1
  167. package/docs/Std.Intrinsic/Ry.md +1 -1
  168. package/docs/Std.Intrinsic/Ryy.md +1 -1
  169. package/docs/Std.Intrinsic/Rz.md +1 -1
  170. package/docs/Std.Intrinsic/Rzz.md +1 -1
  171. package/docs/Std.Intrinsic/S.md +1 -1
  172. package/docs/Std.Intrinsic/SWAP.md +1 -1
  173. package/docs/Std.Intrinsic/SX.md +1 -1
  174. package/docs/Std.Intrinsic/T.md +1 -1
  175. package/docs/Std.Intrinsic/X.md +1 -1
  176. package/docs/Std.Intrinsic/Y.md +1 -1
  177. package/docs/Std.Intrinsic/Z.md +1 -1
  178. package/docs/Std.Intrinsic/index.md +1 -1
  179. package/docs/Std.Logical/Xor.md +1 -1
  180. package/docs/Std.Logical/index.md +1 -1
  181. package/docs/Std.Math/AbsComplex.md +1 -1
  182. package/docs/Std.Math/AbsComplexPolar.md +1 -1
  183. package/docs/Std.Math/AbsD.md +1 -1
  184. package/docs/Std.Math/AbsI.md +1 -1
  185. package/docs/Std.Math/AbsL.md +1 -1
  186. package/docs/Std.Math/AbsSquaredComplex.md +1 -1
  187. package/docs/Std.Math/AbsSquaredComplexPolar.md +1 -1
  188. package/docs/Std.Math/ApproximateFactorial.md +1 -1
  189. package/docs/Std.Math/ArcCos.md +4 -3
  190. package/docs/Std.Math/ArcCosh.md +4 -4
  191. package/docs/Std.Math/ArcSin.md +4 -3
  192. package/docs/Std.Math/ArcSinh.md +4 -4
  193. package/docs/Std.Math/ArcTan.md +4 -3
  194. package/docs/Std.Math/ArcTan2.md +4 -3
  195. package/docs/Std.Math/ArcTanh.md +4 -4
  196. package/docs/Std.Math/ArgComplex.md +1 -1
  197. package/docs/Std.Math/ArgComplexPolar.md +1 -1
  198. package/docs/Std.Math/Binom.md +1 -1
  199. package/docs/Std.Math/BitSizeI.md +1 -1
  200. package/docs/Std.Math/BitSizeL.md +1 -1
  201. package/docs/Std.Math/Ceiling.md +1 -1
  202. package/docs/Std.Math/Complex.md +1 -1
  203. package/docs/Std.Math/ComplexPolar.md +1 -1
  204. package/docs/Std.Math/ContinuedFractionConvergentI.md +1 -1
  205. package/docs/Std.Math/ContinuedFractionConvergentL.md +1 -1
  206. package/docs/Std.Math/Cos.md +4 -3
  207. package/docs/Std.Math/Cosh.md +4 -4
  208. package/docs/Std.Math/DivRemI.md +1 -1
  209. package/docs/Std.Math/DivRemL.md +1 -1
  210. package/docs/Std.Math/DividedByC.md +1 -1
  211. package/docs/Std.Math/DividedByCP.md +1 -1
  212. package/docs/Std.Math/E.md +1 -1
  213. package/docs/Std.Math/ExpModI.md +1 -1
  214. package/docs/Std.Math/ExpModL.md +1 -1
  215. package/docs/Std.Math/ExtendedGreatestCommonDivisorI.md +1 -1
  216. package/docs/Std.Math/ExtendedGreatestCommonDivisorL.md +1 -1
  217. package/docs/Std.Math/FactorialI.md +1 -1
  218. package/docs/Std.Math/FactorialL.md +1 -1
  219. package/docs/Std.Math/Floor.md +1 -1
  220. package/docs/Std.Math/GreatestCommonDivisorI.md +1 -1
  221. package/docs/Std.Math/GreatestCommonDivisorL.md +1 -1
  222. package/docs/Std.Math/HammingWeightI.md +1 -1
  223. package/docs/Std.Math/InverseModI.md +1 -1
  224. package/docs/Std.Math/InverseModL.md +1 -1
  225. package/docs/Std.Math/IsCoprimeI.md +1 -1
  226. package/docs/Std.Math/IsCoprimeL.md +1 -1
  227. package/docs/Std.Math/IsInfinite.md +1 -1
  228. package/docs/Std.Math/IsNaN.md +1 -1
  229. package/docs/Std.Math/LargestFixedPoint.md +1 -1
  230. package/docs/Std.Math/Lg.md +1 -1
  231. package/docs/Std.Math/Log.md +1 -1
  232. package/docs/Std.Math/Log10.md +1 -1
  233. package/docs/Std.Math/LogFactorialD.md +1 -1
  234. package/docs/Std.Math/LogGammaD.md +1 -1
  235. package/docs/Std.Math/LogOf2.md +1 -1
  236. package/docs/Std.Math/Max.md +1 -1
  237. package/docs/Std.Math/MaxD.md +1 -1
  238. package/docs/Std.Math/MaxI.md +1 -1
  239. package/docs/Std.Math/MaxL.md +1 -1
  240. package/docs/Std.Math/Min.md +1 -1
  241. package/docs/Std.Math/MinD.md +1 -1
  242. package/docs/Std.Math/MinI.md +1 -1
  243. package/docs/Std.Math/MinL.md +1 -1
  244. package/docs/Std.Math/MinusC.md +1 -1
  245. package/docs/Std.Math/MinusCP.md +1 -1
  246. package/docs/Std.Math/ModulusI.md +1 -1
  247. package/docs/Std.Math/ModulusL.md +1 -1
  248. package/docs/Std.Math/NegationC.md +1 -1
  249. package/docs/Std.Math/NegationCP.md +1 -1
  250. package/docs/Std.Math/PI.md +1 -1
  251. package/docs/Std.Math/PNorm.md +1 -1
  252. package/docs/Std.Math/PNormalized.md +1 -1
  253. package/docs/Std.Math/PlusC.md +1 -1
  254. package/docs/Std.Math/PlusCP.md +1 -1
  255. package/docs/Std.Math/PowC.md +1 -1
  256. package/docs/Std.Math/PowCP.md +1 -1
  257. package/docs/Std.Math/RealMod.md +1 -1
  258. package/docs/Std.Math/Round.md +1 -1
  259. package/docs/Std.Math/RoundHalfAwayFromZero.md +1 -1
  260. package/docs/Std.Math/SignD.md +1 -1
  261. package/docs/Std.Math/SignI.md +1 -1
  262. package/docs/Std.Math/SignL.md +1 -1
  263. package/docs/Std.Math/Sin.md +4 -3
  264. package/docs/Std.Math/Sinh.md +4 -4
  265. package/docs/Std.Math/SmallestFixedPoint.md +1 -1
  266. package/docs/Std.Math/Sqrt.md +1 -1
  267. package/docs/Std.Math/SquaredNorm.md +1 -1
  268. package/docs/Std.Math/Tan.md +4 -3
  269. package/docs/Std.Math/Tanh.md +4 -4
  270. package/docs/Std.Math/TimesC.md +1 -1
  271. package/docs/Std.Math/TimesCP.md +1 -1
  272. package/docs/Std.Math/TrailingZeroCountI.md +1 -1
  273. package/docs/Std.Math/TrailingZeroCountL.md +1 -1
  274. package/docs/Std.Math/Truncate.md +1 -1
  275. package/docs/Std.Math/index.md +14 -14
  276. package/docs/Std.Measurement/IsLossResult.md +1 -1
  277. package/docs/Std.Measurement/MResetEachZ.md +1 -1
  278. package/docs/Std.Measurement/MResetX.md +1 -1
  279. package/docs/Std.Measurement/MResetY.md +1 -1
  280. package/docs/Std.Measurement/MResetZ.md +1 -1
  281. package/docs/Std.Measurement/MResetZChecked.md +1 -1
  282. package/docs/Std.Measurement/MeasureAllZ.md +1 -1
  283. package/docs/Std.Measurement/MeasureEachZ.md +1 -1
  284. package/docs/Std.Measurement/MeasureInteger.md +1 -1
  285. package/docs/Std.Measurement/index.md +1 -1
  286. package/docs/Std.Random/DrawRandomBool.md +1 -1
  287. package/docs/Std.Random/DrawRandomDouble.md +1 -1
  288. package/docs/Std.Random/DrawRandomInt.md +1 -1
  289. package/docs/Std.Random/index.md +1 -1
  290. package/docs/Std.Range/IsRangeEmpty.md +1 -1
  291. package/docs/Std.Range/RangeEnd.md +1 -1
  292. package/docs/Std.Range/RangeReverse.md +1 -1
  293. package/docs/Std.Range/RangeStart.md +1 -1
  294. package/docs/Std.Range/RangeStep.md +1 -1
  295. package/docs/Std.Range/index.md +1 -1
  296. package/docs/Std.ResourceEstimation/AccountForEstimates.md +1 -1
  297. package/docs/Std.ResourceEstimation/AuxQubitCount.md +1 -1
  298. package/docs/Std.ResourceEstimation/BeginEstimateCaching.md +1 -1
  299. package/docs/Std.ResourceEstimation/BeginRepeatEstimates.md +1 -1
  300. package/docs/Std.ResourceEstimation/CczCount.md +1 -1
  301. package/docs/Std.ResourceEstimation/EnableMemoryComputeArchitecture.md +1 -1
  302. package/docs/Std.ResourceEstimation/EndEstimateCaching.md +1 -1
  303. package/docs/Std.ResourceEstimation/EndRepeatEstimates.md +1 -1
  304. package/docs/Std.ResourceEstimation/LeastFrequentlyUsed.md +1 -1
  305. package/docs/Std.ResourceEstimation/LeastRecentlyUsed.md +1 -1
  306. package/docs/Std.ResourceEstimation/MeasurementCount.md +1 -1
  307. package/docs/Std.ResourceEstimation/PSSPCLayout.md +1 -1
  308. package/docs/Std.ResourceEstimation/RepeatEstimates.md +1 -1
  309. package/docs/Std.ResourceEstimation/RotationCount.md +1 -1
  310. package/docs/Std.ResourceEstimation/RotationDepth.md +1 -1
  311. package/docs/Std.ResourceEstimation/SingleVariant.md +1 -1
  312. package/docs/Std.ResourceEstimation/TCount.md +1 -1
  313. package/docs/Std.ResourceEstimation/index.md +1 -1
  314. package/docs/Std.StatePreparation/ApproximatelyPreparePureStateCP.md +1 -1
  315. package/docs/Std.StatePreparation/PreparePureStateD.md +1 -1
  316. package/docs/Std.StatePreparation/PrepareUniformSuperposition.md +1 -1
  317. package/docs/Std.StatePreparation/index.md +1 -1
  318. package/docs/Std.TableLookup/Select.md +1 -1
  319. package/docs/Std.TableLookup/index.md +1 -1
  320. package/docs/index.md +4 -4
  321. package/lib/nodejs/qsc_wasm.cjs +2 -2
  322. package/lib/nodejs/qsc_wasm.d.cts +23 -1
  323. package/lib/nodejs/qsc_wasm_bg.wasm +0 -0
  324. package/lib/web/qsc_wasm.d.ts +23 -1
  325. package/lib/web/qsc_wasm.js +2 -2
  326. package/lib/web/qsc_wasm_bg.wasm +0 -0
  327. package/package.json +1 -1
  328. package/ux/circuit-vis/constants.ts +16 -13
  329. package/ux/circuit-vis/draggable.ts +4 -1
  330. package/ux/circuit-vis/formatters/gateFormatter.ts +97 -102
  331. package/ux/circuit-vis/formatters/inputFormatter.ts +116 -14
  332. package/ux/circuit-vis/gateRenderData.ts +4 -0
  333. package/ux/circuit-vis/panel.ts +4 -2
  334. package/ux/circuit-vis/process.ts +98 -28
  335. package/ux/circuit-vis/sqore.ts +159 -71
  336. package/ux/circuit-vis/utils.ts +58 -19
  337. package/ux/circuit.tsx +1 -1
  338. package/ux/estimatesPanel.tsx +1 -1
  339. package/ux/output_data.md +1 -1
  340. package/ux/qsharp-circuit.css +20 -14
  341. package/ux/qsharp-ux.css +84 -27
  342. package/ux/scatterChart.tsx +1 -1
@@ -6,7 +6,9 @@ import {
6
6
  startX,
7
7
  gatePadding,
8
8
  controlBtnOffset,
9
- groupBoxPadding,
9
+ groupPaddingX,
10
+ groupTopPadding,
11
+ groupBottomPadding,
10
12
  } from "./constants.js";
11
13
  import {
12
14
  ComponentGrid,
@@ -16,7 +18,7 @@ import {
16
18
  } from "./circuit.js";
17
19
  import { GateRenderData, GateType } from "./gateRenderData.js";
18
20
  import { Register, RegisterMap } from "./register.js";
19
- import { getGateWidth } from "./utils.js";
21
+ import { getMinGateWidth } from "./utils.js";
20
22
 
21
23
  /**
22
24
  * Takes in a component grid and maps the operations to `GateRenderData` objects which
@@ -24,20 +26,38 @@ import { getGateWidth } from "./utils.js";
24
26
  *
25
27
  * @param componentGrid Grid of circuit components.
26
28
  * @param registers Mapping from qubit IDs to register render data.
29
+ * @param topY y-coordinate of the topmost register involved in the operation.
30
+ * @param bottomY y-coordinate of the bottommost register involved in the operation.
31
+ * @param renderLocations Optional function to map source locations to link hrefs and titles.
27
32
  *
28
33
  * @returns An object containing `renderDataArray` (2D Array of GateRenderData objects) and
29
34
  * `svgWidth` which is the width of the entire SVG.
30
35
  */
31
36
  const processOperations = (
32
37
  componentGrid: ComponentGrid,
38
+ topY: number,
39
+ bottomY: number,
33
40
  registers: RegisterMap,
34
41
  renderLocations?: (s: SourceLocation[]) => { title: string; href: string },
35
- ): { renderDataArray: GateRenderData[][]; svgWidth: number } => {
42
+ ): {
43
+ renderDataArray: GateRenderData[][];
44
+ svgWidth: number;
45
+ maxTopPadding: number;
46
+ maxBottomPadding: number;
47
+ } => {
36
48
  if (componentGrid.length === 0)
37
- return { renderDataArray: [], svgWidth: startX + gatePadding * 2 };
49
+ return {
50
+ renderDataArray: [],
51
+ svgWidth: startX + gatePadding * 2,
52
+ maxTopPadding: 0,
53
+ maxBottomPadding: 0,
54
+ };
38
55
  const numColumns: number = componentGrid.length;
39
56
  const columnsWidths: number[] = new Array(numColumns).fill(minGateWidth);
40
57
 
58
+ let maxTopPadding = 0;
59
+ let maxBottomPadding = 0;
60
+
41
61
  // Get classical registers and their starting column index
42
62
  const classicalRegs: [number, Register][] =
43
63
  _getClassicalRegStarts(componentGrid);
@@ -52,6 +72,31 @@ const processOperations = (
52
72
  renderLocations,
53
73
  );
54
74
 
75
+ let targets: Register[];
76
+ switch (op.kind) {
77
+ case "unitary":
78
+ targets = op.targets;
79
+ break;
80
+ case "measurement":
81
+ targets = op.qubits;
82
+ break;
83
+ case "ket":
84
+ targets = op.targets;
85
+ break;
86
+ }
87
+ const minTargetY = Math.min(...(renderData.targetsY as number[]));
88
+ const maxTargetY = Math.max(...(renderData.targetsY as number[]));
89
+
90
+ if (topY === minTargetY) {
91
+ maxTopPadding = Math.max(maxTopPadding, renderData.topPadding);
92
+ }
93
+ if (bottomY === maxTargetY) {
94
+ maxBottomPadding = Math.max(
95
+ maxBottomPadding,
96
+ renderData.bottomPadding,
97
+ );
98
+ }
99
+
55
100
  if (
56
101
  op != null &&
57
102
  [GateType.Unitary, GateType.Ket, GateType.ControlledUnitary].includes(
@@ -75,19 +120,6 @@ const processOperations = (
75
120
  return children[reg.result].y;
76
121
  });
77
122
 
78
- let targets: Register[];
79
- switch (op.kind) {
80
- case "unitary":
81
- targets = op.targets;
82
- break;
83
- case "measurement":
84
- targets = op.qubits;
85
- break;
86
- case "ket":
87
- targets = op.targets;
88
- break;
89
- }
90
-
91
123
  renderData.targetsY = _splitTargetsY(
92
124
  targets,
93
125
  classicalRegY,
@@ -112,7 +144,12 @@ const processOperations = (
112
144
  // Fill in x coord of each gate
113
145
  const endX: number = _fillRenderDataX(filteredArray, columnsWidths);
114
146
 
115
- return { renderDataArray: filteredArray, svgWidth: endX };
147
+ return {
148
+ renderDataArray: filteredArray,
149
+ svgWidth: endX,
150
+ maxTopPadding,
151
+ maxBottomPadding,
152
+ };
116
153
  };
117
154
 
118
155
  /**
@@ -166,6 +203,8 @@ const _opToRenderData = (
166
203
  targetsY: [],
167
204
  label: "",
168
205
  width: -1,
206
+ topPadding: 0,
207
+ bottomPadding: 0,
169
208
  };
170
209
 
171
210
  if (op == null) return renderData;
@@ -203,6 +242,8 @@ const _opToRenderData = (
203
242
  // Set y coords
204
243
  renderData.controlsY = controls?.map((reg) => _getRegY(reg, registers)) || [];
205
244
  renderData.targetsY = targets.map((reg) => _getRegY(reg, registers));
245
+ const topY = Math.min(...(renderData.targetsY as number[]));
246
+ const bottomY = Math.max(...(renderData.targetsY as number[]));
206
247
 
207
248
  if (isConditional) {
208
249
  // Classically-controlled operations
@@ -219,13 +260,18 @@ const _opToRenderData = (
219
260
  ),
220
261
  }))
221
262
  .filter((col) => col.components.length > 0);
263
+
222
264
  let childrenInstrs = processOperations(
223
265
  onZeroOps,
266
+ topY,
267
+ bottomY,
224
268
  registers,
225
269
  renderLocations,
226
270
  );
227
271
  const zeroGates: GateRenderData[][] = childrenInstrs.renderDataArray;
228
272
  const zeroChildWidth: number = childrenInstrs.svgWidth;
273
+ const zeroChildMaxTopPadding = childrenInstrs.maxTopPadding;
274
+ const zeroChildMaxBottomPadding = childrenInstrs.maxBottomPadding;
229
275
 
230
276
  // Gates to display when classical bit is 1.
231
277
  const onOneOps: ComponentGrid = children
@@ -235,18 +281,37 @@ const _opToRenderData = (
235
281
  ),
236
282
  }))
237
283
  .filter((col) => col.components.length > 0);
238
- childrenInstrs = processOperations(onOneOps, registers, renderLocations);
284
+ childrenInstrs = processOperations(
285
+ onOneOps,
286
+ topY,
287
+ bottomY,
288
+ registers,
289
+ renderLocations,
290
+ );
239
291
  const oneGates: GateRenderData[][] = childrenInstrs.renderDataArray;
240
292
  const oneChildWidth: number = childrenInstrs.svgWidth;
293
+ const oneChildMaxTopPadding = childrenInstrs.maxTopPadding;
294
+ const oneChildMaxBottomPadding = childrenInstrs.maxBottomPadding;
241
295
 
242
296
  // Subtract startX (left-side) and 2*gatePadding (right-side) from nested child gates width
243
297
  const width: number =
244
298
  Math.max(zeroChildWidth, oneChildWidth) - startX - gatePadding * 2;
245
299
 
300
+ const maxTopPadding = Math.max(
301
+ zeroChildMaxTopPadding,
302
+ oneChildMaxTopPadding,
303
+ );
304
+ const maxBottomPadding = Math.max(
305
+ zeroChildMaxBottomPadding,
306
+ oneChildMaxBottomPadding,
307
+ );
308
+
246
309
  renderData.type = GateType.ClassicalControlled;
247
310
  renderData.children = [zeroGates, oneGates];
248
311
  // Add additional width from control button and inner box padding for dashed box
249
- renderData.width = width + controlBtnOffset + groupBoxPadding * 2;
312
+ renderData.width = width + controlBtnOffset + groupPaddingX * 2;
313
+ renderData.topPadding = maxTopPadding + groupTopPadding;
314
+ renderData.bottomPadding = maxBottomPadding + groupBottomPadding;
250
315
 
251
316
  // Set targets to first and last quantum registers so we can render the surrounding box
252
317
  // around all quantum registers.
@@ -259,17 +324,23 @@ const _opToRenderData = (
259
324
  ) {
260
325
  const childrenInstrs = processOperations(
261
326
  children!,
327
+ topY,
328
+ bottomY,
262
329
  registers,
263
330
  renderLocations,
264
331
  );
265
332
  renderData.type = GateType.Group;
333
+ renderData.label = gate;
266
334
  renderData.children = childrenInstrs.renderDataArray;
267
335
  // _zoomButton function in gateFormatter.ts relies on
268
336
  // 'expanded' attribute to render zoom button
269
337
  renderData.dataAttributes = { expanded: "true" };
270
- // Subtract startX (left-side) and add inner box padding (minus nested gate padding) for dashed box
338
+ // Subtract startX (left-side) and add inner box padding for dashed box
271
339
  renderData.width =
272
- childrenInstrs.svgWidth - startX + (groupBoxPadding - gatePadding) * 2;
340
+ childrenInstrs.svgWidth - startX - gatePadding * 3 + groupPaddingX * 2; // (svgWidth includes 3 extra gate paddings)
341
+ renderData.topPadding = childrenInstrs.maxTopPadding + groupTopPadding;
342
+ renderData.bottomPadding =
343
+ childrenInstrs.maxBottomPadding + groupBottomPadding;
273
344
  } else if (op.kind === "measurement") {
274
345
  renderData.type = GateType.Measure;
275
346
  } else if (op.kind === "ket") {
@@ -296,8 +367,9 @@ const _opToRenderData = (
296
367
  // For now, we only display the first argument
297
368
  if (args !== undefined && args.length > 0) renderData.displayArgs = args[0];
298
369
 
299
- // Set gate width
300
- renderData.width = getGateWidth(renderData);
370
+ // Minimum width is calculated based on the label and args
371
+ const minWidth = getMinGateWidth(renderData);
372
+ renderData.width = Math.max(minWidth, renderData.width);
301
373
 
302
374
  if (op.metadata?.source && renderLocations) {
303
375
  renderData.link = renderLocations([op.metadata.source]);
@@ -432,16 +504,14 @@ const _fillRenderDataX = (
432
504
  case GateType.Group:
433
505
  {
434
506
  // Subtract startX offset from nested gates and add offset and padding
435
- let offset: number = x - startX + groupBoxPadding;
507
+ let offset: number = x - startX + groupPaddingX;
436
508
  if (renderData.type === GateType.ClassicalControlled)
437
509
  offset += controlBtnOffset;
438
510
 
439
511
  // Offset each x coord in children gates
440
512
  _offsetChildrenX(renderData.children, offset);
441
513
 
442
- // We don't use the centre x coord because we only care about the rightmost x for
443
- // rendering the box around the group of nested gates
444
- renderData.x = x;
514
+ renderData.x = x + columnWidths[colIndex] / 2;
445
515
  }
446
516
  break;
447
517
 
@@ -11,8 +11,8 @@ import {
11
11
  CircuitGroup,
12
12
  ComponentGrid,
13
13
  Operation,
14
- Column,
15
14
  SourceLocation,
15
+ Qubit,
16
16
  } from "./circuit.js";
17
17
  import { GateRenderData } from "./gateRenderData.js";
18
18
  import {
@@ -24,6 +24,7 @@ import {
24
24
  import { createDropzones } from "./draggable.js";
25
25
  import { enableEvents } from "./events.js";
26
26
  import { createPanel, enableRunButton } from "./panel.js";
27
+ import { getMinMaxRegIdx } from "./utils.js";
27
28
 
28
29
  /**
29
30
  * Contains render data for visualization.
@@ -115,28 +116,11 @@ export class Sqore {
115
116
  ),
116
117
  );
117
118
 
118
- // Render operations starting at given depth
119
- _circuit.componentGrid = this.selectOpsAtDepth(
120
- _circuit.componentGrid,
121
- this.renderDepth,
122
- );
119
+ // Expand operations to the specified render depth
120
+ this.expandOperationsToDepth(_circuit.componentGrid, this.renderDepth);
123
121
 
124
- // If only one top-level operation, expand automatically:
125
- if (
126
- _circuit.componentGrid.length == 1 &&
127
- _circuit.componentGrid[0].components.length == 1 &&
128
- _circuit.componentGrid[0].components[0].dataAttributes != null &&
129
- Object.prototype.hasOwnProperty.call(
130
- _circuit.componentGrid[0].components[0].dataAttributes,
131
- "location",
132
- ) &&
133
- _circuit.componentGrid[0].components[0].dataAttributes["expanded"] !==
134
- "false"
135
- ) {
136
- const location: string =
137
- _circuit.componentGrid[0].components[0].dataAttributes["location"];
138
- this.expandOperation(_circuit.componentGrid, location);
139
- }
122
+ // Auto-expand any groups with single children
123
+ this.expandIfSingleOperation(_circuit.componentGrid);
140
124
 
141
125
  // Create visualization components
142
126
  const composedSqore: ComposedSqore = this.compose(_circuit);
@@ -169,6 +153,50 @@ export class Sqore {
169
153
  }
170
154
  }
171
155
 
156
+ private expandOperationsToDepth(
157
+ componentGrid: ComponentGrid,
158
+ targetDepth: number,
159
+ currentDepth: number = 0,
160
+ ) {
161
+ for (const col of componentGrid) {
162
+ for (const op of col.components) {
163
+ if (currentDepth < targetDepth && op.children != null) {
164
+ op.conditionalRender = ConditionalRender.AsGroup;
165
+ op.dataAttributes = op.dataAttributes || {};
166
+ op.dataAttributes["expanded"] = "true";
167
+ this.expandOperationsToDepth(
168
+ op.children,
169
+ targetDepth,
170
+ currentDepth + 1,
171
+ );
172
+ }
173
+ }
174
+ }
175
+ }
176
+
177
+ private expandIfSingleOperation(grid: ComponentGrid) {
178
+ if (grid.length == 1 && grid[0].components.length == 1) {
179
+ const onlyComponent = grid[0].components[0];
180
+ if (
181
+ onlyComponent.dataAttributes != null &&
182
+ Object.prototype.hasOwnProperty.call(
183
+ onlyComponent.dataAttributes,
184
+ "location",
185
+ ) &&
186
+ onlyComponent.dataAttributes["expanded"] !== "false"
187
+ ) {
188
+ const location: string = onlyComponent.dataAttributes["location"];
189
+ this.expandOperation(grid, location);
190
+ }
191
+ }
192
+ // Recursively expand if the only child is also a single operation
193
+ for (const col of grid) {
194
+ for (const op of col.components) {
195
+ this.expandIfSingleOperation(op.children || []);
196
+ }
197
+ }
198
+ }
199
+
172
200
  /**
173
201
  * Sets the viewBox attribute of the SVG element to enable zooming and panning.
174
202
  *
@@ -208,15 +236,33 @@ export class Sqore {
208
236
  };
209
237
 
210
238
  const { qubits, componentGrid } = circuit;
211
- const { qubitWires, registers, svgHeight } = formatInputs(
239
+
240
+ // Calculate the row heights, which may vary depending on how many
241
+ // expanded group borders need to fit between qubit wires.
242
+ const rowHeights = getRowHeights(qubits, componentGrid);
243
+
244
+ // Draw the qubit labels.
245
+ // Also calculate other register render data to be used later in the rendering.
246
+ const { qubitLabels, registers, svgHeight } = formatInputs(
212
247
  qubits,
248
+ rowHeights,
213
249
  this.options.isEditable ? undefined : this.options.renderLocations,
214
250
  );
251
+
252
+ // Calculate the render data for the operations.
253
+ const topY = qubits[0] ? registers[qubits[0].id].y : -1;
254
+ const bottomY = qubits[qubits.length - 1]
255
+ ? registers[qubits[qubits.length - 1].id].y
256
+ : -1;
215
257
  const { renderDataArray, svgWidth } = processOperations(
216
258
  componentGrid,
259
+ topY,
260
+ bottomY,
217
261
  registers,
218
262
  this.options.isEditable ? undefined : this.options.renderLocations,
219
263
  );
264
+
265
+ // Draw the operations.
220
266
  const formattedGates: SVGElement = formatGates(renderDataArray);
221
267
 
222
268
  // Draw the lines that represent qubit and classical wires.
@@ -229,7 +275,7 @@ export class Sqore {
229
275
  const composedSqore: ComposedSqore = {
230
276
  width: svgWidth,
231
277
  height: svgHeight,
232
- elements: [qubitWires, formattedRegs, formattedGates],
278
+ elements: [qubitLabels, formattedRegs, formattedGates],
233
279
  };
234
280
  return composedSqore;
235
281
  }
@@ -300,53 +346,6 @@ export class Sqore {
300
346
  ).toString();
301
347
  }
302
348
 
303
- /**
304
- * Pick out operations that are at or below `renderDepth`.
305
- *
306
- * @param componentGrid Circuit components.
307
- * @param renderDepth Initial layer depth at which to render gates.
308
- *
309
- * @returns Grid of components at or below specified depth.
310
- */
311
- private selectOpsAtDepth(
312
- componentGrid: ComponentGrid,
313
- renderDepth: number,
314
- ): ComponentGrid {
315
- if (renderDepth < 0)
316
- throw new Error(
317
- `Invalid renderDepth of ${renderDepth}. Needs to be >= 0.`,
318
- );
319
- if (renderDepth === 0) return componentGrid;
320
- const selectedOps: ComponentGrid = [];
321
- componentGrid.forEach((col) => {
322
- const selectedCol: Operation[] = [];
323
- const extraCols: Column[] = [];
324
- col.components.forEach((op) => {
325
- if (op.children != null) {
326
- const selectedChildren = this.selectOpsAtDepth(
327
- op.children,
328
- renderDepth - 1,
329
- );
330
- if (selectedChildren.length > 0) {
331
- selectedCol.push(...selectedChildren[0].components);
332
- selectedChildren.slice(1).forEach((col, colIndex) => {
333
- if (extraCols[colIndex] == null) extraCols[colIndex] = col;
334
- // NOTE: I'm unsure if this is a safe way to combine column arrays
335
- else extraCols[colIndex].components.push(...col.components);
336
- });
337
- }
338
- } else {
339
- selectedCol.push(op);
340
- }
341
- });
342
- selectedOps.push({ components: selectedCol });
343
- if (extraCols.length > 0) {
344
- selectedOps.push(...extraCols);
345
- }
346
- });
347
- return selectedOps;
348
- }
349
-
350
349
  /**
351
350
  * Add interactive click handlers to circuit HTML elements.
352
351
  *
@@ -509,3 +508,92 @@ export class Sqore {
509
508
  operation.dataAttributes = undefined;
510
509
  };
511
510
  }
511
+
512
+ /**
513
+ * Recursively computes vertical space required to render group borders.
514
+ *
515
+ * The resulting `heightAboveWire` and `heightBelowWire` values per qubit are
516
+ * later used by `formatInputs` to leave sufficient space between qubit wires.
517
+ *
518
+ * @param qubits Array of qubits in the circuit.
519
+ * @param componentGrid Grid of circuit components to traverse.
520
+ *
521
+ * @returns Mapping from qubit index to required heights above and below their wires.
522
+ */
523
+ function getRowHeights(
524
+ qubits: Qubit[],
525
+ componentGrid: ComponentGrid,
526
+ ): {
527
+ [qubitIndex: number]: {
528
+ heightAboveWire: number;
529
+ heightBelowWire: number;
530
+ };
531
+ } {
532
+ const rowHeights: {
533
+ [qubitIndex: number]: {
534
+ currentGroupBordersAboveWire: number;
535
+ currentGroupBordersBelowWire: number;
536
+ heightAboveWire: number;
537
+ heightBelowWire: number;
538
+ };
539
+ } = {};
540
+
541
+ for (const q of qubits) {
542
+ const { id } = q;
543
+ rowHeights[id] = {
544
+ currentGroupBordersBelowWire: 0,
545
+ currentGroupBordersAboveWire: 0,
546
+ heightBelowWire: 0,
547
+ heightAboveWire: 0,
548
+ };
549
+ }
550
+
551
+ updateRowHeights(componentGrid, rowHeights, qubits.length);
552
+ return rowHeights;
553
+ }
554
+
555
+ function updateRowHeights(
556
+ componentGrid: ComponentGrid,
557
+ rowHeights: {
558
+ [qubitIndex: number]: {
559
+ currentGroupBordersAboveWire: number;
560
+ currentGroupBordersBelowWire: number;
561
+ heightAboveWire: number;
562
+ heightBelowWire: number;
563
+ };
564
+ },
565
+ numQubits: number,
566
+ ) {
567
+ for (const col of componentGrid) {
568
+ for (const component of col.components) {
569
+ if (component.dataAttributes?.["expanded"] === "true") {
570
+ // We're in an expanded group. There is a dashed border above
571
+ // the top qubit, and below the bottom qubit.
572
+ const [topQubit, bottomQubit] = getMinMaxRegIdx(component, numQubits);
573
+
574
+ // Increment the current count of dashed group borders for
575
+ // the top and bottom rows for this operation.
576
+ // If the max height for this row has been exceeded above or below the wire,
577
+ // update it.
578
+ rowHeights[topQubit].currentGroupBordersAboveWire++;
579
+ rowHeights[topQubit].heightAboveWire = Math.max(
580
+ rowHeights[topQubit].heightAboveWire,
581
+ rowHeights[topQubit].currentGroupBordersAboveWire,
582
+ );
583
+
584
+ rowHeights[bottomQubit].currentGroupBordersBelowWire++;
585
+ rowHeights[bottomQubit].heightBelowWire = Math.max(
586
+ rowHeights[bottomQubit].heightBelowWire,
587
+ rowHeights[bottomQubit].currentGroupBordersBelowWire,
588
+ );
589
+
590
+ // recurse
591
+ updateRowHeights(component.children || [], rowHeights, numQubits);
592
+
593
+ // decrement
594
+ rowHeights[topQubit].currentGroupBordersAboveWire--;
595
+ rowHeights[bottomQubit].currentGroupBordersBelowWire--;
596
+ }
597
+ }
598
+ }
599
+ }
@@ -4,7 +4,7 @@
4
4
  import { GateRenderData, GateType } from "./gateRenderData.js";
5
5
  import {
6
6
  minGateWidth,
7
- labelPadding,
7
+ labelPaddingX,
8
8
  labelFontSize,
9
9
  argsFontSize,
10
10
  } from "./constants.js";
@@ -52,18 +52,15 @@ const deepEqual = (obj1: unknown, obj2: unknown): boolean => {
52
52
  /**
53
53
  * Calculate the width of a gate, given its render data.
54
54
  *
55
- * @param renderData - The rendering data of the gate, including its type, label, display arguments, and width.
55
+ * @param renderData - The rendering data of the gate, including its type, label, display arguments.
56
56
  *
57
57
  * @returns Width of given gate (in pixels).
58
58
  */
59
- const getGateWidth = ({
59
+ const getMinGateWidth = ({
60
60
  type,
61
61
  label,
62
62
  displayArgs,
63
- width,
64
63
  }: GateRenderData): number => {
65
- if (width > 0) return width;
66
-
67
64
  switch (type) {
68
65
  case GateType.Measure:
69
66
  case GateType.Cnot:
@@ -73,31 +70,73 @@ const getGateWidth = ({
73
70
  const labelWidth = _getStringWidth(label);
74
71
  const argsWidth =
75
72
  displayArgs != null ? _getStringWidth(displayArgs, argsFontSize) : 0;
76
- const textWidth = Math.max(labelWidth, argsWidth) + labelPadding * 2;
73
+ const textWidth = Math.max(labelWidth, argsWidth) + labelPaddingX * 2;
77
74
  return Math.max(minGateWidth, textWidth);
78
75
  }
79
76
  }
80
77
  };
81
78
 
82
79
  /**
83
- * Get the width of a string with font-size `fontSize` and font-family Arial.
80
+ * Estimate string width in pixels based on character types and font size.
81
+ * This may not match the true rendered width, but should be close enough for
82
+ * calculating layout.
84
83
  *
85
- * @param text Input string.
86
- * @param fontSize Font size of `text`.
84
+ * @param text - The text string to measure.
85
+ * @param fontSize - The font size in pixels (default is labelFontSize).
87
86
  *
88
- * @returns Pixel width of given string.
87
+ * @returns Estimated width of the string in pixels.
89
88
  */
90
89
  const _getStringWidth = (
91
90
  text: string,
92
91
  fontSize: number = labelFontSize,
93
92
  ): number => {
94
- const canvas: HTMLCanvasElement = document.createElement("canvas");
95
- const context: CanvasRenderingContext2D | null = canvas.getContext("2d");
96
- if (context == null) throw new Error("Null canvas");
97
-
98
- context.font = `${fontSize}px Arial`;
99
- const metrics: TextMetrics = context.measureText(text);
100
- return metrics.width;
93
+ let units = 0;
94
+ for (const ch of Array.from(text)) {
95
+ if (ch === " ") {
96
+ units += 0.33;
97
+ continue;
98
+ }
99
+ if ("il.:;,'`!|".includes(ch)) {
100
+ units += 0.28;
101
+ continue;
102
+ }
103
+ if ("mw".includes(ch)) {
104
+ units += 0.72;
105
+ continue;
106
+ }
107
+ if ("MW@#%&".includes(ch)) {
108
+ units += 0.78;
109
+ continue;
110
+ }
111
+ if (/[0-9]/.test(ch)) {
112
+ units += 0.55;
113
+ continue;
114
+ }
115
+ if (/[A-Z]/.test(ch)) {
116
+ units += 0.56;
117
+ continue;
118
+ }
119
+ if (/[a-z]/.test(ch)) {
120
+ units += 0.5;
121
+ continue;
122
+ }
123
+ if (/[θπ]/.test(ch)) {
124
+ units += 0.56;
125
+ continue;
126
+ }
127
+ if (/[ψ]/.test(ch)) {
128
+ units += 0.6;
129
+ continue;
130
+ }
131
+ if ("-+*/=^~_<>".includes(ch)) {
132
+ units += 0.5;
133
+ continue;
134
+ }
135
+ units += 0.56;
136
+ }
137
+ const kerningFudge = Math.max(0, text.length - 1) * 0.005;
138
+ // Round to a whole number to keep it easy to read
139
+ return Math.floor((units + kerningFudge) * fontSize);
101
140
  };
102
141
 
103
142
  /**
@@ -426,7 +465,7 @@ const mathChars = {
426
465
 
427
466
  export {
428
467
  deepEqual,
429
- getGateWidth,
468
+ getMinGateWidth,
430
469
  getChildTargets,
431
470
  locationStringToIndexes,
432
471
  getGateLocationString,
package/ux/circuit.tsx CHANGED
@@ -361,7 +361,7 @@ function renderLocations(locations: SourceLocation[]) {
361
361
  });
362
362
  const title = titles.length > 1 ? `${titles[0]}, ...` : titles[0];
363
363
 
364
- const argsStr = encodeURIComponent(JSON.stringify([qdkLocations]));
364
+ const argsStr = encodeURI(encodeURIComponent(JSON.stringify([qdkLocations])));
365
365
  const href = `command:qsharp-vscode.gotoLocations?${argsStr}`;
366
366
  return {
367
367
  title,
@@ -55,7 +55,7 @@ export function EstimatesPanel(props: {
55
55
  {props.calculating ? (
56
56
  <Spinner style="position: absolute; top: 11px; left: 4px;" />
57
57
  ) : null}
58
- <h1>Azure Quantum Resource Estimator</h1>
58
+ <h1>Microsoft Quantum Resource Estimator</h1>
59
59
  </div>
60
60
  <EstimatesOverview
61
61
  estimatesData={props.estimatesData}