qsharp-lang 1.13.1-dev → 1.13.3-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.
- package/dist/browser.d.ts +1 -0
- package/dist/compiler/compiler.d.ts +3 -3
- package/dist/compiler/compiler.js +2 -2
- package/dist/debug-service/debug-service.d.ts +1 -1
- package/dist/katas-content.generated.js +1 -1
- package/dist/katas-content.generated.md.js +1 -1
- package/dist/shared/circuit.d.ts +64 -0
- package/dist/shared/circuit.js +16 -0
- package/dist/shared/register.d.ts +35 -0
- package/dist/shared/register.js +10 -0
- package/docs/Microsoft.Quantum.Core/Length.md +1 -1
- package/docs/Microsoft.Quantum.Core/Repeated.md +1 -1
- package/docs/Microsoft.Quantum.Core/index.md +1 -1
- package/docs/Std.Arithmetic/AddLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfEqualL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfEqualLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfGreaterL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfGreaterLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfGreaterOrEqualL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfGreaterOrEqualLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfLessL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfLessLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfLessOrEqualL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfLessOrEqualLE.md +1 -1
- package/docs/Std.Arithmetic/FourierTDIncByLE.md +1 -1
- package/docs/Std.Arithmetic/IncByI.md +1 -1
- package/docs/Std.Arithmetic/IncByIUsingIncByLE.md +1 -1
- package/docs/Std.Arithmetic/IncByL.md +1 -1
- package/docs/Std.Arithmetic/IncByLE.md +1 -1
- package/docs/Std.Arithmetic/IncByLEUsingAddLE.md +1 -1
- package/docs/Std.Arithmetic/IncByLUsingIncByLE.md +1 -1
- package/docs/Std.Arithmetic/LookAheadDKRSAddLE.md +1 -1
- package/docs/Std.Arithmetic/MAJ.md +1 -1
- package/docs/Std.Arithmetic/ReflectAboutInteger.md +1 -1
- package/docs/Std.Arithmetic/RippleCarryCGAddLE.md +1 -1
- package/docs/Std.Arithmetic/RippleCarryCGIncByLE.md +1 -1
- package/docs/Std.Arithmetic/RippleCarryTTKIncByLE.md +1 -1
- package/docs/Std.Arithmetic/index.md +1 -1
- package/docs/Std.Arrays/All.md +1 -1
- package/docs/Std.Arrays/Any.md +1 -1
- package/docs/Std.Arrays/Chunks.md +1 -1
- package/docs/Std.Arrays/CircularlyShifted.md +1 -1
- package/docs/Std.Arrays/ColumnAt.md +1 -1
- package/docs/Std.Arrays/Count.md +1 -1
- package/docs/Std.Arrays/Diagonal.md +1 -1
- package/docs/Std.Arrays/DrawMany.md +1 -1
- package/docs/Std.Arrays/Enumerated.md +1 -1
- package/docs/Std.Arrays/Excluding.md +1 -1
- package/docs/Std.Arrays/Filtered.md +1 -1
- package/docs/Std.Arrays/FlatMapped.md +1 -1
- package/docs/Std.Arrays/Flattened.md +1 -1
- package/docs/Std.Arrays/Fold.md +1 -1
- package/docs/Std.Arrays/ForEach.md +1 -1
- package/docs/Std.Arrays/Head.md +1 -1
- package/docs/Std.Arrays/HeadAndRest.md +1 -1
- package/docs/Std.Arrays/IndexOf.md +1 -1
- package/docs/Std.Arrays/IndexRange.md +1 -1
- package/docs/Std.Arrays/Interleaved.md +1 -1
- package/docs/Std.Arrays/IsEmpty.md +1 -1
- package/docs/Std.Arrays/IsRectangularArray.md +1 -1
- package/docs/Std.Arrays/IsSorted.md +1 -1
- package/docs/Std.Arrays/IsSquareArray.md +1 -1
- package/docs/Std.Arrays/Mapped.md +1 -1
- package/docs/Std.Arrays/MappedByIndex.md +1 -1
- package/docs/Std.Arrays/MappedOverRange.md +1 -1
- package/docs/Std.Arrays/Most.md +1 -1
- package/docs/Std.Arrays/MostAndTail.md +1 -1
- package/docs/Std.Arrays/Padded.md +1 -1
- package/docs/Std.Arrays/Partitioned.md +1 -1
- package/docs/Std.Arrays/Rest.md +1 -1
- package/docs/Std.Arrays/Reversed.md +1 -1
- package/docs/Std.Arrays/SequenceI.md +1 -1
- package/docs/Std.Arrays/SequenceL.md +1 -1
- package/docs/Std.Arrays/Sorted.md +1 -1
- package/docs/Std.Arrays/Subarray.md +1 -1
- package/docs/Std.Arrays/Swapped.md +1 -1
- package/docs/Std.Arrays/Tail.md +1 -1
- package/docs/Std.Arrays/Transposed.md +1 -1
- package/docs/Std.Arrays/Unzipped.md +1 -1
- package/docs/Std.Arrays/Where.md +1 -1
- package/docs/Std.Arrays/Windows.md +1 -1
- package/docs/Std.Arrays/Zipped.md +1 -1
- package/docs/Std.Arrays/index.md +1 -1
- package/docs/Std.Canon/ApplyCNOTChain.md +1 -1
- package/docs/Std.Canon/ApplyControlledOnBitString.md +1 -1
- package/docs/Std.Canon/ApplyControlledOnInt.md +1 -1
- package/docs/Std.Canon/ApplyP.md +1 -1
- package/docs/Std.Canon/ApplyPauli.md +1 -1
- package/docs/Std.Canon/ApplyPauliFromBitString.md +1 -1
- package/docs/Std.Canon/ApplyPauliFromInt.md +1 -1
- package/docs/Std.Canon/ApplyQFT.md +1 -1
- package/docs/Std.Canon/ApplyToEach.md +1 -1
- package/docs/Std.Canon/ApplyToEachA.md +1 -1
- package/docs/Std.Canon/ApplyToEachC.md +1 -1
- package/docs/Std.Canon/ApplyToEachCA.md +1 -1
- package/docs/Std.Canon/ApplyXorInPlace.md +1 -1
- package/docs/Std.Canon/ApplyXorInPlaceL.md +1 -1
- package/docs/Std.Canon/CX.md +1 -1
- package/docs/Std.Canon/CY.md +1 -1
- package/docs/Std.Canon/CZ.md +1 -1
- package/docs/Std.Canon/Fst.md +1 -1
- package/docs/Std.Canon/Relabel.md +1 -1
- package/docs/Std.Canon/Snd.md +1 -1
- package/docs/Std.Canon/SwapReverseRegister.md +1 -1
- package/docs/Std.Canon/index.md +1 -1
- package/docs/Std.Convert/BigIntAsBoolArray.md +1 -1
- package/docs/Std.Convert/BoolArrayAsBigInt.md +1 -1
- package/docs/Std.Convert/BoolArrayAsInt.md +1 -1
- package/docs/Std.Convert/BoolArrayAsResultArray.md +1 -1
- package/docs/Std.Convert/BoolAsResult.md +1 -1
- package/docs/Std.Convert/ComplexAsComplexPolar.md +1 -1
- package/docs/Std.Convert/ComplexPolarAsComplex.md +1 -1
- package/docs/Std.Convert/DoubleAsStringWithPrecision.md +1 -1
- package/docs/Std.Convert/IntAsBigInt.md +1 -1
- package/docs/Std.Convert/IntAsBoolArray.md +1 -1
- package/docs/Std.Convert/IntAsDouble.md +1 -1
- package/docs/Std.Convert/ResultArrayAsBoolArray.md +1 -1
- package/docs/Std.Convert/ResultArrayAsInt.md +1 -1
- package/docs/Std.Convert/ResultAsBool.md +1 -1
- package/docs/Std.Convert/index.md +1 -1
- package/docs/Std.Core/Length.md +1 -1
- package/docs/Std.Core/Repeated.md +1 -1
- package/docs/Std.Core/index.md +1 -1
- package/docs/Std.Diagnostics/ApplyIdleNoise.md +1 -1
- package/docs/Std.Diagnostics/BitFlipNoise.md +1 -1
- package/docs/Std.Diagnostics/CheckAllZero.md +1 -1
- package/docs/Std.Diagnostics/CheckOperationsAreEqual.md +1 -1
- package/docs/Std.Diagnostics/CheckZero.md +1 -1
- package/docs/Std.Diagnostics/ConfigurePauliNoise.md +1 -1
- package/docs/Std.Diagnostics/DepolarizingNoise.md +1 -1
- package/docs/Std.Diagnostics/DumpMachine.md +1 -1
- package/docs/Std.Diagnostics/DumpOperation.md +1 -1
- package/docs/Std.Diagnostics/DumpRegister.md +1 -1
- package/docs/Std.Diagnostics/Fact.md +1 -1
- package/docs/Std.Diagnostics/NoNoise.md +1 -1
- package/docs/Std.Diagnostics/PhaseFlipNoise.md +1 -1
- package/docs/Std.Diagnostics/StartCountingFunction.md +1 -1
- package/docs/Std.Diagnostics/StartCountingOperation.md +1 -1
- package/docs/Std.Diagnostics/StartCountingQubits.md +1 -1
- package/docs/Std.Diagnostics/StopCountingFunction.md +1 -1
- package/docs/Std.Diagnostics/StopCountingOperation.md +1 -1
- package/docs/Std.Diagnostics/StopCountingQubits.md +1 -1
- package/docs/Std.Diagnostics/index.md +1 -1
- package/docs/Std.Intrinsic/AND.md +1 -1
- package/docs/Std.Intrinsic/ApplyUnitary.md +1 -1
- package/docs/Std.Intrinsic/CCNOT.md +1 -1
- package/docs/Std.Intrinsic/CNOT.md +1 -1
- package/docs/Std.Intrinsic/Exp.md +1 -1
- package/docs/Std.Intrinsic/H.md +1 -1
- package/docs/Std.Intrinsic/I.md +1 -1
- package/docs/Std.Intrinsic/M.md +1 -1
- package/docs/Std.Intrinsic/Measure.md +1 -1
- package/docs/Std.Intrinsic/Message.md +1 -1
- package/docs/Std.Intrinsic/R.md +1 -1
- package/docs/Std.Intrinsic/R1.md +1 -1
- package/docs/Std.Intrinsic/R1Frac.md +1 -1
- package/docs/Std.Intrinsic/RFrac.md +1 -1
- package/docs/Std.Intrinsic/Reset.md +1 -1
- package/docs/Std.Intrinsic/ResetAll.md +1 -1
- package/docs/Std.Intrinsic/Rx.md +1 -1
- package/docs/Std.Intrinsic/Rxx.md +1 -1
- package/docs/Std.Intrinsic/Ry.md +1 -1
- package/docs/Std.Intrinsic/Ryy.md +1 -1
- package/docs/Std.Intrinsic/Rz.md +1 -1
- package/docs/Std.Intrinsic/Rzz.md +1 -1
- package/docs/Std.Intrinsic/S.md +1 -1
- package/docs/Std.Intrinsic/SWAP.md +1 -1
- package/docs/Std.Intrinsic/T.md +1 -1
- package/docs/Std.Intrinsic/X.md +1 -1
- package/docs/Std.Intrinsic/Y.md +1 -1
- package/docs/Std.Intrinsic/Z.md +1 -1
- package/docs/Std.Intrinsic/index.md +1 -1
- package/docs/Std.Logical/Xor.md +1 -1
- package/docs/Std.Logical/index.md +1 -1
- package/docs/Std.Math/AbsComplex.md +1 -1
- package/docs/Std.Math/AbsComplexPolar.md +1 -1
- package/docs/Std.Math/AbsD.md +1 -1
- package/docs/Std.Math/AbsI.md +1 -1
- package/docs/Std.Math/AbsL.md +1 -1
- package/docs/Std.Math/AbsSquaredComplex.md +1 -1
- package/docs/Std.Math/AbsSquaredComplexPolar.md +1 -1
- package/docs/Std.Math/ApproximateFactorial.md +1 -1
- package/docs/Std.Math/ArcCos.md +1 -1
- package/docs/Std.Math/ArcCosh.md +1 -1
- package/docs/Std.Math/ArcSin.md +1 -1
- package/docs/Std.Math/ArcSinh.md +1 -1
- package/docs/Std.Math/ArcTan.md +1 -1
- package/docs/Std.Math/ArcTan2.md +1 -1
- package/docs/Std.Math/ArcTanh.md +1 -1
- package/docs/Std.Math/ArgComplex.md +1 -1
- package/docs/Std.Math/ArgComplexPolar.md +1 -1
- package/docs/Std.Math/Binom.md +1 -1
- package/docs/Std.Math/BitSizeI.md +1 -1
- package/docs/Std.Math/BitSizeL.md +1 -1
- package/docs/Std.Math/Ceiling.md +1 -1
- package/docs/Std.Math/Complex.md +1 -1
- package/docs/Std.Math/ComplexPolar.md +1 -1
- package/docs/Std.Math/ContinuedFractionConvergentI.md +1 -1
- package/docs/Std.Math/ContinuedFractionConvergentL.md +1 -1
- package/docs/Std.Math/Cos.md +1 -1
- package/docs/Std.Math/Cosh.md +1 -1
- package/docs/Std.Math/DivRemI.md +1 -1
- package/docs/Std.Math/DivRemL.md +1 -1
- package/docs/Std.Math/DividedByC.md +1 -1
- package/docs/Std.Math/DividedByCP.md +1 -1
- package/docs/Std.Math/E.md +1 -1
- package/docs/Std.Math/ExpModI.md +1 -1
- package/docs/Std.Math/ExpModL.md +1 -1
- package/docs/Std.Math/ExtendedGreatestCommonDivisorI.md +1 -1
- package/docs/Std.Math/ExtendedGreatestCommonDivisorL.md +1 -1
- package/docs/Std.Math/FactorialI.md +1 -1
- package/docs/Std.Math/FactorialL.md +1 -1
- package/docs/Std.Math/Floor.md +1 -1
- package/docs/Std.Math/GreatestCommonDivisorI.md +1 -1
- package/docs/Std.Math/GreatestCommonDivisorL.md +1 -1
- package/docs/Std.Math/HammingWeightI.md +1 -1
- package/docs/Std.Math/InverseModI.md +1 -1
- package/docs/Std.Math/InverseModL.md +1 -1
- package/docs/Std.Math/IsCoprimeI.md +1 -1
- package/docs/Std.Math/IsCoprimeL.md +1 -1
- package/docs/Std.Math/IsInfinite.md +1 -1
- package/docs/Std.Math/IsNaN.md +1 -1
- package/docs/Std.Math/LargestFixedPoint.md +1 -1
- package/docs/Std.Math/Lg.md +1 -1
- package/docs/Std.Math/Log.md +1 -1
- package/docs/Std.Math/Log10.md +1 -1
- package/docs/Std.Math/LogFactorialD.md +1 -1
- package/docs/Std.Math/LogGammaD.md +1 -1
- package/docs/Std.Math/LogOf2.md +1 -1
- package/docs/Std.Math/Max.md +1 -1
- package/docs/Std.Math/MaxD.md +1 -1
- package/docs/Std.Math/MaxI.md +1 -1
- package/docs/Std.Math/MaxL.md +1 -1
- package/docs/Std.Math/Min.md +1 -1
- package/docs/Std.Math/MinD.md +1 -1
- package/docs/Std.Math/MinI.md +1 -1
- package/docs/Std.Math/MinL.md +1 -1
- package/docs/Std.Math/MinusC.md +1 -1
- package/docs/Std.Math/MinusCP.md +1 -1
- package/docs/Std.Math/ModulusI.md +1 -1
- package/docs/Std.Math/ModulusL.md +1 -1
- package/docs/Std.Math/NegationC.md +1 -1
- package/docs/Std.Math/NegationCP.md +1 -1
- package/docs/Std.Math/PI.md +1 -1
- package/docs/Std.Math/PNorm.md +1 -1
- package/docs/Std.Math/PNormalized.md +1 -1
- package/docs/Std.Math/PlusC.md +1 -1
- package/docs/Std.Math/PlusCP.md +1 -1
- package/docs/Std.Math/PowC.md +1 -1
- package/docs/Std.Math/PowCP.md +1 -1
- package/docs/Std.Math/RealMod.md +1 -1
- package/docs/Std.Math/Round.md +1 -1
- package/docs/Std.Math/SignD.md +1 -1
- package/docs/Std.Math/SignI.md +1 -1
- package/docs/Std.Math/SignL.md +1 -1
- package/docs/Std.Math/Sin.md +1 -1
- package/docs/Std.Math/Sinh.md +1 -1
- package/docs/Std.Math/SmallestFixedPoint.md +1 -1
- package/docs/Std.Math/Sqrt.md +1 -1
- package/docs/Std.Math/SquaredNorm.md +1 -1
- package/docs/Std.Math/Tan.md +1 -1
- package/docs/Std.Math/Tanh.md +1 -1
- package/docs/Std.Math/TimesC.md +1 -1
- package/docs/Std.Math/TimesCP.md +1 -1
- package/docs/Std.Math/TrailingZeroCountI.md +1 -1
- package/docs/Std.Math/TrailingZeroCountL.md +1 -1
- package/docs/Std.Math/Truncate.md +1 -1
- package/docs/Std.Math/index.md +1 -1
- package/docs/Std.Measurement/MResetEachZ.md +1 -1
- package/docs/Std.Measurement/MResetX.md +1 -1
- package/docs/Std.Measurement/MResetY.md +1 -1
- package/docs/Std.Measurement/MResetZ.md +1 -1
- package/docs/Std.Measurement/MeasureAllZ.md +1 -1
- package/docs/Std.Measurement/MeasureEachZ.md +1 -1
- package/docs/Std.Measurement/MeasureInteger.md +1 -1
- package/docs/Std.Measurement/index.md +1 -1
- package/docs/Std.Random/DrawRandomBool.md +1 -1
- package/docs/Std.Random/DrawRandomDouble.md +1 -1
- package/docs/Std.Random/DrawRandomInt.md +1 -1
- package/docs/Std.Random/index.md +1 -1
- package/docs/Std.Range/IsRangeEmpty.md +1 -1
- package/docs/Std.Range/RangeEnd.md +1 -1
- package/docs/Std.Range/RangeReverse.md +1 -1
- package/docs/Std.Range/RangeStart.md +1 -1
- package/docs/Std.Range/RangeStep.md +1 -1
- package/docs/Std.Range/index.md +1 -1
- package/docs/Std.ResourceEstimation/AccountForEstimates.md +1 -1
- package/docs/Std.ResourceEstimation/AuxQubitCount.md +1 -1
- package/docs/Std.ResourceEstimation/BeginEstimateCaching.md +1 -1
- package/docs/Std.ResourceEstimation/BeginRepeatEstimates.md +1 -1
- package/docs/Std.ResourceEstimation/CczCount.md +1 -1
- package/docs/Std.ResourceEstimation/EndEstimateCaching.md +1 -1
- package/docs/Std.ResourceEstimation/EndRepeatEstimates.md +1 -1
- package/docs/Std.ResourceEstimation/MeasurementCount.md +1 -1
- package/docs/Std.ResourceEstimation/PSSPCLayout.md +1 -1
- package/docs/Std.ResourceEstimation/RepeatEstimates.md +1 -1
- package/docs/Std.ResourceEstimation/RotationCount.md +1 -1
- package/docs/Std.ResourceEstimation/RotationDepth.md +1 -1
- package/docs/Std.ResourceEstimation/SingleVariant.md +1 -1
- package/docs/Std.ResourceEstimation/TCount.md +1 -1
- package/docs/Std.ResourceEstimation/index.md +1 -1
- package/docs/Std.StatePreparation/ApproximatelyPreparePureStateCP.md +1 -1
- package/docs/Std.StatePreparation/PreparePureStateD.md +1 -1
- package/docs/Std.StatePreparation/index.md +1 -1
- package/docs/Std.TableLookup/Select.md +1 -1
- package/docs/Std.TableLookup/index.md +1 -1
- package/docs/index.md +1 -1
- package/lib/node/qsc_wasm.cjs +17 -14
- package/lib/node/qsc_wasm.d.cts +3 -6
- package/lib/node/qsc_wasm_bg.wasm +0 -0
- package/lib/web/qsc_wasm.d.ts +4 -7
- package/lib/web/qsc_wasm.js +17 -14
- package/lib/web/qsc_wasm_bg.wasm +0 -0
- package/package.json +1 -1
- package/ux/circuit-vis/README.md +1 -0
- package/ux/circuit-vis/circuit.ts +10 -0
- package/ux/circuit-vis/constants.ts +39 -0
- package/ux/circuit-vis/formatters/formatUtils.ts +220 -0
- package/ux/circuit-vis/formatters/gateFormatter.ts +557 -0
- package/ux/circuit-vis/formatters/inputFormatter.ts +78 -0
- package/ux/circuit-vis/formatters/registerFormatter.ts +118 -0
- package/ux/circuit-vis/index.ts +30 -0
- package/ux/circuit-vis/metadata.ts +56 -0
- package/ux/circuit-vis/process.ts +536 -0
- package/ux/circuit-vis/register.ts +9 -0
- package/ux/circuit-vis/sqore.ts +376 -0
- package/ux/circuit-vis/styles.ts +236 -0
- package/ux/circuit-vis/utils.ts +77 -0
- package/ux/circuit.tsx +2 -2
- package/ux/data.ts +1 -1
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
|
|
4
|
+
import { formatInputs } from "./formatters/inputFormatter";
|
|
5
|
+
import { formatGates } from "./formatters/gateFormatter";
|
|
6
|
+
import { formatRegisters } from "./formatters/registerFormatter";
|
|
7
|
+
import { processOperations } from "./process";
|
|
8
|
+
import { ConditionalRender, Circuit, Operation } from "./circuit";
|
|
9
|
+
import { Metadata, GateType } from "./metadata";
|
|
10
|
+
import { StyleConfig, style, STYLES } from "./styles";
|
|
11
|
+
import { createUUID } from "./utils";
|
|
12
|
+
import { svgNS } from "./constants";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Contains metadata for visualization.
|
|
16
|
+
*/
|
|
17
|
+
interface ComposedSqore {
|
|
18
|
+
/** Width of visualization. */
|
|
19
|
+
width: number;
|
|
20
|
+
/** Height of visualization. */
|
|
21
|
+
height: number;
|
|
22
|
+
/** SVG elements the make up the visualization. */
|
|
23
|
+
elements: SVGElement[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Defines the mapping of unique ID to each operation. Used for enabling
|
|
28
|
+
* interactivity.
|
|
29
|
+
*/
|
|
30
|
+
type GateRegistry = {
|
|
31
|
+
[id: string]: Operation;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Entrypoint class for rendering circuit visualizations.
|
|
36
|
+
*/
|
|
37
|
+
export class Sqore {
|
|
38
|
+
circuit: Circuit;
|
|
39
|
+
style: StyleConfig = {};
|
|
40
|
+
gateRegistry: GateRegistry = {};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Initializes Sqore object with custom styles.
|
|
44
|
+
*
|
|
45
|
+
* @param circuit Circuit to be visualized.
|
|
46
|
+
* @param style Custom visualization style.
|
|
47
|
+
*/
|
|
48
|
+
constructor(circuit: Circuit, style: StyleConfig | string = {}) {
|
|
49
|
+
this.circuit = circuit;
|
|
50
|
+
this.style = this.getStyle(style);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Render circuit into `container` at the specified layer depth.
|
|
55
|
+
*
|
|
56
|
+
* @param container HTML element for rendering visualization into.
|
|
57
|
+
* @param renderDepth Initial layer depth at which to render gates.
|
|
58
|
+
*/
|
|
59
|
+
draw(container: HTMLElement, renderDepth = 0): void {
|
|
60
|
+
// Inject into container
|
|
61
|
+
if (container == null) throw new Error(`Container not provided.`);
|
|
62
|
+
|
|
63
|
+
// Create copy of circuit to prevent mutation
|
|
64
|
+
const circuit: Circuit = JSON.parse(JSON.stringify(this.circuit));
|
|
65
|
+
|
|
66
|
+
// Assign unique IDs to each operation
|
|
67
|
+
circuit.operations.forEach((op, i) =>
|
|
68
|
+
this.fillGateRegistry(op, i.toString()),
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
// Render operations at starting at given depth
|
|
72
|
+
circuit.operations = this.selectOpsAtDepth(circuit.operations, renderDepth);
|
|
73
|
+
|
|
74
|
+
// If only one top-level operation, expand automatically:
|
|
75
|
+
if (
|
|
76
|
+
circuit.operations.length == 1 &&
|
|
77
|
+
circuit.operations[0].dataAttributes != null &&
|
|
78
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
79
|
+
circuit.operations[0].dataAttributes.hasOwnProperty("id")
|
|
80
|
+
) {
|
|
81
|
+
const id: string = circuit.operations[0].dataAttributes["id"];
|
|
82
|
+
this.expandOperation(circuit.operations, id);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
this.renderCircuit(container, circuit);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Retrieve style for visualization.
|
|
90
|
+
*
|
|
91
|
+
* @param style Custom style or style name.
|
|
92
|
+
*
|
|
93
|
+
* @returns Custom style.
|
|
94
|
+
*/
|
|
95
|
+
private getStyle(style: StyleConfig | string = {}): StyleConfig {
|
|
96
|
+
if (typeof style === "string" || style instanceof String) {
|
|
97
|
+
const styleName: string = style as string;
|
|
98
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
99
|
+
if (!STYLES.hasOwnProperty(styleName)) {
|
|
100
|
+
console.error(`No style ${styleName} found in STYLES.`);
|
|
101
|
+
return {};
|
|
102
|
+
}
|
|
103
|
+
style = STYLES[styleName];
|
|
104
|
+
}
|
|
105
|
+
return style;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Render circuit into `container`.
|
|
110
|
+
*
|
|
111
|
+
* @param container HTML element for rendering visualization into.
|
|
112
|
+
* @param circuit Circuit object to be rendered.
|
|
113
|
+
*/
|
|
114
|
+
private renderCircuit(container: HTMLElement, circuit: Circuit): void {
|
|
115
|
+
// Create visualization components
|
|
116
|
+
const composedSqore: ComposedSqore = this.compose(circuit);
|
|
117
|
+
const svg: SVGElement = this.generateSvg(composedSqore);
|
|
118
|
+
container.innerHTML = "";
|
|
119
|
+
container.appendChild(svg);
|
|
120
|
+
this.addGateClickHandlers(container, circuit);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Generates the components required for visualization.
|
|
125
|
+
*
|
|
126
|
+
* @param circuit Circuit to be visualized.
|
|
127
|
+
*
|
|
128
|
+
* @returns `ComposedSqore` object containing metadata for visualization.
|
|
129
|
+
*/
|
|
130
|
+
private compose(circuit: Circuit): ComposedSqore {
|
|
131
|
+
const add = (acc: Metadata[], gate: Metadata | Metadata[]): void => {
|
|
132
|
+
if (Array.isArray(gate)) {
|
|
133
|
+
gate.forEach((g) => add(acc, g));
|
|
134
|
+
} else {
|
|
135
|
+
acc.push(gate);
|
|
136
|
+
gate.children?.forEach((g) => add(acc, g));
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const flatten = (gates: Metadata[]): Metadata[] => {
|
|
141
|
+
const result: Metadata[] = [];
|
|
142
|
+
add(result, gates);
|
|
143
|
+
return result;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const { qubits, operations } = circuit;
|
|
147
|
+
const { qubitWires, registers, svgHeight } = formatInputs(qubits);
|
|
148
|
+
const { metadataList, svgWidth } = processOperations(operations, registers);
|
|
149
|
+
const formattedGates: SVGElement = formatGates(metadataList);
|
|
150
|
+
const measureGates: Metadata[] = flatten(metadataList).filter(
|
|
151
|
+
({ type }) => type === GateType.Measure,
|
|
152
|
+
);
|
|
153
|
+
const formattedRegs: SVGElement = formatRegisters(
|
|
154
|
+
registers,
|
|
155
|
+
measureGates,
|
|
156
|
+
svgWidth,
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
const composedSqore: ComposedSqore = {
|
|
160
|
+
width: svgWidth,
|
|
161
|
+
height: svgHeight,
|
|
162
|
+
elements: [qubitWires, formattedRegs, formattedGates],
|
|
163
|
+
};
|
|
164
|
+
return composedSqore;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Generates visualization of `composedSqore` as an SVG.
|
|
169
|
+
*
|
|
170
|
+
* @param composedSqore ComposedSqore to be visualized.
|
|
171
|
+
*
|
|
172
|
+
* @returns SVG representation of circuit visualization.
|
|
173
|
+
*/
|
|
174
|
+
private generateSvg(composedSqore: ComposedSqore): SVGElement {
|
|
175
|
+
const { width, height, elements } = composedSqore;
|
|
176
|
+
const uuid: string = createUUID();
|
|
177
|
+
|
|
178
|
+
const svg: SVGElement = document.createElementNS(svgNS, "svg");
|
|
179
|
+
svg.setAttribute("id", uuid);
|
|
180
|
+
svg.setAttribute("class", "qviz");
|
|
181
|
+
svg.setAttribute("width", width.toString());
|
|
182
|
+
svg.setAttribute("height", height.toString());
|
|
183
|
+
svg.style.setProperty("max-width", "fit-content");
|
|
184
|
+
|
|
185
|
+
// Add styles
|
|
186
|
+
const css = document.createElement("style");
|
|
187
|
+
css.innerHTML = style(this.style);
|
|
188
|
+
svg.appendChild(css);
|
|
189
|
+
|
|
190
|
+
// Add body elements
|
|
191
|
+
elements.forEach((element: SVGElement) => svg.appendChild(element));
|
|
192
|
+
|
|
193
|
+
return svg;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Depth-first traversal to assign unique ID to `operation`.
|
|
198
|
+
* The operation is assigned the id `id` and its `i`th child is recursively given
|
|
199
|
+
* the id `${id}-${i}`.
|
|
200
|
+
*
|
|
201
|
+
* @param operation Operation to be assigned.
|
|
202
|
+
* @param id: ID to assign to `operation`.
|
|
203
|
+
*
|
|
204
|
+
*/
|
|
205
|
+
private fillGateRegistry(operation: Operation, id: string): void {
|
|
206
|
+
if (operation.dataAttributes == null) operation.dataAttributes = {};
|
|
207
|
+
operation.dataAttributes["id"] = id;
|
|
208
|
+
// By default, operations cannot be zoomed-out
|
|
209
|
+
operation.dataAttributes["zoom-out"] = "false";
|
|
210
|
+
this.gateRegistry[id] = operation;
|
|
211
|
+
operation.children?.forEach((childOp, i) => {
|
|
212
|
+
this.fillGateRegistry(childOp, `${id}-${i}`);
|
|
213
|
+
if (childOp.dataAttributes == null) childOp.dataAttributes = {};
|
|
214
|
+
// Children operations can be zoomed out
|
|
215
|
+
childOp.dataAttributes["zoom-out"] = "true";
|
|
216
|
+
});
|
|
217
|
+
// Composite operations can be zoomed in
|
|
218
|
+
operation.dataAttributes["zoom-in"] = (
|
|
219
|
+
operation.children != null
|
|
220
|
+
).toString();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Pick out operations that are at or below `renderDepth`.
|
|
225
|
+
*
|
|
226
|
+
* @param operations List of circuit operations.
|
|
227
|
+
* @param renderDepth Initial layer depth at which to render gates.
|
|
228
|
+
*
|
|
229
|
+
* @returns List of operations at or below specifed depth.
|
|
230
|
+
*/
|
|
231
|
+
private selectOpsAtDepth(
|
|
232
|
+
operations: Operation[],
|
|
233
|
+
renderDepth: number,
|
|
234
|
+
): Operation[] {
|
|
235
|
+
if (renderDepth < 0)
|
|
236
|
+
throw new Error(
|
|
237
|
+
`Invalid renderDepth of ${renderDepth}. Needs to be >= 0.`,
|
|
238
|
+
);
|
|
239
|
+
if (renderDepth === 0) return operations;
|
|
240
|
+
return operations
|
|
241
|
+
.map((op) =>
|
|
242
|
+
op.children != null
|
|
243
|
+
? this.selectOpsAtDepth(op.children, renderDepth - 1)
|
|
244
|
+
: op,
|
|
245
|
+
)
|
|
246
|
+
.flat();
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Add interactive click handlers to circuit HTML elements.
|
|
251
|
+
*
|
|
252
|
+
* @param container HTML element containing visualized circuit.
|
|
253
|
+
* @param circuit Circuit to be visualized.
|
|
254
|
+
*
|
|
255
|
+
*/
|
|
256
|
+
private addGateClickHandlers(container: HTMLElement, circuit: Circuit): void {
|
|
257
|
+
this.addClassicalControlHandlers(container);
|
|
258
|
+
this.addZoomHandlers(container, circuit);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Add interactive click handlers for classically-controlled operations.
|
|
263
|
+
*
|
|
264
|
+
* @param container HTML element containing visualized circuit.
|
|
265
|
+
*
|
|
266
|
+
*/
|
|
267
|
+
private addClassicalControlHandlers(container: HTMLElement): void {
|
|
268
|
+
container.querySelectorAll(".classically-controlled-btn").forEach((btn) => {
|
|
269
|
+
// Zoom in on clicked gate
|
|
270
|
+
btn.addEventListener("click", (evt: Event) => {
|
|
271
|
+
const textSvg = btn.querySelector("text");
|
|
272
|
+
const group = btn.parentElement;
|
|
273
|
+
if (textSvg == null || group == null) return;
|
|
274
|
+
|
|
275
|
+
const currValue = textSvg.firstChild?.nodeValue;
|
|
276
|
+
const zeroGates = group?.querySelector(".gates-zero");
|
|
277
|
+
const oneGates = group?.querySelector(".gates-one");
|
|
278
|
+
switch (currValue) {
|
|
279
|
+
case "?":
|
|
280
|
+
textSvg.childNodes[0].nodeValue = "1";
|
|
281
|
+
group.classList.remove("classically-controlled-unknown");
|
|
282
|
+
group.classList.remove("classically-controlled-zero");
|
|
283
|
+
group.classList.add("classically-controlled-one");
|
|
284
|
+
zeroGates?.classList.add("hidden");
|
|
285
|
+
oneGates?.classList.remove("hidden");
|
|
286
|
+
break;
|
|
287
|
+
case "1":
|
|
288
|
+
textSvg.childNodes[0].nodeValue = "0";
|
|
289
|
+
group.classList.remove("classically-controlled-unknown");
|
|
290
|
+
group.classList.add("classically-controlled-zero");
|
|
291
|
+
group.classList.remove("classically-controlled-one");
|
|
292
|
+
zeroGates?.classList.remove("hidden");
|
|
293
|
+
oneGates?.classList.add("hidden");
|
|
294
|
+
break;
|
|
295
|
+
case "0":
|
|
296
|
+
textSvg.childNodes[0].nodeValue = "?";
|
|
297
|
+
group.classList.add("classically-controlled-unknown");
|
|
298
|
+
group.classList.remove("classically-controlled-zero");
|
|
299
|
+
group.classList.remove("classically-controlled-one");
|
|
300
|
+
zeroGates?.classList.remove("hidden");
|
|
301
|
+
oneGates?.classList.remove("hidden");
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
evt.stopPropagation();
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Add interactive click handlers for zoom-in/out functionality.
|
|
311
|
+
*
|
|
312
|
+
* @param container HTML element containing visualized circuit.
|
|
313
|
+
* @param circuit Circuit to be visualized.
|
|
314
|
+
*
|
|
315
|
+
*/
|
|
316
|
+
private addZoomHandlers(container: HTMLElement, circuit: Circuit): void {
|
|
317
|
+
container.querySelectorAll(".gate .gate-control").forEach((ctrl) => {
|
|
318
|
+
// Zoom in on clicked gate
|
|
319
|
+
ctrl.addEventListener("click", (ev: Event) => {
|
|
320
|
+
const gateId: string | null | undefined =
|
|
321
|
+
ctrl.parentElement?.getAttribute("data-id");
|
|
322
|
+
if (typeof gateId == "string") {
|
|
323
|
+
if (ctrl.classList.contains("gate-collapse")) {
|
|
324
|
+
this.collapseOperation(circuit.operations, gateId);
|
|
325
|
+
} else if (ctrl.classList.contains("gate-expand")) {
|
|
326
|
+
this.expandOperation(circuit.operations, gateId);
|
|
327
|
+
}
|
|
328
|
+
this.renderCircuit(container, circuit);
|
|
329
|
+
|
|
330
|
+
ev.stopPropagation();
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Expand selected operation for zoom-in interaction.
|
|
338
|
+
*
|
|
339
|
+
* @param operations List of circuit operations.
|
|
340
|
+
* @param id ID of operation to expand.
|
|
341
|
+
*
|
|
342
|
+
*/
|
|
343
|
+
private expandOperation(operations: Operation[], id: string): void {
|
|
344
|
+
operations.forEach((op) => {
|
|
345
|
+
if (op.conditionalRender === ConditionalRender.AsGroup)
|
|
346
|
+
this.expandOperation(op.children || [], id);
|
|
347
|
+
if (op.dataAttributes == null) return op;
|
|
348
|
+
const opId: string = op.dataAttributes["id"];
|
|
349
|
+
if (opId === id && op.children != null) {
|
|
350
|
+
op.conditionalRender = ConditionalRender.AsGroup;
|
|
351
|
+
op.dataAttributes["expanded"] = "true";
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Collapse selected operation for zoom-out interaction.
|
|
358
|
+
*
|
|
359
|
+
* @param operations List of circuit operations.
|
|
360
|
+
* @param id ID of operation to collapse.
|
|
361
|
+
*
|
|
362
|
+
*/
|
|
363
|
+
private collapseOperation(operations: Operation[], parentId: string): void {
|
|
364
|
+
operations.forEach((op) => {
|
|
365
|
+
if (op.conditionalRender === ConditionalRender.AsGroup)
|
|
366
|
+
this.collapseOperation(op.children || [], parentId);
|
|
367
|
+
if (op.dataAttributes == null) return op;
|
|
368
|
+
const opId: string = op.dataAttributes["id"];
|
|
369
|
+
// Collapse parent gate and its children
|
|
370
|
+
if (opId.startsWith(parentId)) {
|
|
371
|
+
op.conditionalRender = ConditionalRender.Always;
|
|
372
|
+
delete op.dataAttributes["expanded"];
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Provides configuration for CSS styles of visualization.
|
|
6
|
+
*/
|
|
7
|
+
export interface StyleConfig {
|
|
8
|
+
/** Line stroke style. */
|
|
9
|
+
lineStroke?: string;
|
|
10
|
+
/** Line width. */
|
|
11
|
+
lineWidth?: number;
|
|
12
|
+
/** Text colour. */
|
|
13
|
+
textColour?: string;
|
|
14
|
+
/** Single qubit unitary fill colour. */
|
|
15
|
+
unitary?: string;
|
|
16
|
+
/** Oplus circle fill colour. */
|
|
17
|
+
oplus?: string;
|
|
18
|
+
/** Measurement gate fill colour. */
|
|
19
|
+
measure?: string;
|
|
20
|
+
/** Measurement unknown primary colour. */
|
|
21
|
+
classicalUnknown?: string;
|
|
22
|
+
/** Measurement zero primary colour. */
|
|
23
|
+
classicalZero?: string;
|
|
24
|
+
/** Measurement one primary colour. */
|
|
25
|
+
classicalOne?: string;
|
|
26
|
+
/** Measurement zero text colour */
|
|
27
|
+
classicalZeroText?: string;
|
|
28
|
+
/** Measurement one text colour */
|
|
29
|
+
classicalOneText?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const defaultStyle: StyleConfig = {
|
|
33
|
+
lineStroke: "#000000",
|
|
34
|
+
lineWidth: 1,
|
|
35
|
+
textColour: "#000000",
|
|
36
|
+
unitary: "#D9F1FA",
|
|
37
|
+
oplus: "#FFFFFF",
|
|
38
|
+
measure: "#FFDE86",
|
|
39
|
+
classicalUnknown: "#E5E5E5",
|
|
40
|
+
classicalZero: "#C40000",
|
|
41
|
+
classicalOne: "#4059BD",
|
|
42
|
+
classicalZeroText: "#FFFFFF",
|
|
43
|
+
classicalOneText: "#FFFFFF",
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const blackAndWhiteStyle: StyleConfig = {
|
|
47
|
+
lineStroke: "#000000",
|
|
48
|
+
lineWidth: 1,
|
|
49
|
+
textColour: "#000000",
|
|
50
|
+
unitary: "#FFFFFF",
|
|
51
|
+
oplus: "#FFFFFF",
|
|
52
|
+
measure: "#FFFFFF",
|
|
53
|
+
classicalUnknown: "#FFFFFF",
|
|
54
|
+
classicalZero: "#000000",
|
|
55
|
+
classicalOne: "#000000",
|
|
56
|
+
classicalZeroText: "#FFFFFF",
|
|
57
|
+
classicalOneText: "#FFFFFF",
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const invertedStyle: StyleConfig = {
|
|
61
|
+
lineStroke: "#FFFFFF",
|
|
62
|
+
lineWidth: 1,
|
|
63
|
+
textColour: "#FFFFFF",
|
|
64
|
+
unitary: "#000000",
|
|
65
|
+
oplus: "#000000",
|
|
66
|
+
measure: "#000000",
|
|
67
|
+
classicalUnknown: "#000000",
|
|
68
|
+
classicalZero: "#FFFFFF",
|
|
69
|
+
classicalOne: "#FFFFFF",
|
|
70
|
+
classicalZeroText: "#000000",
|
|
71
|
+
classicalOneText: "#000000",
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Set of default styles.
|
|
76
|
+
*/
|
|
77
|
+
export const STYLES: { [name: string]: StyleConfig } = {
|
|
78
|
+
/** Default style with coloured gates. */
|
|
79
|
+
Default: defaultStyle,
|
|
80
|
+
/** Black and white style. */
|
|
81
|
+
BlackAndWhite: blackAndWhiteStyle,
|
|
82
|
+
/** Inverted black and white style (for black backgrounds). */
|
|
83
|
+
Inverted: invertedStyle,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* CSS style script to be injected into visualization SVG.
|
|
88
|
+
*
|
|
89
|
+
* @param customStyle Custom style configuration.
|
|
90
|
+
*
|
|
91
|
+
* @returns String containing CSS style script.
|
|
92
|
+
*/
|
|
93
|
+
export const style = (customStyle: StyleConfig = {}): string => {
|
|
94
|
+
const styleConfig = { ...defaultStyle, ...customStyle };
|
|
95
|
+
|
|
96
|
+
return `${_defaultGates(styleConfig)}
|
|
97
|
+
${_classicallyControlledGates(styleConfig)}
|
|
98
|
+
${_expandCollapse}`;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const _defaultGates = (styleConfig: StyleConfig): string => `
|
|
102
|
+
line,
|
|
103
|
+
circle,
|
|
104
|
+
rect {
|
|
105
|
+
stroke: ${styleConfig.lineStroke};
|
|
106
|
+
stroke-width: ${styleConfig.lineWidth};
|
|
107
|
+
}
|
|
108
|
+
text {
|
|
109
|
+
fill: ${styleConfig.textColour};
|
|
110
|
+
dominant-baseline: middle;
|
|
111
|
+
text-anchor: middle;
|
|
112
|
+
font-family: Arial;
|
|
113
|
+
}
|
|
114
|
+
.control-dot {
|
|
115
|
+
fill: ${styleConfig.lineStroke};
|
|
116
|
+
}
|
|
117
|
+
.oplus line, .oplus circle {
|
|
118
|
+
fill: ${styleConfig.oplus};
|
|
119
|
+
stroke-width: 2;
|
|
120
|
+
}
|
|
121
|
+
.gate-unitary {
|
|
122
|
+
fill: ${styleConfig.unitary};
|
|
123
|
+
}
|
|
124
|
+
.gate-measure {
|
|
125
|
+
fill: ${styleConfig.measure};
|
|
126
|
+
}
|
|
127
|
+
rect.gate-swap {
|
|
128
|
+
fill: transparent;
|
|
129
|
+
stroke: transparent;
|
|
130
|
+
}
|
|
131
|
+
.arc-measure {
|
|
132
|
+
stroke: ${styleConfig.lineStroke};
|
|
133
|
+
fill: none;
|
|
134
|
+
stroke-width: ${styleConfig.lineWidth};
|
|
135
|
+
}
|
|
136
|
+
.register-classical {
|
|
137
|
+
stroke-width: ${(styleConfig.lineWidth || 0) / 2};
|
|
138
|
+
}`;
|
|
139
|
+
|
|
140
|
+
const _classicallyControlledGates = (styleConfig: StyleConfig): string => {
|
|
141
|
+
const gateOutline = `
|
|
142
|
+
.classically-controlled-one .classical-container,
|
|
143
|
+
.classically-controlled-one .classical-line {
|
|
144
|
+
stroke: ${styleConfig.classicalOne};
|
|
145
|
+
stroke-width: ${(styleConfig.lineWidth || 0) + 0.3};
|
|
146
|
+
fill: ${styleConfig.classicalOne};
|
|
147
|
+
fill-opacity: 0.1;
|
|
148
|
+
}
|
|
149
|
+
.classically-controlled-zero .classical-container,
|
|
150
|
+
.classically-controlled-zero .classical-line {
|
|
151
|
+
stroke: ${styleConfig.classicalZero};
|
|
152
|
+
stroke-width: ${(styleConfig.lineWidth || 0) + 0.3};
|
|
153
|
+
fill: ${styleConfig.classicalZero};
|
|
154
|
+
fill-opacity: 0.1;
|
|
155
|
+
}`;
|
|
156
|
+
const controlBtn = `
|
|
157
|
+
.classically-controlled-btn {
|
|
158
|
+
cursor: pointer;
|
|
159
|
+
}
|
|
160
|
+
.classically-controlled-unknown .classically-controlled-btn {
|
|
161
|
+
fill: ${styleConfig.classicalUnknown};
|
|
162
|
+
}
|
|
163
|
+
.classically-controlled-one .classically-controlled-btn {
|
|
164
|
+
fill: ${styleConfig.classicalOne};
|
|
165
|
+
}
|
|
166
|
+
.classically-controlled-zero .classically-controlled-btn {
|
|
167
|
+
fill: ${styleConfig.classicalZero};
|
|
168
|
+
}`;
|
|
169
|
+
|
|
170
|
+
const controlBtnText = `
|
|
171
|
+
.classically-controlled-btn text {
|
|
172
|
+
dominant-baseline: middle;
|
|
173
|
+
text-anchor: middle;
|
|
174
|
+
stroke: none;
|
|
175
|
+
font-family: Arial;
|
|
176
|
+
}
|
|
177
|
+
.classically-controlled-unknown .classically-controlled-btn text {
|
|
178
|
+
fill: ${styleConfig.textColour};
|
|
179
|
+
}
|
|
180
|
+
.classically-controlled-one .classically-controlled-btn text {
|
|
181
|
+
fill: ${styleConfig.classicalOneText};
|
|
182
|
+
}
|
|
183
|
+
.classically-controlled-zero .classically-controlled-btn text {
|
|
184
|
+
fill: ${styleConfig.classicalZeroText};
|
|
185
|
+
}`;
|
|
186
|
+
|
|
187
|
+
return `
|
|
188
|
+
.hidden {
|
|
189
|
+
display: none;
|
|
190
|
+
}
|
|
191
|
+
.classically-controlled-unknown {
|
|
192
|
+
opacity: 0.25;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
${gateOutline}
|
|
196
|
+
${controlBtn}
|
|
197
|
+
${controlBtnText}`;
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const _expandCollapse = `
|
|
201
|
+
.qviz .gate-collapse,
|
|
202
|
+
.qviz .gate-expand {
|
|
203
|
+
opacity: 0;
|
|
204
|
+
transition: opacity 1s;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.qviz:hover .gate-collapse,
|
|
208
|
+
.qviz:hover .gate-expand {
|
|
209
|
+
visibility: visible;
|
|
210
|
+
opacity: 0.2;
|
|
211
|
+
transition: visibility 1s;
|
|
212
|
+
transition: opacity 1s;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.gate-expand, .gate-collapse {
|
|
216
|
+
cursor: pointer;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.gate-collapse circle,
|
|
220
|
+
.gate-expand circle {
|
|
221
|
+
fill: white;
|
|
222
|
+
stroke-width: 2px;
|
|
223
|
+
stroke: black;
|
|
224
|
+
}
|
|
225
|
+
.gate-collapse path,
|
|
226
|
+
.gate-expand path {
|
|
227
|
+
stroke-width: 4px;
|
|
228
|
+
stroke: black;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.gate:hover > .gate-collapse,
|
|
232
|
+
.gate:hover > .gate-expand {
|
|
233
|
+
visibility: visible;
|
|
234
|
+
opacity: 1;
|
|
235
|
+
transition: opacity 1s;
|
|
236
|
+
}`;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
|
|
4
|
+
import { Metadata, GateType } from "./metadata";
|
|
5
|
+
import {
|
|
6
|
+
minGateWidth,
|
|
7
|
+
labelPadding,
|
|
8
|
+
labelFontSize,
|
|
9
|
+
argsFontSize,
|
|
10
|
+
} from "./constants";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Generate a UUID using `Math.random`.
|
|
14
|
+
* Note: this implementation came from https://stackoverflow.com/questions/105034/how-to-create-guid-uuid
|
|
15
|
+
* and is not cryptographically secure but works for our use case.
|
|
16
|
+
*
|
|
17
|
+
* @returns UUID string.
|
|
18
|
+
*/
|
|
19
|
+
const createUUID = (): string =>
|
|
20
|
+
"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
|
|
21
|
+
const r = (Math.random() * 16) | 0,
|
|
22
|
+
v = c == "x" ? r : (r & 0x3) | 0x8;
|
|
23
|
+
return v.toString(16);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Calculate the width of a gate, given its metadata.
|
|
28
|
+
*
|
|
29
|
+
* @param metadata Metadata of a given gate.
|
|
30
|
+
*
|
|
31
|
+
* @returns Width of given gate (in pixels).
|
|
32
|
+
*/
|
|
33
|
+
const getGateWidth = ({
|
|
34
|
+
type,
|
|
35
|
+
label,
|
|
36
|
+
displayArgs,
|
|
37
|
+
width,
|
|
38
|
+
}: Metadata): number => {
|
|
39
|
+
if (width > 0) return width;
|
|
40
|
+
|
|
41
|
+
switch (type) {
|
|
42
|
+
case GateType.Measure:
|
|
43
|
+
case GateType.Cnot:
|
|
44
|
+
case GateType.Swap:
|
|
45
|
+
return minGateWidth;
|
|
46
|
+
default: {
|
|
47
|
+
const labelWidth = _getStringWidth(label);
|
|
48
|
+
const argsWidth =
|
|
49
|
+
displayArgs != null ? _getStringWidth(displayArgs, argsFontSize) : 0;
|
|
50
|
+
const textWidth = Math.max(labelWidth, argsWidth) + labelPadding * 2;
|
|
51
|
+
return Math.max(minGateWidth, textWidth);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Get the width of a string with font-size `fontSize` and font-family Arial.
|
|
58
|
+
*
|
|
59
|
+
* @param text Input string.
|
|
60
|
+
* @param fontSize Font size of `text`.
|
|
61
|
+
*
|
|
62
|
+
* @returns Pixel width of given string.
|
|
63
|
+
*/
|
|
64
|
+
const _getStringWidth = (
|
|
65
|
+
text: string,
|
|
66
|
+
fontSize: number = labelFontSize,
|
|
67
|
+
): number => {
|
|
68
|
+
const canvas: HTMLCanvasElement = document.createElement("canvas");
|
|
69
|
+
const context: CanvasRenderingContext2D | null = canvas.getContext("2d");
|
|
70
|
+
if (context == null) throw new Error("Null canvas");
|
|
71
|
+
|
|
72
|
+
context.font = `${fontSize}px Arial`;
|
|
73
|
+
const metrics: TextMetrics = context.measureText(text);
|
|
74
|
+
return metrics.width;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export { createUUID, getGateWidth, _getStringWidth };
|
package/ux/circuit.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
3
|
|
|
4
|
-
import * as qviz from "
|
|
4
|
+
import * as qviz from "./circuit-vis";
|
|
5
5
|
import { useEffect, useRef, useState } from "preact/hooks";
|
|
6
6
|
import { CircuitProps } from "./data.js";
|
|
7
7
|
import { Spinner } from "./spinner.js";
|
|
@@ -131,7 +131,7 @@ function ZoomableCircuit(props: { circuit: qviz.Circuit }) {
|
|
|
131
131
|
function renderCircuit(circuit: qviz.Circuit, container: HTMLDivElement) {
|
|
132
132
|
qviz.draw(circuit, container);
|
|
133
133
|
|
|
134
|
-
//
|
|
134
|
+
// circuit-vis hardcodes the styles in the SVG.
|
|
135
135
|
// Remove the style elements -- we'll define the styles in our own CSS.
|
|
136
136
|
const styleElements = container.querySelectorAll("style");
|
|
137
137
|
styleElements?.forEach((tag) => tag.remove());
|
package/ux/data.ts
CHANGED