qsharp-lang 1.15.4-dev → 1.16.1-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 (326) hide show
  1. package/dist/browser.d.ts +2 -2
  2. package/dist/compiler/compiler.d.ts +3 -1
  3. package/dist/compiler/compiler.js +5 -1
  4. package/dist/samples.generated.js +1 -1
  5. package/dist/utils.d.ts +8 -0
  6. package/dist/utils.js +22 -8
  7. package/docs/Microsoft.Quantum.Core/Length.md +1 -1
  8. package/docs/Microsoft.Quantum.Core/Repeated.md +1 -1
  9. package/docs/Microsoft.Quantum.Core/index.md +1 -1
  10. package/docs/Std.Arithmetic/AddLE.md +1 -1
  11. package/docs/Std.Arithmetic/ApplyIfEqualL.md +1 -1
  12. package/docs/Std.Arithmetic/ApplyIfEqualLE.md +1 -1
  13. package/docs/Std.Arithmetic/ApplyIfGreaterL.md +1 -1
  14. package/docs/Std.Arithmetic/ApplyIfGreaterLE.md +1 -1
  15. package/docs/Std.Arithmetic/ApplyIfGreaterOrEqualL.md +1 -1
  16. package/docs/Std.Arithmetic/ApplyIfGreaterOrEqualLE.md +1 -1
  17. package/docs/Std.Arithmetic/ApplyIfLessL.md +1 -1
  18. package/docs/Std.Arithmetic/ApplyIfLessLE.md +1 -1
  19. package/docs/Std.Arithmetic/ApplyIfLessOrEqualL.md +1 -1
  20. package/docs/Std.Arithmetic/ApplyIfLessOrEqualLE.md +1 -1
  21. package/docs/Std.Arithmetic/FourierTDIncByLE.md +1 -1
  22. package/docs/Std.Arithmetic/IncByI.md +1 -1
  23. package/docs/Std.Arithmetic/IncByIUsingIncByLE.md +1 -1
  24. package/docs/Std.Arithmetic/IncByL.md +1 -1
  25. package/docs/Std.Arithmetic/IncByLE.md +1 -1
  26. package/docs/Std.Arithmetic/IncByLEUsingAddLE.md +1 -1
  27. package/docs/Std.Arithmetic/IncByLUsingIncByLE.md +1 -1
  28. package/docs/Std.Arithmetic/LookAheadDKRSAddLE.md +1 -1
  29. package/docs/Std.Arithmetic/MAJ.md +1 -1
  30. package/docs/Std.Arithmetic/ReflectAboutInteger.md +1 -1
  31. package/docs/Std.Arithmetic/RippleCarryCGAddLE.md +1 -1
  32. package/docs/Std.Arithmetic/RippleCarryCGIncByLE.md +1 -1
  33. package/docs/Std.Arithmetic/RippleCarryTTKIncByLE.md +1 -1
  34. package/docs/Std.Arithmetic/index.md +1 -1
  35. package/docs/Std.Arrays/All.md +1 -1
  36. package/docs/Std.Arrays/Any.md +1 -1
  37. package/docs/Std.Arrays/Chunks.md +1 -1
  38. package/docs/Std.Arrays/CircularlyShifted.md +1 -1
  39. package/docs/Std.Arrays/ColumnAt.md +1 -1
  40. package/docs/Std.Arrays/Count.md +1 -1
  41. package/docs/Std.Arrays/Diagonal.md +1 -1
  42. package/docs/Std.Arrays/DrawMany.md +1 -1
  43. package/docs/Std.Arrays/Enumerated.md +1 -1
  44. package/docs/Std.Arrays/Excluding.md +1 -1
  45. package/docs/Std.Arrays/Filtered.md +1 -1
  46. package/docs/Std.Arrays/FlatMapped.md +1 -1
  47. package/docs/Std.Arrays/Flattened.md +1 -1
  48. package/docs/Std.Arrays/Fold.md +1 -1
  49. package/docs/Std.Arrays/ForEach.md +1 -1
  50. package/docs/Std.Arrays/Head.md +1 -1
  51. package/docs/Std.Arrays/HeadAndRest.md +1 -1
  52. package/docs/Std.Arrays/IndexOf.md +1 -1
  53. package/docs/Std.Arrays/IndexRange.md +1 -1
  54. package/docs/Std.Arrays/Interleaved.md +1 -1
  55. package/docs/Std.Arrays/IsEmpty.md +1 -1
  56. package/docs/Std.Arrays/IsRectangularArray.md +1 -1
  57. package/docs/Std.Arrays/IsSorted.md +1 -1
  58. package/docs/Std.Arrays/IsSquareArray.md +1 -1
  59. package/docs/Std.Arrays/Mapped.md +1 -1
  60. package/docs/Std.Arrays/MappedByIndex.md +1 -1
  61. package/docs/Std.Arrays/MappedOverRange.md +1 -1
  62. package/docs/Std.Arrays/Most.md +1 -1
  63. package/docs/Std.Arrays/MostAndTail.md +1 -1
  64. package/docs/Std.Arrays/Padded.md +1 -1
  65. package/docs/Std.Arrays/Partitioned.md +1 -1
  66. package/docs/Std.Arrays/Rest.md +1 -1
  67. package/docs/Std.Arrays/Reversed.md +1 -1
  68. package/docs/Std.Arrays/SequenceI.md +1 -1
  69. package/docs/Std.Arrays/SequenceL.md +1 -1
  70. package/docs/Std.Arrays/Sorted.md +1 -1
  71. package/docs/Std.Arrays/Subarray.md +1 -1
  72. package/docs/Std.Arrays/Swapped.md +1 -1
  73. package/docs/Std.Arrays/Tail.md +1 -1
  74. package/docs/Std.Arrays/Transposed.md +1 -1
  75. package/docs/Std.Arrays/Unzipped.md +1 -1
  76. package/docs/Std.Arrays/Where.md +1 -1
  77. package/docs/Std.Arrays/Windows.md +1 -1
  78. package/docs/Std.Arrays/Zipped.md +1 -1
  79. package/docs/Std.Arrays/index.md +1 -1
  80. package/docs/Std.Canon/ApplyCNOTChain.md +1 -1
  81. package/docs/Std.Canon/ApplyControlledOnBitString.md +1 -1
  82. package/docs/Std.Canon/ApplyControlledOnInt.md +1 -1
  83. package/docs/Std.Canon/ApplyOperationPowerA.md +1 -1
  84. package/docs/Std.Canon/ApplyP.md +1 -1
  85. package/docs/Std.Canon/ApplyPauli.md +1 -1
  86. package/docs/Std.Canon/ApplyPauliFromBitString.md +1 -1
  87. package/docs/Std.Canon/ApplyPauliFromInt.md +1 -1
  88. package/docs/Std.Canon/ApplyQFT.md +1 -1
  89. package/docs/Std.Canon/ApplyToEach.md +1 -1
  90. package/docs/Std.Canon/ApplyToEachA.md +1 -1
  91. package/docs/Std.Canon/ApplyToEachC.md +1 -1
  92. package/docs/Std.Canon/ApplyToEachCA.md +1 -1
  93. package/docs/Std.Canon/ApplyXorInPlace.md +1 -1
  94. package/docs/Std.Canon/ApplyXorInPlaceL.md +1 -1
  95. package/docs/Std.Canon/CX.md +1 -1
  96. package/docs/Std.Canon/CY.md +1 -1
  97. package/docs/Std.Canon/CZ.md +1 -1
  98. package/docs/Std.Canon/Fst.md +1 -1
  99. package/docs/Std.Canon/Relabel.md +1 -1
  100. package/docs/Std.Canon/Snd.md +1 -1
  101. package/docs/Std.Canon/SwapReverseRegister.md +1 -1
  102. package/docs/Std.Canon/index.md +1 -1
  103. package/docs/Std.Convert/BigIntAsBoolArray.md +1 -1
  104. package/docs/Std.Convert/BigIntAsInt.md +1 -1
  105. package/docs/Std.Convert/BoolArrayAsBigInt.md +1 -1
  106. package/docs/Std.Convert/BoolArrayAsInt.md +1 -1
  107. package/docs/Std.Convert/BoolArrayAsResultArray.md +1 -1
  108. package/docs/Std.Convert/BoolAsResult.md +1 -1
  109. package/docs/Std.Convert/ComplexAsComplexPolar.md +1 -1
  110. package/docs/Std.Convert/ComplexPolarAsComplex.md +1 -1
  111. package/docs/Std.Convert/DoubleAsStringWithPrecision.md +1 -1
  112. package/docs/Std.Convert/IntAsBigInt.md +1 -1
  113. package/docs/Std.Convert/IntAsBoolArray.md +1 -1
  114. package/docs/Std.Convert/IntAsDouble.md +1 -1
  115. package/docs/Std.Convert/ResultArrayAsBoolArray.md +1 -1
  116. package/docs/Std.Convert/ResultArrayAsInt.md +1 -1
  117. package/docs/Std.Convert/ResultAsBool.md +1 -1
  118. package/docs/Std.Convert/index.md +1 -1
  119. package/docs/Std.Core/Length.md +1 -1
  120. package/docs/Std.Core/Repeated.md +1 -1
  121. package/docs/Std.Core/index.md +1 -1
  122. package/docs/Std.Diagnostics/ApplyIdleNoise.md +1 -1
  123. package/docs/Std.Diagnostics/BitFlipNoise.md +1 -1
  124. package/docs/Std.Diagnostics/CheckAllZero.md +1 -1
  125. package/docs/Std.Diagnostics/CheckOperationsAreEqual.md +1 -1
  126. package/docs/Std.Diagnostics/CheckZero.md +1 -1
  127. package/docs/Std.Diagnostics/ConfigurePauliNoise.md +1 -1
  128. package/docs/Std.Diagnostics/DepolarizingNoise.md +1 -1
  129. package/docs/Std.Diagnostics/DumpMachine.md +1 -1
  130. package/docs/Std.Diagnostics/DumpOperation.md +1 -1
  131. package/docs/Std.Diagnostics/DumpRegister.md +1 -1
  132. package/docs/Std.Diagnostics/Fact.md +1 -1
  133. package/docs/Std.Diagnostics/NoNoise.md +1 -1
  134. package/docs/Std.Diagnostics/PhaseFlipNoise.md +1 -1
  135. package/docs/Std.Diagnostics/StartCountingFunction.md +1 -1
  136. package/docs/Std.Diagnostics/StartCountingOperation.md +1 -1
  137. package/docs/Std.Diagnostics/StartCountingQubits.md +1 -1
  138. package/docs/Std.Diagnostics/StopCountingFunction.md +1 -1
  139. package/docs/Std.Diagnostics/StopCountingOperation.md +1 -1
  140. package/docs/Std.Diagnostics/StopCountingQubits.md +1 -1
  141. package/docs/Std.Diagnostics/index.md +1 -1
  142. package/docs/Std.Intrinsic/AND.md +1 -1
  143. package/docs/Std.Intrinsic/ApplyUnitary.md +1 -1
  144. package/docs/Std.Intrinsic/CCNOT.md +1 -1
  145. package/docs/Std.Intrinsic/CNOT.md +1 -1
  146. package/docs/Std.Intrinsic/Exp.md +1 -1
  147. package/docs/Std.Intrinsic/H.md +1 -1
  148. package/docs/Std.Intrinsic/I.md +1 -1
  149. package/docs/Std.Intrinsic/M.md +1 -1
  150. package/docs/Std.Intrinsic/Measure.md +1 -1
  151. package/docs/Std.Intrinsic/Message.md +1 -1
  152. package/docs/Std.Intrinsic/R.md +1 -1
  153. package/docs/Std.Intrinsic/R1.md +1 -1
  154. package/docs/Std.Intrinsic/R1Frac.md +1 -1
  155. package/docs/Std.Intrinsic/RFrac.md +1 -1
  156. package/docs/Std.Intrinsic/Reset.md +1 -1
  157. package/docs/Std.Intrinsic/ResetAll.md +1 -1
  158. package/docs/Std.Intrinsic/Rx.md +1 -1
  159. package/docs/Std.Intrinsic/Rxx.md +1 -1
  160. package/docs/Std.Intrinsic/Ry.md +1 -1
  161. package/docs/Std.Intrinsic/Ryy.md +1 -1
  162. package/docs/Std.Intrinsic/Rz.md +1 -1
  163. package/docs/Std.Intrinsic/Rzz.md +1 -1
  164. package/docs/Std.Intrinsic/S.md +1 -1
  165. package/docs/Std.Intrinsic/SWAP.md +1 -1
  166. package/docs/Std.Intrinsic/SX.md +38 -0
  167. package/docs/Std.Intrinsic/T.md +1 -1
  168. package/docs/Std.Intrinsic/X.md +1 -1
  169. package/docs/Std.Intrinsic/Y.md +1 -1
  170. package/docs/Std.Intrinsic/Z.md +1 -1
  171. package/docs/Std.Intrinsic/index.md +2 -1
  172. package/docs/Std.Logical/Xor.md +1 -1
  173. package/docs/Std.Logical/index.md +1 -1
  174. package/docs/Std.Math/AbsComplex.md +1 -1
  175. package/docs/Std.Math/AbsComplexPolar.md +1 -1
  176. package/docs/Std.Math/AbsD.md +1 -1
  177. package/docs/Std.Math/AbsI.md +1 -1
  178. package/docs/Std.Math/AbsL.md +1 -1
  179. package/docs/Std.Math/AbsSquaredComplex.md +1 -1
  180. package/docs/Std.Math/AbsSquaredComplexPolar.md +1 -1
  181. package/docs/Std.Math/ApproximateFactorial.md +1 -1
  182. package/docs/Std.Math/ArcCos.md +1 -1
  183. package/docs/Std.Math/ArcCosh.md +1 -1
  184. package/docs/Std.Math/ArcSin.md +1 -1
  185. package/docs/Std.Math/ArcSinh.md +1 -1
  186. package/docs/Std.Math/ArcTan.md +1 -1
  187. package/docs/Std.Math/ArcTan2.md +1 -1
  188. package/docs/Std.Math/ArcTanh.md +1 -1
  189. package/docs/Std.Math/ArgComplex.md +1 -1
  190. package/docs/Std.Math/ArgComplexPolar.md +1 -1
  191. package/docs/Std.Math/Binom.md +1 -1
  192. package/docs/Std.Math/BitSizeI.md +1 -1
  193. package/docs/Std.Math/BitSizeL.md +1 -1
  194. package/docs/Std.Math/Ceiling.md +1 -1
  195. package/docs/Std.Math/Complex.md +1 -1
  196. package/docs/Std.Math/ComplexPolar.md +1 -1
  197. package/docs/Std.Math/ContinuedFractionConvergentI.md +1 -1
  198. package/docs/Std.Math/ContinuedFractionConvergentL.md +1 -1
  199. package/docs/Std.Math/Cos.md +1 -1
  200. package/docs/Std.Math/Cosh.md +1 -1
  201. package/docs/Std.Math/DivRemI.md +1 -1
  202. package/docs/Std.Math/DivRemL.md +1 -1
  203. package/docs/Std.Math/DividedByC.md +1 -1
  204. package/docs/Std.Math/DividedByCP.md +1 -1
  205. package/docs/Std.Math/E.md +1 -1
  206. package/docs/Std.Math/ExpModI.md +1 -1
  207. package/docs/Std.Math/ExpModL.md +1 -1
  208. package/docs/Std.Math/ExtendedGreatestCommonDivisorI.md +1 -1
  209. package/docs/Std.Math/ExtendedGreatestCommonDivisorL.md +1 -1
  210. package/docs/Std.Math/FactorialI.md +1 -1
  211. package/docs/Std.Math/FactorialL.md +1 -1
  212. package/docs/Std.Math/Floor.md +1 -1
  213. package/docs/Std.Math/GreatestCommonDivisorI.md +1 -1
  214. package/docs/Std.Math/GreatestCommonDivisorL.md +1 -1
  215. package/docs/Std.Math/HammingWeightI.md +1 -1
  216. package/docs/Std.Math/InverseModI.md +1 -1
  217. package/docs/Std.Math/InverseModL.md +1 -1
  218. package/docs/Std.Math/IsCoprimeI.md +1 -1
  219. package/docs/Std.Math/IsCoprimeL.md +1 -1
  220. package/docs/Std.Math/IsInfinite.md +1 -1
  221. package/docs/Std.Math/IsNaN.md +1 -1
  222. package/docs/Std.Math/LargestFixedPoint.md +1 -1
  223. package/docs/Std.Math/Lg.md +1 -1
  224. package/docs/Std.Math/Log.md +1 -1
  225. package/docs/Std.Math/Log10.md +1 -1
  226. package/docs/Std.Math/LogFactorialD.md +1 -1
  227. package/docs/Std.Math/LogGammaD.md +1 -1
  228. package/docs/Std.Math/LogOf2.md +1 -1
  229. package/docs/Std.Math/Max.md +1 -1
  230. package/docs/Std.Math/MaxD.md +1 -1
  231. package/docs/Std.Math/MaxI.md +1 -1
  232. package/docs/Std.Math/MaxL.md +1 -1
  233. package/docs/Std.Math/Min.md +1 -1
  234. package/docs/Std.Math/MinD.md +1 -1
  235. package/docs/Std.Math/MinI.md +1 -1
  236. package/docs/Std.Math/MinL.md +1 -1
  237. package/docs/Std.Math/MinusC.md +1 -1
  238. package/docs/Std.Math/MinusCP.md +1 -1
  239. package/docs/Std.Math/ModulusI.md +1 -1
  240. package/docs/Std.Math/ModulusL.md +1 -1
  241. package/docs/Std.Math/NegationC.md +1 -1
  242. package/docs/Std.Math/NegationCP.md +1 -1
  243. package/docs/Std.Math/PI.md +1 -1
  244. package/docs/Std.Math/PNorm.md +1 -1
  245. package/docs/Std.Math/PNormalized.md +1 -1
  246. package/docs/Std.Math/PlusC.md +1 -1
  247. package/docs/Std.Math/PlusCP.md +1 -1
  248. package/docs/Std.Math/PowC.md +1 -1
  249. package/docs/Std.Math/PowCP.md +1 -1
  250. package/docs/Std.Math/RealMod.md +1 -1
  251. package/docs/Std.Math/Round.md +1 -1
  252. package/docs/Std.Math/RoundHalfAwayFromZero.md +1 -1
  253. package/docs/Std.Math/SignD.md +1 -1
  254. package/docs/Std.Math/SignI.md +1 -1
  255. package/docs/Std.Math/SignL.md +1 -1
  256. package/docs/Std.Math/Sin.md +1 -1
  257. package/docs/Std.Math/Sinh.md +1 -1
  258. package/docs/Std.Math/SmallestFixedPoint.md +1 -1
  259. package/docs/Std.Math/Sqrt.md +1 -1
  260. package/docs/Std.Math/SquaredNorm.md +1 -1
  261. package/docs/Std.Math/Tan.md +1 -1
  262. package/docs/Std.Math/Tanh.md +1 -1
  263. package/docs/Std.Math/TimesC.md +1 -1
  264. package/docs/Std.Math/TimesCP.md +1 -1
  265. package/docs/Std.Math/TrailingZeroCountI.md +1 -1
  266. package/docs/Std.Math/TrailingZeroCountL.md +1 -1
  267. package/docs/Std.Math/Truncate.md +1 -1
  268. package/docs/Std.Math/index.md +1 -1
  269. package/docs/Std.Measurement/MResetEachZ.md +1 -1
  270. package/docs/Std.Measurement/MResetX.md +1 -1
  271. package/docs/Std.Measurement/MResetY.md +1 -1
  272. package/docs/Std.Measurement/MResetZ.md +1 -1
  273. package/docs/Std.Measurement/MeasureAllZ.md +1 -1
  274. package/docs/Std.Measurement/MeasureEachZ.md +1 -1
  275. package/docs/Std.Measurement/MeasureInteger.md +1 -1
  276. package/docs/Std.Measurement/index.md +1 -1
  277. package/docs/Std.Random/DrawRandomBool.md +1 -1
  278. package/docs/Std.Random/DrawRandomDouble.md +1 -1
  279. package/docs/Std.Random/DrawRandomInt.md +1 -1
  280. package/docs/Std.Random/index.md +1 -1
  281. package/docs/Std.Range/IsRangeEmpty.md +1 -1
  282. package/docs/Std.Range/RangeEnd.md +1 -1
  283. package/docs/Std.Range/RangeReverse.md +1 -1
  284. package/docs/Std.Range/RangeStart.md +1 -1
  285. package/docs/Std.Range/RangeStep.md +1 -1
  286. package/docs/Std.Range/index.md +1 -1
  287. package/docs/Std.ResourceEstimation/AccountForEstimates.md +1 -1
  288. package/docs/Std.ResourceEstimation/AuxQubitCount.md +1 -1
  289. package/docs/Std.ResourceEstimation/BeginEstimateCaching.md +1 -1
  290. package/docs/Std.ResourceEstimation/BeginRepeatEstimates.md +1 -1
  291. package/docs/Std.ResourceEstimation/CczCount.md +1 -1
  292. package/docs/Std.ResourceEstimation/EndEstimateCaching.md +1 -1
  293. package/docs/Std.ResourceEstimation/EndRepeatEstimates.md +1 -1
  294. package/docs/Std.ResourceEstimation/MeasurementCount.md +1 -1
  295. package/docs/Std.ResourceEstimation/PSSPCLayout.md +1 -1
  296. package/docs/Std.ResourceEstimation/RepeatEstimates.md +1 -1
  297. package/docs/Std.ResourceEstimation/RotationCount.md +1 -1
  298. package/docs/Std.ResourceEstimation/RotationDepth.md +1 -1
  299. package/docs/Std.ResourceEstimation/SingleVariant.md +1 -1
  300. package/docs/Std.ResourceEstimation/TCount.md +1 -1
  301. package/docs/Std.ResourceEstimation/index.md +1 -1
  302. package/docs/Std.StatePreparation/ApproximatelyPreparePureStateCP.md +1 -1
  303. package/docs/Std.StatePreparation/PreparePureStateD.md +1 -1
  304. package/docs/Std.StatePreparation/PrepareUniformSuperposition.md +1 -1
  305. package/docs/Std.StatePreparation/index.md +1 -1
  306. package/docs/Std.TableLookup/Select.md +1 -1
  307. package/docs/Std.TableLookup/index.md +1 -1
  308. package/docs/index.md +1 -1
  309. package/docs/toc.yml +1 -0
  310. package/lib/node/qsc_wasm.cjs +22 -4
  311. package/lib/node/qsc_wasm.d.cts +10 -0
  312. package/lib/node/qsc_wasm_bg.wasm +0 -0
  313. package/lib/web/qsc_wasm.d.ts +11 -0
  314. package/lib/web/qsc_wasm.js +21 -4
  315. package/lib/web/qsc_wasm_bg.wasm +0 -0
  316. package/package.json +1 -1
  317. package/ux/circuit-vis/circuitManipulation.ts +145 -48
  318. package/ux/circuit-vis/contextMenu.ts +1 -1
  319. package/ux/circuit-vis/draggable.ts +288 -112
  320. package/ux/circuit-vis/events.ts +433 -199
  321. package/ux/circuit-vis/formatters/inputFormatter.ts +9 -4
  322. package/ux/circuit-vis/panel.ts +37 -34
  323. package/ux/circuit-vis/process.ts +1 -1
  324. package/ux/circuit-vis/sqore.ts +2 -2
  325. package/ux/circuit-vis/utils.ts +17 -1
  326. package/ux/qsharp-circuit.css +2 -35
@@ -66,7 +66,7 @@ const addContextMenuToHostElem = (
66
66
  const removeControlOption = _createContextMenuItem(
67
67
  "Remove control",
68
68
  () => {
69
- removeControl(selectedOperation, dataWire);
69
+ removeControl(circuitEvents, selectedOperation, dataWire);
70
70
  circuitEvents.renderFn();
71
71
  },
72
72
  );
@@ -3,9 +3,16 @@
3
3
 
4
4
  import { getMinMaxRegIdx } from "../../src/utils";
5
5
  import { ComponentGrid, Operation } from "./circuit";
6
- import { gatePadding, minGateWidth, startX } from "./constants";
7
- import { box, controlDot } from "./formatters/formatUtils";
6
+ import {
7
+ gatePadding,
8
+ minGateWidth,
9
+ registerHeight,
10
+ regLineStart,
11
+ startX,
12
+ } from "./constants";
13
+ import { box, controlDot, line } from "./formatters/formatUtils";
8
14
  import { formatGate } from "./formatters/gateFormatter";
15
+ import { qubitInput } from "./formatters/inputFormatter";
9
16
  import { toRenderData } from "./panel";
10
17
  import { Sqore } from "./sqore";
11
18
  import {
@@ -18,28 +25,29 @@ import {
18
25
 
19
26
  interface Context {
20
27
  container: HTMLElement;
28
+ svg: SVGElement;
21
29
  operationGrid: ComponentGrid;
22
30
  wireData: number[];
23
- paddingY: number;
24
31
  }
25
32
 
26
33
  /**
27
- * Create dragzones elements for dragging on circuit.
34
+ * Create dropzones elements for dragging on circuit.
28
35
  *
29
36
  * @param container HTML element for rendering visualization into
30
37
  * @param sqore Sqore object
31
38
  */
32
- const createDragzones = (container: HTMLElement, sqore: Sqore): void => {
39
+ const createDropzones = (container: HTMLElement, sqore: Sqore): void => {
33
40
  const svg = container.querySelector("svg[id]") as SVGElement;
34
41
 
35
42
  const context: Context = {
36
43
  container,
44
+ svg,
37
45
  operationGrid: sqore.circuit.componentGrid,
38
46
  wireData: getWireData(container),
39
- paddingY: 20,
40
47
  };
41
48
  _addStyles(container, getWireData(container));
42
49
  _addDataWires(container);
50
+ svg.appendChild(_ghostQubitLayer(context));
43
51
  svg.appendChild(_dropzoneLayer(context));
44
52
  };
45
53
 
@@ -51,7 +59,7 @@ const createDragzones = (container: HTMLElement, sqore: Sqore): void => {
51
59
  * @param selectedOperation The operation that is being dragged.
52
60
  * @param isControl A boolean indicating if the ghost element is for a control operation.
53
61
  */
54
- const createGhostElement = (
62
+ const createGateGhost = (
55
63
  ev: MouseEvent,
56
64
  container: HTMLElement,
57
65
  selectedOperation: Operation,
@@ -64,6 +72,63 @@ const createGhostElement = (
64
72
  return formatGate(ghostRenderData).cloneNode(true) as SVGElement;
65
73
  })();
66
74
 
75
+ _createGhostElement(container, ev, ghost, isControl);
76
+ };
77
+
78
+ /**
79
+ * Creates a ghost element for dragging a qubit line label.
80
+ *
81
+ * @param ev The mouse event that triggered the drag.
82
+ * @param container The HTML container element where the ghost will be appended.
83
+ * @param labelElem The SVGTextElement representing the qubit label to be cloned (including any tspans or formatting).
84
+ */
85
+ const createQubitLabelGhost = (
86
+ ev: MouseEvent,
87
+ container: HTMLElement,
88
+ labelElem: SVGTextElement,
89
+ ) => {
90
+ const ghostGate: Operation = {
91
+ kind: "unitary",
92
+ gate: "?", // This will be replaced by the label elem
93
+ targets: [],
94
+ };
95
+ const ghostRenderData = toRenderData(ghostGate, 0, 0);
96
+ const ghost = formatGate(ghostRenderData) as SVGElement;
97
+
98
+ // Replace the placeholder text with the label element
99
+ const placeholderText = ghost.querySelector(".qs-maintext");
100
+ if (placeholderText) {
101
+ // Remove all children from placeholderText
102
+ while (placeholderText.firstChild) {
103
+ placeholderText.removeChild(placeholderText.firstChild);
104
+ }
105
+ // Clone and append each child from labelElem
106
+ for (const child of Array.from(labelElem.childNodes)) {
107
+ placeholderText.appendChild(child.cloneNode(true));
108
+ }
109
+ placeholderText.setAttribute(
110
+ "font-size",
111
+ labelElem.getAttribute("font-size") || "16",
112
+ );
113
+ }
114
+
115
+ _createGhostElement(container, ev, ghost, false);
116
+ };
117
+
118
+ /**
119
+ * Creates and appends a draggable "ghost" element to the DOM for visual feedback during drag operations.
120
+ *
121
+ * @param container The HTML container element to which the ghost element will be appended.
122
+ * @param ev The MouseEvent that triggered the drag, used to position the ghost.
123
+ * @param ghost The SVGElement representing the visual ghost to be dragged.
124
+ * @param isControl Boolean indicating if the ghost is for a control operation (affects sizing).
125
+ */
126
+ const _createGhostElement = (
127
+ container: HTMLElement,
128
+ ev: MouseEvent,
129
+ ghost: SVGElement,
130
+ isControl: boolean,
131
+ ) => {
67
132
  // Generate svg element to wrap around ghost element
68
133
  const svgElem = document.createElementNS("http://www.w3.org/2000/svg", "svg");
69
134
  svgElem.append(ghost);
@@ -92,7 +157,16 @@ const createGhostElement = (
92
157
 
93
158
  updateDivLeftTop(ev);
94
159
 
160
+ const cleanup = () => {
161
+ container.removeEventListener("mousemove", updateDivLeftTop);
162
+ document.removeEventListener("mouseup", cleanup);
163
+ if (divElem.parentNode) {
164
+ divElem.parentNode.removeChild(divElem);
165
+ }
166
+ };
167
+
95
168
  container.addEventListener("mousemove", updateDivLeftTop);
169
+ document.addEventListener("mouseup", cleanup);
96
170
  } else {
97
171
  console.error("container not found");
98
172
  }
@@ -103,17 +177,31 @@ const createGhostElement = (
103
177
  *
104
178
  * @param circuitSvg The SVG element representing the circuit.
105
179
  * @param wireData An array of y values corresponding to the circuit wires.
106
- * @param wireIndex The index of the wire for which the dropzone is created.
180
+ * @param wireIndex The index of the wire or the "between" position.
181
+ * @param isBetween If true, creates a dropzone between wires.
107
182
  * @returns The created dropzone SVG element.
108
183
  */
109
184
  const createWireDropzone = (
110
185
  circuitSvg: SVGElement,
111
186
  wireData: number[],
112
187
  wireIndex: number,
188
+ isBetween: boolean = false,
113
189
  ): SVGElement => {
114
- const wireY = wireData[wireIndex];
115
190
  const svgWidth = Number(circuitSvg.getAttribute("width"));
116
191
  const paddingY = 20;
192
+ let wireY: number;
193
+
194
+ if (isBetween) {
195
+ // Dropzone BETWEEN wires (including before first and after last)
196
+ if (wireIndex === wireData.length) {
197
+ wireY = wireData[wireData.length - 1] + registerHeight / 2;
198
+ } else {
199
+ wireY = wireData[wireIndex] - registerHeight / 2;
200
+ }
201
+ } else {
202
+ // Dropzone ON the wire
203
+ wireY = wireData[wireIndex];
204
+ }
117
205
 
118
206
  const dropzone = box(
119
207
  0,
@@ -195,6 +283,55 @@ const _center = (elem: SVGGraphicsElement): { cX: number; cY: number } => {
195
283
  return { cX: x + width / 2, cY: y + height / 2 };
196
284
  };
197
285
 
286
+ /**
287
+ * Create layer with ghost qubit wire and label
288
+ */
289
+ const _ghostQubitLayer = (context: Context) => {
290
+ const { container, svg } = context;
291
+
292
+ const wireData = getWireData(container);
293
+
294
+ const svgHeight = Number(svg.getAttribute("height") || svg.clientHeight || 0);
295
+ const svgWidth = Number(svg.getAttribute("width") || svg.clientWidth || 800);
296
+ const ghostY = svgHeight;
297
+
298
+ const ghostLayer = document.createElementNS(
299
+ "http://www.w3.org/2000/svg",
300
+ "g",
301
+ );
302
+ ghostLayer.classList.add("ghost-qubit-layer");
303
+ ghostLayer.style.display = "none";
304
+ // Insert before dropzone-layer if possible, otherwise at end
305
+ const dzLayer = svg.querySelector("g.dropzone-layer");
306
+ if (dzLayer) {
307
+ svg.insertBefore(ghostLayer, dzLayer);
308
+ } else {
309
+ svg.appendChild(ghostLayer);
310
+ }
311
+
312
+ const ghostWire = line(
313
+ regLineStart,
314
+ ghostY,
315
+ svgWidth,
316
+ ghostY,
317
+ "qubit-wire ghost-opacity",
318
+ );
319
+
320
+ const ghostLabel = qubitInput(
321
+ ghostY,
322
+ wireData.length,
323
+ wireData.length.toString(),
324
+ );
325
+ ghostLabel.classList.add("ghost-opacity");
326
+ ghostLayer.appendChild(ghostWire);
327
+ ghostLayer.appendChild(ghostLabel);
328
+
329
+ context.svg.setAttribute("height", (svgHeight + registerHeight).toString());
330
+ svg.setAttribute("viewBox", `0 0 ${svgWidth} ${svgHeight + registerHeight}`);
331
+
332
+ return ghostLayer;
333
+ };
334
+
198
335
  /**
199
336
  * Create dropzone layer with all dropzones populated
200
337
  */
@@ -206,97 +343,34 @@ const _dropzoneLayer = (context: Context) => {
206
343
  dropzoneLayer.classList.add("dropzone-layer");
207
344
  dropzoneLayer.style.display = "none";
208
345
 
209
- const { container, operationGrid, wireData, paddingY } = context;
210
- if (wireData.length === 0) return dropzoneLayer; // Return early if there are no wires
211
- const elems = getHostElems(container);
212
-
213
- // Get the widths of each column based on the elements in the column
214
- const colWidths = elems.reduce(
215
- (acc, elem) => {
216
- const location = findLocation(elem);
217
- if (!location) return acc;
218
- const indexes = locationStringToIndexes(location);
219
- // NOTE: for now, we are just going to consider the widths of top-level gates
220
- if (indexes.length != 1) return acc;
221
- const [colIndex] = indexes[0];
222
-
223
- if (!acc[colIndex]) {
224
- acc[colIndex] = Math.max(minGateWidth, elem.getBBox().width);
225
- } else {
226
- acc[colIndex] = Math.max(acc[colIndex], elem.getBBox().width);
227
- }
228
- return acc;
229
- },
230
- {} as Record<number, number>,
231
- );
232
-
233
- // Sort colWidths by colIndex
234
- const sortedColWidths = Object.entries(colWidths)
235
- .sort(([colIndexA], [colIndexB]) => Number(colIndexA) - Number(colIndexB))
236
- .map(([colIndex, colWidth]) => [Number(colIndex), colWidth]);
346
+ const { container, operationGrid } = context;
237
347
 
238
- // let xOffset = regLineStart;
239
- let xOffset = startX - gatePadding;
240
-
241
- /**
242
- * Create a dropzone box element.
243
- *
244
- * @param wireIndex The index of the wire for which the dropzone is created.
245
- * @param colIndex The index of the column where the dropzone is located.
246
- * @param colWidth The width of the column.
247
- * @param opIndex The index of the operation within the column.
248
- * @param interColumn Whether the dropzone is between columns.
249
- * @returns The created dropzone SVG element.
250
- */
251
- const _makeDropzoneBox = (
252
- wireIndex: number,
253
- colIndex: number,
254
- colWidth: number,
255
- opIndex: number,
256
- interColumn: boolean,
257
- ): SVGElement => {
258
- const wireY = wireData[wireIndex];
259
- let dropzone = null;
260
- if (interColumn) {
261
- dropzone = box(
262
- xOffset - gatePadding * 2,
263
- wireY - paddingY,
264
- gatePadding * 4,
265
- paddingY * 2,
266
- "dropzone",
267
- );
268
- } else {
269
- dropzone = box(
270
- xOffset + gatePadding,
271
- wireY - paddingY,
272
- colWidth,
273
- paddingY * 2,
274
- "dropzone",
275
- );
276
- }
277
- dropzone.setAttribute("data-dropzone-location", `${colIndex},${opIndex}`);
278
- dropzone.setAttribute("data-dropzone-wire", `${wireIndex}`);
279
- dropzone.setAttribute("data-dropzone-inter-column", `${interColumn}`);
280
- return dropzone;
281
- };
348
+ const colArray = getColumnOffsetsAndWidths(container);
349
+ const wireData = getWireData(container);
282
350
 
283
351
  // Create dropzones for each intersection of columns and wires
284
- sortedColWidths.forEach(([colIndex, colWidth]) => {
352
+ for (let colIndex = 0; colIndex < colArray.length; colIndex++) {
285
353
  const columnOps = operationGrid[colIndex];
286
354
  let wireIndex = 0;
287
355
 
356
+ const makeBox = (opIndex: number, interColumn: boolean) =>
357
+ makeDropzoneBox(
358
+ colIndex,
359
+ opIndex,
360
+ colArray,
361
+ wireData,
362
+ wireIndex,
363
+ interColumn,
364
+ );
365
+
288
366
  columnOps.components.forEach((op, opIndex) => {
289
367
  const [minTarget, maxTarget] = getMinMaxRegIdx(op, wireData.length);
290
368
  // Add dropzones before the first target
291
369
  while (wireIndex <= maxTarget) {
292
- dropzoneLayer.appendChild(
293
- _makeDropzoneBox(wireIndex, colIndex, colWidth, opIndex, true),
294
- );
370
+ dropzoneLayer.appendChild(makeBox(opIndex, true));
295
371
  // We don't want to make a central zone if the spot is occupied by a gate or its connecting lines
296
372
  if (wireIndex < minTarget) {
297
- dropzoneLayer.appendChild(
298
- _makeDropzoneBox(wireIndex, colIndex, colWidth, opIndex, false),
299
- );
373
+ dropzoneLayer.appendChild(makeBox(opIndex, false));
300
374
  }
301
375
 
302
376
  wireIndex++;
@@ -305,36 +379,26 @@ const _dropzoneLayer = (context: Context) => {
305
379
 
306
380
  // Add dropzones after the last target
307
381
  while (wireIndex < wireData.length) {
308
- dropzoneLayer.appendChild(
309
- _makeDropzoneBox(
310
- wireIndex,
311
- colIndex,
312
- colWidth,
313
- columnOps.components.length,
314
- true,
315
- ),
316
- );
317
- dropzoneLayer.appendChild(
318
- _makeDropzoneBox(
319
- wireIndex,
320
- colIndex,
321
- colWidth,
322
- columnOps.components.length,
323
- false,
324
- ),
325
- );
382
+ dropzoneLayer.appendChild(makeBox(columnOps.components.length, true));
383
+ dropzoneLayer.appendChild(makeBox(columnOps.components.length, false));
326
384
 
327
385
  wireIndex++;
328
386
  }
329
- xOffset += colWidth + gatePadding * 2;
330
- });
387
+ }
331
388
 
332
389
  // This assumes column indexes are continuous
333
- const endColIndex = sortedColWidths.length;
390
+ const endColIndex = colArray.length;
334
391
 
335
392
  // Add remaining dropzones to allow users to add gates to the end of the circuit
336
393
  for (let wireIndex = 0; wireIndex < wireData.length; wireIndex++) {
337
- const dropzone = _makeDropzoneBox(wireIndex, endColIndex, 0, 0, true);
394
+ const dropzone = makeDropzoneBox(
395
+ endColIndex,
396
+ 0,
397
+ colArray,
398
+ wireData,
399
+ wireIndex,
400
+ true,
401
+ );
338
402
  // Note: the last column should have the shape of an inter-column dropzone, but
339
403
  // we don't want to attach the inter-column logic to it.
340
404
  dropzone.setAttribute("data-dropzone-inter-column", "false");
@@ -344,9 +408,121 @@ const _dropzoneLayer = (context: Context) => {
344
408
  return dropzoneLayer;
345
409
  };
346
410
 
411
+ /**
412
+ * Computes a sorted array of { xOffset, colWidth } for each column index.
413
+ * The array index corresponds to the column index.
414
+ *
415
+ * @param container The circuit container element.
416
+ * @returns Array where arr[colIndex] = { xOffset, colWidth }
417
+ */
418
+ const getColumnOffsetsAndWidths = (
419
+ container: HTMLElement,
420
+ ): { xOffset: number; colWidth: number }[] => {
421
+ const elems = getHostElems(container);
422
+
423
+ if (elems.length === 0) {
424
+ return [];
425
+ }
426
+
427
+ // Compute column widths
428
+ const colWidths = elems.reduce(
429
+ (acc, elem) => {
430
+ const location = findLocation(elem);
431
+ if (!location) return acc;
432
+ const indexes = locationStringToIndexes(location);
433
+ if (indexes.length != 1) return acc;
434
+ const [colIndex] = indexes[0];
435
+ if (!acc[colIndex]) {
436
+ acc[colIndex] = Math.max(minGateWidth, elem.getBBox().width);
437
+ } else {
438
+ acc[colIndex] = Math.max(acc[colIndex], elem.getBBox().width);
439
+ }
440
+ return acc;
441
+ },
442
+ {} as Record<number, number>,
443
+ );
444
+
445
+ // Find the max colIndex to size the array
446
+ const maxColIndex = Math.max(...Object.keys(colWidths).map(Number), 0);
447
+
448
+ let xOffset = startX - gatePadding;
449
+ const result: { xOffset: number; colWidth: number }[] = [];
450
+ for (let colIndex = 0; colIndex <= maxColIndex; colIndex++) {
451
+ const colWidth = colWidths[colIndex] ?? minGateWidth;
452
+ result[colIndex] = { xOffset, colWidth };
453
+ xOffset += colWidth + gatePadding * 2;
454
+ }
455
+ return result;
456
+ };
457
+
458
+ /**
459
+ * Create a dropzone box element.
460
+ *
461
+ * @param colIndex The index of the column where the dropzone is located.
462
+ * @param opIndex The index of the operation within the column.
463
+ * @param colArray An array of objects containing xOffset and colWidth for each column.
464
+ * @param wireData The array of wire Y positions.
465
+ * @param wireIndex The index of the wire for which the dropzone is created.
466
+ * @param interColumn Whether the dropzone is between columns.
467
+ *
468
+ * @returns The created dropzone SVG element.
469
+ */
470
+ const makeDropzoneBox = (
471
+ colIndex: number,
472
+ opIndex: number,
473
+ colArray: { xOffset: number; colWidth: number }[],
474
+ wireData: number[],
475
+ wireIndex: number,
476
+ interColumn: boolean,
477
+ ): SVGElement => {
478
+ const wireY = wireData[wireIndex];
479
+ let xOffset: number, colWidth: number;
480
+
481
+ if (colArray[colIndex]) {
482
+ ({ xOffset, colWidth } = colArray[colIndex]);
483
+ } else {
484
+ // Compute offset for a hypothetical new last column
485
+ const last = colArray[colArray.length - 1];
486
+ if (last) {
487
+ xOffset = last.xOffset + last.colWidth + gatePadding * 2;
488
+ } else {
489
+ // If there are no columns at all, start at initial offset
490
+ xOffset = startX - gatePadding;
491
+ }
492
+ colWidth = minGateWidth;
493
+ }
494
+
495
+ const paddingY = 20;
496
+ let dropzone = null;
497
+ if (interColumn) {
498
+ dropzone = box(
499
+ xOffset - gatePadding * 2,
500
+ wireY - paddingY,
501
+ gatePadding * 4,
502
+ paddingY * 2,
503
+ "dropzone",
504
+ );
505
+ } else {
506
+ dropzone = box(
507
+ xOffset + gatePadding,
508
+ wireY - paddingY,
509
+ colWidth,
510
+ paddingY * 2,
511
+ "dropzone",
512
+ );
513
+ }
514
+ dropzone.setAttribute("data-dropzone-location", `${colIndex},${opIndex}`);
515
+ dropzone.setAttribute("data-dropzone-wire", `${wireIndex}`);
516
+ dropzone.setAttribute("data-dropzone-inter-column", `${interColumn}`);
517
+ return dropzone;
518
+ };
519
+
347
520
  export {
348
- createDragzones,
349
- createGhostElement,
521
+ createDropzones,
522
+ createGateGhost,
523
+ createQubitLabelGhost,
350
524
  createWireDropzone,
351
525
  removeAllWireDropzones,
526
+ getColumnOffsetsAndWidths,
527
+ makeDropzoneBox,
352
528
  };