%This is the quantikz library for typesetting quantum circuits using LaTeX/Tikz. version 0.9.8
% Written by Alastair Kay, 2018. Published under a CC-BY-4.0 licence
% Please email me ([email protected]) with any bug reports or feature requests.
% If you find this library useful, please cite its usage in your work, using arXiv:1809.03842, and possibly the DOI: 10.17637/rh.7000520.
% Usage is at your own risk.

%version 0.9.8 (not yet released)
%added \multimeter and \multimeterD. Multi qubit versions of \meter and \meterD command. Arguments directly mirror those of \gate, except that style={} parameter in first optional argument does not work. Instead, these are provided as an extra optiona parameter (the second). Updated the drawing to respect this better.
%drawing function of meterD now accepts commands such as "rectangle with rounded corners north west=20pt" to control rounding of individual corners of node
%added \permute command. Experimental - I'm not confident that the wire crossings will look good in all situations.
%fixed a bug spotted by Stefan Krastanov about spacing that particularly affects transparent gates.
%fixed a bug spotted by Leo Colisson about spacing
%       added \forceredefine if you prefer my bra, ket etc to ones given in other packages
%       added pswap[i]{j} command. Similar to \swap{i} but now has label j in a circle. Only works well if i is odd. Draw order issue with even i.
%       I've altered a few options such that transparency is applied more uniformly and line colours are inherited better. Background colours of items now derived from tikzcd parameter in \pgfkeysvalueof{/tikz/commutative diagrams/background color}.
%version 0.9.7
%       added a parameter \ctrlbundle[3]{}. This lets you control off classical wires.
%version 0.9.6:
%       changed packaging so there isn't a compile warning any more
%       modified the meter command so that \meter[draw=blue]{} colours everything blue, not just outline.
%       added trash command
%       added \ctrlbundle command so that \ctrl works well with \qwbundle[alternate]. If you supple \ctrlbundle[2]{}, then the bundle only contains 2 wires instead of the default of 3
%       \qwbundle[alternate] now also works with the parameter \qwbundle[alternate=2] to only have 2 wires in the bundle.
%       added \midstick. Works a bit like rstick and lstick, but reserves space for the text. Can choose to have brackets=none|left|right|both (default is both). Gives better method for circuit identities and other things.
%       added "align equals at" key for setting circuit identities (specifies wire number that should line up with equals. can be non-integer)
%       added makeebit command. accepts one parameter which is the text. Haven't got tyling and different angles of the split working yet.
%   added bundle option to supplement nwires and cwires.
%       fixed bug where you couldn't put a wire command after the declaration of a multi-qubit gate command.
%version 0.9.5:
%       fixed bug which meant multi-wire gates didn't work outside of an environment such as center.
%version 0.9.4:
%       added nwires and cwires options to gate command to simulate qcircuit's nphantom and cphantom
%       vertical text options for slice labels.
%       replaced macro for measuring width and height for greater reliability. disable auto spacing now unnecessary as things like \sqrt{} work in the gate label.
%       investigated possibility of high labels (multi-line labels, particularly for a multi-qubit gate). key disable auto height introduced.
%       now provides a quantikz environment, which is theoretically compatible with tikz' external library (entirely untested). Can still use tikzcd environment otherwise.
%       removed a tikzcd customisation fixing the baseline for one row circuits as this was messing with any manual attempts to adjust the baseline.
%version 0.9.3:
%       adjusted spacing of gate operation between in-circuit and overlay so that transparency looks better
%       Other gate spacing adjustments. multi-qubit gates in particular should look better. 'disable auto spacing' can switch this off, particularly for use with things like \sqrt{} in the multi-qubit gate label, which will throw a weird error.
%       gate command now takes two further optional parameters: minimum width and minimum height for each cell.
%       some consolidation of styling commands
%       global keys 'transparent' and 'thin lines' added. 'thin lines' gives a look more similar to the original QCircuit.
%version 0.9.2:
%       made 'wires' the default key, so [wires=2] now becomes [2]
%       added 'slice title', 'slices style', 'slices label style' key to control titles of slices under 'slice all'
%       better access to positioning of gategroup label.
%       now arXiv compatible (that was a challenge! they use old versions of packages)
%Previous versions:
%version 0.9.1:
%       added \cwbend gate for cornering classical wires.
%       made size of strike through for multiqubit gates stylable via the keys /quantikz/Strike Height/ and /quantikz/Strike Width/
%       added new \gate[swap] variant of swap (nearest-neighbour only).
%version 0.9.0:
%original release.

%\ProvidesPackage{quantikz}[2020/04/27 typeset quantum circuit diagrams]

% Package(s) to include
\RequirePackage{xargs,ifthen,xstring,xparse,etoolbox,mathtools,pgfmath}
\RequirePackage{environ} %in an attempt to help with compatibility with the external library of tikz.
%\RequirePackage{tikz}
\usetikzlibrary{cd,decorations.pathreplacing,calc,positioning,fit,shapes.symbols,decorations.pathmorphing,shapes.misc,backgrounds,decorations.markings,math}

\PackageWarning{quantikz}{You are using an old version of quantikz. Please update your command to "quantikz2".}

\newlength{\myl}
\newlength{\myh}
\newlength{\myd}

%\makeatletter
\newcounter{aaa}
\tikzset{
 apply/.style args={#1 except on segments #2}{postaction={
     /utils/exec={
       \@for\mattempa:=#2\do{\csdef{aaa@\mattempa}{}}
       \setcounter{aaa}{0}
     },
     decorate,decoration={show path construction,
       moveto code={},
       lineto code={
         \stepcounter{aaa}
         \ifcsdef{aaa@\theaaa}{}{
           \path[#1] (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
         }
       },
       curveto code={
         \stepcounter{aaa}
         \ifcsdef{aaa@\theaaa}{}{
           \path [#1] (\tikzinputsegmentfirst) .. controls
           (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
           ..(\tikzinputsegmentlast);
         }
       },
       closepath code={
         \stepcounter{aaa}
         \ifcsdef{aaa@\theaaa}{}{
           \path [#1] (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
         }
       },
     },
   },
 },
}
%test if item is in list of item. Probably better ways to do this, but I could get this version to work.
\newcommand*{\IfInList}[2]{%
       \gdef\memory{0}
       \edef\arg{#1}
        \foreach \q in #2 {%
               \ifthenelse{\q=\arg}{%
                       \gdef\memory{1}
               }{}
        }
       \ifthenelse{\memory=1} {%
               \expandafter\@firstoftwo
       }{%
               \expandafter\@secondoftwo
       }
}
%define the quantikz environment. I need this to facilitate the external library
\NewEnviron{quantikz}[1][]{%
 \def\@temp{\tikzcd@[#1]\BODY}%
 \expandafter\@temp\endtikzcd
}
\def\temp{&} \catcode`&=\active \let&=\temp
%
%commands for putting in text vertically
\protected\def\vvv#1{\leavevmode\bgroup\vbox\bgroup\xvvv#1\relax}
%
\def\xvvv{\afterassignment\xxvvv\let\tmp= }
%
\def\xxvvv{%
% \ifx\tmp\@sptoken\egroup\ \vbox\bgroup\let\next\xvvv
% \else
\ifx\tmp\relax\egroup\egroup\let\next\relax
\else
\hbox to 1.1em{\hfill\tmp\hfill}% centred
\let\next\xvvv\fi%\fi
\next}
%end of commands for putting text vertically
%
\long\def\ifnodedefined#1#2#3{%
   \@ifundefined{pgf@sh@ns@#1}{#3}{#2}%
}
%I don't think this is used any more
% \newcommand\getwidth[1]{
%       \pgfkeys{minimum width=0pt}%
%       \pgfkeys{/quantikz,#1}
%       \pgfkeysgetvalue{/quantikz/minimum width}{\minwidth}
%       \minwidth
% }

%find the vertical position of the middle of an equals sign
%https://tex.stackexchange.com/questions/355680/how-can-i-vertically-align-an-equals-sign-in-a-tikz-node/355686
\pgfmathsetmacro\MathAxis{height("$\vcenter{}$")}
\newcounter{wirenumberpermute}

\newcommand{\permute}[1]{%
\hphantom{Wide}%
\def\firstlist{#1}
       \edef\n{\the\pgfmatrixcurrentrow} %the row
       \edef\m{\the\pgfmatrixcurrentcolumn} %the column
       \edef\mn{\the\numexpr\m-1\relax}
       \edef\mp{\the\numexpr\m+1\relax}
       \settowidth{\myl}{$Wide$}
       \setcounter{wirenumberpermute}{0}
       \foreach \x [count=\c] in \firstlist {%
               \edef\start{\the\numexpr\c+\n-1\relax}%
               \edef\endy{\the\numexpr\x+\n-1\relax}%
               %apply auto width to the cell, and make sure we unset the setting so that it doesn't apply to later circuits.
               %I think use of globaldefs in this way is very slow, but I don't know of a better way.
               \globaldefs=1%
               \edef\dotikzset{\noexpand\tikzset{row \start\space column \m/.append style={minimum width={\the\myl}}}}%
               \dotikzset%
               \edef\undotikzset{\noexpand\tikzset{row \start\space column \m/.style={}}}%
   \expandafter\pgfutil@g@addto@macro\expandafter\tikzcd@atendglobals\expandafter{\undotikzset}%
   \globaldefs=0%
               \stepcounter{wirenumberpermute}
               }
               \expandafter\expandafter\expandafter\pgfutil@g@addto@macro\expandafter\expandafter\expandafter\tikzcd@atendsavedpaths\expandafter\expandafter\expandafter{%
               \expandafter\expandafter\expandafter\wirepair@end\expandafter\expandafter\expandafter{\expandafter\n\expandafter}\expandafter{\m}{#1}%
               }
       \edef\lim{\the\numexpr\arabic{wirenumberpermute}+\n-1\relax}
               \foreach \i in {\n,...,\lim} {%
            \edef\newcom{\noexpand\vqwexplicit{\i-\m}{\i-\mn}}
                        \newcom%
               }
}

\newcommand{\wirepair@end}[3]{%#row,col of left-most site. #row of right-most site.
       \xdef\LoopGG{}
       \edef\i{#1}
       \def\firstlist{#3}
       %\show\i
       %\show\j
       %create a list of cell names to be included in this grouped gate
       \foreach \n in \firstlist {%
       \ifnodedefined{\tikzcdmatrixname-\the\numexpr\n+\i-1\relax-#2}{%
               \xdef\LoopGG{\LoopGG(\tikzcdmatrixname-\the\numexpr\n+\i-1\relax-#2)}
               }{}
       }
       \ifnodedefined{\tikzcdmatrixname-\i-#2}{%
               \xdef\LoopGG{\LoopGG(\tikzcdmatrixname-\i-#2)}
               }{}
       \node (group\tikzcdmatrixname-#1-#2) [fit=\LoopGG,transparent,inner sep=0pt] {\phantom{Wide}};
               \foreach \n [count=\c] in \firstlist{%
                       \draw [line width=3pt,\pgfkeysvalueof{/tikz/commutative diagrams/background color},shorten >=0.9pt,shorten <=0.9pt] (group\tikzcdmatrixname-#1-#2.west|-\tikzcdmatrixname-\the\numexpr\i+\c-1\relax-#2.center) to[out=0,in=180] (group\tikzcdmatrixname-#1-#2.east|-\tikzcdmatrixname-\the\numexpr\i+\n-1\relax-#2.center);
                       \draw [thickness] (group\tikzcdmatrixname-#1-#2.west|-\tikzcdmatrixname-\the\numexpr\i+\c-1\relax-#2.center) to[out=0,in=180] (group\tikzcdmatrixname-#1-#2.east|-\tikzcdmatrixname-\the\numexpr\i+\n-1\relax-#2.center);
               }
}

\DeclareExpandableDocumentCommand{\multimeter}{O{}O{}O{1.5pt}O{1.5pt}m}{
\gate[style={meter,inner sep=0,#2},#1][#3][#4]{#5}
}
\DeclareExpandableDocumentCommand{\multimeterD}{O{}O{}O{1.5pt}O{1.5pt}m}{%
% \pgfkeys{/quantikz,#1}%
% \pgfkeysgetvalue{/quantikz/style}{\a}%
\gate[#1,style={meterD,inner sep=0,#2}][#3][#4]{#5}
}

%the main gate command
\DeclareExpandableDocumentCommand{\gate}{O{}O{1.5pt}O{1.5pt}m}{%optional parameter contains styling info. compulsory is gate text.
       |[inner sep=4pt,minimum width=#2,minimum height=#3]|%
       \edef\n{\the\pgfmatrixcurrentrow} %the row
       \edef\m{\the\pgfmatrixcurrentcolumn} %the column
       %reset macros that are going to be set by the options
       \edef\options{row=\n,col=\m,#1}
       \def\toswap{0}%
       \def\DisableMinSize{0}%
       %\pgfkeys{/quantikz,wires=1,style=,label style=,braces=}%
       %import options passed as parameters
       \pgfkeys{/quantikz,wires=1,style=,label style=,braces=,#1}%
       \pgfkeysgetvalue{/quantikz/wires}{\quantwires}
       \pgfkeysgetvalue{/quantikz/style}{\a}
       \pgfkeysgetvalue{/quantikz/label style}{\b}
       \pgfkeysgetvalue{/quantikz/cwires}{\mylist}
       \pgfkeysgetvalue{/quantikz/nwires}{\nowires}
       \pgfkeysgetvalue{/quantikz/bundle}{\bundle}
       \ifthenelse{\toswap=1}{%if it's a swap gate...
               \pgfkeys{/quantikz,wires=2}
               \def\quantwires{2}
               \phantom{wide}
               \settowidth{\myl}{$wide$}
               \settoheight{\myh}{$wide$}
               \settodepth{\myd}{$wide$}
       }{%not a swap gate
               \settowidth{\myl}{$#4$}
               \ifthenelse{\DisableMinSize=1}{%disable automatic size detection. Use $U$ instead.
                       \phantom{U}
                       \settoheight{\myh}{$U$}
                       \settodepth{\myd}{$U$}
               }{%automatically get width and height of label
                       \phantom{#4}
                       \settoheight{\myh}{$#4$}
                       \settodepth{\myd}{$#4$}
               }
       }
%
       \IfInList{1}{\mylist}{\cw}{\IfInList{1}{\nowires}{}{\IfInList{1}{\bundle}{\qwbundle[alternate]{}}{\qw}}}%do we need classical, no wire, or quantum wire?
       \edef\k{\the\numexpr\n+\quantwires-1\relax}
       \edef\mn{\the\numexpr\m-1\relax}
       \ifthenelse{\quantwires=1}{}{%more than 1 wire on gate. iterate through each wire
       \foreach \i in {\the\numexpr\n+1\relax,...,\k} {
           \edef\newcom{\noexpand\vcwhexplicit{\i-\m}{\i-\mn}}
       \edef\newcomb{\noexpand\vqwexplicit{\i-\m}{\i-\mn}}
       \edef\newcomc{\noexpand\vqbundleexplicit{\i-\m}{\i-\mn}}
               \edef\val{\the\numexpr\i+1-\n\relax}
               \IfInList{\val}{\mylist}{\newcom}{\IfInList{\val}{\nowires}{}{\IfInList{\val}{\bundle}{\newcomc}{\newcomb}}}%do we need classical, no wire, or quantum wire?
               %apply auto width to the cell, and make sure we unset the setting so that it doesn't apply to later circuits.
               %I think use of globaldefs in this way is very slow, but I don't know of a better way.
               \globaldefs=1
               \edef\dotikzset{\noexpand\tikzset{row \i\space column \m/.append style={minimum width={max(\the\myl+8pt,#2)}}}}%
               \dotikzset%
               \edef\undotikzset{\noexpand\tikzset{row \i\space column \m/.style={}}}%
       \expandafter\pgfutil@g@addto@macro\expandafter\tikzcd@atendglobals\expandafter{\undotikzset}%
       }
                       %apply auto height to last row only. unsetting already handled above.
                  \globaldefs=1%
                  \edef\dotikzset{\noexpand\tikzset{row \k\space column \m/.append style={minimum height={max(\the\myh+\the\myd+8pt,#3)}}}}%
                  \dotikzset%
                  \globaldefs=0%
%
       }
       %call deferred gate command. to be executed after the tikzcd matrix stuff is completed
       \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfutil@g@addto@macro\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\tikzcd@atendsavedpaths\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{%
               \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\gate@end\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\a\expandafter\expandafter\expandafter}\expandafter\expandafter\expandafter{\expandafter\b\expandafter}\expandafter{\options}{#4}
       }
}

%deferred gate command. draws a box around all included cells. this is not part of the matrix, but comes afterwards.
\newcommand{\gate@end}[4]{
       \pgfkeys{/quantikz,wires=1}
       \def\toswap{0}
       \def\DisableMinSize{0}
       \pgfkeys{/quantikz,#3}%import options
       \pgfkeysgetvalue{/quantikz/wires}{\quantwires}
       \pgfkeysgetvalue{/quantikz/row}{\row}
       \pgfkeysgetvalue{/quantikz/col}{\col}
       \ifthenelse{\toswap=1}{\def\quantwires{2}}{}
       \xdef\LoopGG{}
       %create a list of cell names to be included in this grouped gate
       \foreach \n in  {\row,...,\the\numexpr\row+\quantwires-1\relax} {
       \ifnodedefined{\tikzcdmatrixname-\n-\col}{
               \xdef\LoopGG{\LoopGG(\tikzcdmatrixname-\n-\col)}
               }{}
       }
       \ifthenelse{\toswap=1}{
               \node (group\tikzcdmatrixname-\row-\col) [fit=\LoopGG,operator,inner sep=0pt,#1] {\hphantom{Wide}};
               \draw [thickness] (group\tikzcdmatrixname-\row-\col.west|-\tikzcdmatrixname-\row-\col.center) to[out=0,in=180] (group\tikzcdmatrixname-\row-\col.east|-\tikzcdmatrixname-\the\numexpr\row+1\relax-\col.center);
               \draw [line width=3pt,\pgfkeysvalueof{/tikz/commutative diagrams/background color},shorten >=0.9pt,shorten <=0.9pt] (group\tikzcdmatrixname-\row-\col.east|-\tikzcdmatrixname-\row-\col.center) to[out=180,in=0] (group\tikzcdmatrixname-\row-\col.west|-\tikzcdmatrixname-\the\numexpr\row+1\relax-\col.center);
               \draw [thickness] (group\tikzcdmatrixname-\row-\col.east|-\tikzcdmatrixname-\row-\col.center) to[out=180,in=0] (group\tikzcdmatrixname-\row-\col.west|-\tikzcdmatrixname-\the\numexpr\row+1\relax-\col.center);
       }{
       %the actual gate drawing command
         \node (group\tikzcdmatrixname-\row-\col) [fit=\LoopGG,operator,inner sep=0pt,label={[gg label,#2]$#4$},#1] {\hphantom{$#4$}};
       }
}

%ghost will get height correct if can't be automatically assigned.
\DeclareExpandableDocumentCommand{\ghost}{O{}O{0pt}O{1.5pt}m}{%optional parameter contains styling info. compulsory is gate text.
       |[inner ysep=4pt,minimum width=#2,minimum height=#3]| \vphantom{#4}
}


%single slice
\newcommand\slice[2][]{%
       %\edef\currcol{\the\pgfmatrixcurrentcolumn}
       \pgfkeys{/quantikz,wires=1,style=,label style=,braces=}
       \pgfkeys{/quantikz,#1}%
       \edef\options{\pgfkeysvalueof{/quantikz/style}}
       \edef\opts{\pgfkeysvalueof{/quantikz/label style}}
       \edef\n{\the\pgfmatrixcurrentcolumn}
       %\expandafter\show\n
       \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfutil@g@addto@macro\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\tikzcd@atendslices\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{%
               \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\slice@end\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\n\expandafter\expandafter\expandafter}\expandafter\expandafter\expandafter{\expandafter\options\expandafter}\expandafter{\opts}{#2}%
       }}
%deferred slice command
\newcommand{\slice@end}[4]{
       \edef\top{($1/2*(\tikzcdmatrixname-col#1.east |- \tikzcdmatrixname-row1.north)+1/2*(\tikzcdmatrixname-col\the\numexpr#1+1\relax.west |- \tikzcdmatrixname-row1.north)$)}
       \edef\bottom{($1/2*(\tikzcdmatrixname-col#1.east |- \tikzcdmatrixname-row\the\pgfmatrixcurrentrow.south)+1/2*(\tikzcdmatrixname-col\the\numexpr#1+1\relax.west |- \tikzcdmatrixname-row\the\pgfmatrixcurrentrow.south)+(0,-3pt)$)}
       \expandafter\expandafter\expandafter\make@slice\expandafter\expandafter\expandafter{\expandafter\top\expandafter}\expandafter{\bottom}{#4}{#2}{#3}
}
\newcommand{\make@slice}[5]{
       \draw[slice,#4] #1 to node[pos=0,inner sep=4pt,anchor=south,color=black,#5] {#3} #2;
}
%deferred command which will slice everything
\newcommand{\sliceallr}{
       \edef\sstyle{\pgfkeysvalueof{/tikz/slice style}}
       \edef\slstyle{\pgfkeysvalueof{/tikz/slice label style}}
       \foreach \n in  {2,...,\the\numexpr\pgfmatrixcurrentcolumn-1-\pgfkeysvalueof{/tikz/remove end slices}\relax} {
               \edef\col{\the\numexpr\n-1\relax}
               \edef\title{\pgfkeysvalueof{/tikz/slice titles}}
               \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\slice@end\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\n\expandafter\expandafter\expandafter}\expandafter\expandafter\expandafter{\expandafter\sstyle\expandafter}\expandafter{\slstyle}{\title}
       }
}
%deferred slice command with vertical text
\newcommand{\sliceallvr}{
       \edef\sstyle{\pgfkeysvalueof{/tikz/slice style}}
       \edef\slstyle{\pgfkeysvalueof{/tikz/slice label style}}
       \foreach \n in  {2,...,\the\numexpr\pgfmatrixcurrentcolumn-1-\pgfkeysvalueof{/tikz/remove end slices}\relax} {
               \edef\col{\the\numexpr\n-1\relax}
               \edef\title{\vvv{\pgfkeysvalueof{/tikz/slice titles}}}
               \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\slice@end\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\n\expandafter\expandafter\expandafter}\expandafter\expandafter\expandafter{\expandafter\sstyle\expandafter}\expandafter{\slstyle}{\title}
       }
}

%labelling of inputs
\newcommand\lstick[2][]{%
       \pgfkeys{/quantikz,wires=1,style=,label style=,braces=}
       \pgfkeys{/quantikz,#1}%
       \edef\newoptions{row=\the\pgfmatrixcurrentrow,col=\the\pgfmatrixcurrentcolumn,#1}
       \pgfkeysgetvalue{/quantikz/label style}{\options}
       \pgfkeysgetvalue{/quantikz/braces}{\opts}
       %\edef\n{\the\pgfmatrixcurrentrow}
       %\edef\m{\the\pgfmatrixcurrentcolumn}
       \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfutil@g@addto@macro\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\tikzcd@atendsavedpaths\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{%
               \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\groupinput@end\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\newoptions\expandafter\expandafter\expandafter}\expandafter\expandafter\expandafter{\expandafter\options\expandafter}\expandafter{\opts}{#2}%
       }
}
%labelling of outputs
\newcommand\rstick[2][]{%
       \pgfkeys{/quantikz,wires=1,style=,label style=,braces=}
       \pgfkeys{/quantikz,#1}%
       \edef\newoptions{row=\the\pgfmatrixcurrentrow,col=\the\pgfmatrixcurrentcolumn,#1}
       \pgfkeysgetvalue{/quantikz/label style}{\options}
       \pgfkeysgetvalue{/quantikz/braces}{\opts}
       %\edef\n{\the\pgfmatrixcurrentrow}
       %\edef\m{\the\pgfmatrixcurrentcolumn}
       \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfutil@g@addto@macro\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\tikzcd@atendsavedpaths\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{%
               \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\groupoutput@end\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\newoptions\expandafter\expandafter\expandafter}\expandafter\expandafter\expandafter{\expandafter\options\expandafter}\expandafter{\opts}{#2}%
       }
}

\newcommand\midstick[2][]{%
       \hphantom{\text{g#2g}}\ %leave enough space for whatever text we've inserted
       \pgfkeys{/quantikz,wires=1,style=,label style=,braces=}
       \pgfkeys{/quantikz,#1}%
       \edef\newoptions{row=\the\pgfmatrixcurrentrow,col=\the\pgfmatrixcurrentcolumn,#1}
       \pgfkeysgetvalue{/quantikz/wires}{\quantwires}
       \pgfkeysgetvalue{/quantikz/label style}{\options}
       \pgfkeysgetvalue{/quantikz/braces}{\opts}
        \edef\n{\the\pgfmatrixcurrentrow} %the row
       \edef\m{\the\pgfmatrixcurrentcolumn} %the column
       \edef\mn{\the\numexpr\m-1\relax}
       \edef\k{\the\numexpr\n+\quantwires-1\relax}
       \settowidth{\myl}{g#2g}
       %if more than 1 wire, need to reserve space for each wire
       \ifthenelse{\quantwires=1}{}{
               \foreach \i in {\the\numexpr\n+1\relax,...,\k} {
               \edef\val{\the\numexpr\i+1-\n\relax}
               %apply auto width to the cell, and make sure we unset the setting so that it doesn't apply to later circuits.
               %I think use of globaldefs in this way is very slow, but I don't know of a better way.
               \globaldefs=1
               \edef\dotikzset{\noexpand\tikzset{row \i\space column \m/.append style={minimum width={\the\myl}}}}
               \dotikzset
               \edef\undotikzset{\noexpand\tikzset{row \i\space column \m/.style={}}}
       \expandafter\pgfutil@g@addto@macro\expandafter\tikzcd@atendglobals\expandafter{\undotikzset}
       \globaldefs=0
       }
%
       }
       %\edef\n{\the\pgfmatrixcurrentrow}
       %\edef\m{\the\pgfmatrixcurrentcolumn}
       \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfutil@g@addto@macro\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\tikzcd@atendsavedpaths\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{%
               \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\groupoutput@mid\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\newoptions\expandafter\expandafter\expandafter}\expandafter\expandafter\expandafter{\expandafter\options\expandafter}\expandafter{\opts}{#2}%
       }
}
%deferred labelling of inputs
\newcommand{\groupinput@end}[4]{%basic data as keys, lable options, brace options, text
       \pgfkeys{/quantikz,wires=1}
       \pgfkeys{/quantikz,#1}%
       \pgfkeysgetvalue{/quantikz/wires}{\quantwires}
       \pgfkeysgetvalue{/quantikz/row}{\row}
       \pgfkeysgetvalue{/quantikz/col}{\col}
       \xdef\LoopGI{}
       \foreach \n in  {\row,...,\the\numexpr\row+\quantwires-1\relax} {
       \ifnodedefined{\tikzcdmatrixname-\n-\col}{
               \xdef\LoopGI{\LoopGI(\tikzcdmatrixname-\n-\col)}
               }{}
               }
       \ifthenelse{\quantwires=1} {
               \node (ingr-\row) [fit=\LoopGI, inner sep=0pt,label={[align=center,#2]left:#4}] {};
       }{
       \node (ingr-\row) [fit=\LoopGI, inner sep=0pt] {};
       \draw[dm,#3] ($(ingr-\row.north west)+(-0.1cm,0.1cm)$) to node[midway,align=center,anchor=east,xshift=-0.1cm,#2] {#4} ($(ingr-\row.south west)+(-0.1cm,-0.1cm)$);
       }
} %
%deferred labelling of outputs
\newcommand{\groupoutput@end}[4]{%basic data as keys, label options, brace options, text
       \pgfkeys{/quantikz,wires=1}
       \pgfkeys{/quantikz,#1}%
       \pgfkeysgetvalue{/quantikz/wires}{\quantwires}
       \pgfkeysgetvalue{/quantikz/row}{\row}
       \pgfkeysgetvalue{/quantikz/col}{\col}
       \xdef\LoopGO{}
       \foreach \n in  {\row,...,\the\numexpr\row+\quantwires-1\relax} {
               \ifnodedefined{\tikzcdmatrixname-\n-\col}{
                       \xdef\LoopGO{\LoopGO(\tikzcdmatrixname-\n-\col)}
               }}
               \ifthenelse{\quantwires=1} {
               \node (outgr-\row) [fit=\LoopGO, inner sep=0pt,label={[align=center,#2]right:#4}] {};
       }{
       \node (outgr-\row) [fit=\LoopGO, inner sep=0pt] {};
       \draw[dd,#3] ($(outgr-\row.north east)+(0.1cm,0.1cm)$) to node[midway,align=center,anchor=west,xshift=0.1cm,#2] {#4} ($(outgr-\row.south east)+(0.1cm,-0.1cm)$);
       }
} %
%deferred labelling in the middle of circuits
\newcommand{\groupoutput@mid}[4]{%basic data as keys, label options, brace options, text
       \pgfkeys{/quantikz,wires=1}
       \def\leftbrace{1}\def\rightbrace{1}
       \pgfkeys{/quantikz,#1}%
       \pgfkeysgetvalue{/quantikz/wires}{\quantwires}
       \pgfkeysgetvalue{/quantikz/row}{\row}
       \pgfkeysgetvalue{/quantikz/col}{\col}
       \xdef\LoopGO{}
       \foreach \n in  {\row,...,\the\numexpr\row+\quantwires-1\relax} {
               \ifnodedefined{\tikzcdmatrixname-\n-\col}{
                       \xdef\LoopGO{\LoopGO(\tikzcdmatrixname-\n-\col)}
               }}
               \ifthenelse{\quantwires=1} {
               %\node (midgr-\row-\col) [fit=\LoopGO, inner sep=0pt,label={[align=center,#2]#4}] {};
               \node (midgr-\row-\col) [fit=\LoopGO, inner sep=0pt,label={[anchor=mid,#2]center:#4}] {};
       }{
       \node (midgr-\row-\col) [fit=\LoopGO, inner sep=0pt,label={[anchor=mid,#2]center:#4}] {};
       \ifthenelse{\rightbrace=1}{
       \draw[dm,#3] ($(midgr-\row-\col.north east)+(-0.1cm,0.05cm)$) to ($(midgr-\row-\col.south east)+(-0.1cm,-0.05cm)$);
       }{}
       \ifthenelse{\leftbrace=1}{
       \draw[dd,#3] ($(midgr-\row-\col.north west)+(0.1cm,0.05cm)$) to ($(midgr-\row-\col.south west)+(0.1cm,-0.05cm)$);
       }{}
       }
} %
%inputs and outputs within a multi-wire gate
\newcommand\gateinput[2][]{%
       \pgfkeys{/quantikz,wires=1,style=,label style=,braces=}%
       \pgfkeys{/quantikz,#1}%
       \edef\newoptions{row=\the\pgfmatrixcurrentrow,col=\the\pgfmatrixcurrentcolumn,#1}
       \pgfkeysgetvalue{/quantikz/label style}{\options}
       \pgfkeysgetvalue{/quantikz/braces}{\opts}%
       \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfutil@g@addto@macro\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\tikzcd@atendlabels\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{%
               \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\mginput@end\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\newoptions\expandafter\expandafter\expandafter}\expandafter\expandafter\expandafter{\expandafter\options\expandafter}\expandafter{\opts}{#2}%
       }
}
\newcommand\gateoutput[2][]{%
       \pgfkeys{/quantikz,wires=1,style=,label style=,braces=}
       \pgfkeys{/quantikz,#1}%
       \edef\newoptions{row=\the\pgfmatrixcurrentrow,col=\the\pgfmatrixcurrentcolumn,#1}
       \pgfkeysgetvalue{/quantikz/label style}{\options}
       \pgfkeysgetvalue{/quantikz/braces}{\opts}
       \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfutil@g@addto@macro\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\tikzcd@atendlabels\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{%
               \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\mgoutput@end\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\newoptions\expandafter\expandafter\expandafter}\expandafter\expandafter\expandafter{\expandafter\options\expandafter}\expandafter{\opts}{#2}%
       }
}
%deferred functions for the above
\newcommand{\mginput@end}[4]{%collected options,label style, brace style,text
       \pgfkeys{/quantikz,wires=1}
       \pgfkeys{/quantikz,#1}%
       \edef\quantwires{\pgfkeysvalueof{/quantikz/wires}}
       %\pgfkeysgetvalue{/quantikz/wires}{\quantwires}
       \pgfkeysgetvalue{/quantikz/row}{\row}
       \pgfkeysgetvalue{/quantikz/col}{\col}
%can we find the gategroup node?
\xdef\cell{group\tikzcdmatrixname-1-\col}
\foreach \n in {\row,...,1} {%
       %test if node group-\n-#2 exists
       \ifnodedefined{group\tikzcdmatrixname-\n-\col}{%
       \xdef\cell{group\tikzcdmatrixname-\n-\col}
       \breakforeach
       }{}
}
\ifthenelse{\quantwires=1}{%
       \node at ($(\cell.west |- \tikzcdmatrixname-\row-\col.west)+(0,0cm)$)[leftinternal,#2]{#4};
}{%
%\show\quantwires
\draw[dd,#3] ($(\cell.west |- \tikzcdmatrixname-\row-\col.west)+(0.1cm,0.1cm)$) to node[leftinternal,midway,#2] {#4} ($(\cell.west |- \tikzcdmatrixname-\the\numexpr\row+\quantwires-1\relax-\col.west)+(0.1cm,-0.1cm)$);
}
} %
\newcommand{\mgoutput@end}[4]{%
       \pgfkeys{/quantikz,wires=1}
       \pgfkeys{/quantikz,#1}%
       \edef\quantwires{\pgfkeysvalueof{/quantikz/wires}}
       %\pgfkeysgetvalue{/quantikz/wires}{\quantwires}
       \pgfkeysgetvalue{/quantikz/row}{\row}
       \pgfkeysgetvalue{/quantikz/col}{\col}
%can we find the gategroup node?
\xdef\cell{group\tikzcdmatrixname-1-\col}
\foreach \n in {\row,...,1} {%
       %test if node group-\n-#2 exists
       \ifnodedefined{group\tikzcdmatrixname-\n-\col}{%
       \xdef\cell{group\tikzcdmatrixname-\n-\col}
       \breakforeach
       }{}
}
\ifthenelse{\quantwires=1}{%
       \node at ($(\cell.east |- \tikzcdmatrixname-\row-\col.east)+(0,0cm)$)[rightinternal,#2]{#4};
}{%
\draw[dm,#3] ($(\cell.east |- \tikzcdmatrixname-\row-\col.east)+(-0.1cm,0.1cm)$) to node[rightinternal,midway,#2] {#4} ($(\cell.east |- \tikzcdmatrixname-\the\numexpr\row+\quantwires-1\relax-\col.east)+(-0.1cm,-0.1cm)$);
}
} %

%wave command
\newcommand\wave[1][]{%
       \edef\n{\the\pgfmatrixcurrentrow}
       \expandafter\pgfutil@g@addto@macro\expandafter\tikzcd@atendslices\expandafter{%
               \expandafter\wave@end\expandafter{\n}{#1}%
       }
}
%deferred wave
\newcommand{\wave@end}[2]{
       \node (wave-#1) [fit=(\tikzcdmatrixname-row#1),wave,#2] {};
}

\DeclareDocumentCommand{\makeebit}{O{-45}O{}m}{
       \arrow[arrows,line cap=round,to path={(\tikztostart) -- ($(\tikztostart)!{0.5/cos(#1)}!#1:(\tikztotarget)$) node [anchor=east,style={#2}]{#3} -- (\tikztotarget) }]{d}
}

% \newcommand{\makeebit}[2][-45]{
%       \arrow[arrows,line cap=round,to path={(\tikztostart) -- ($(\tikztostart)!0.707!#1:(\tikztotarget)$) node [anchor=east]{#2} -- (\tikztotarget) }]{d}
% }

%put a border around a group of gates
\newcommand\gategroup[2][]{%
       \pgfkeys{/quantikz,wires=1,style=,label style=,braces=}
       \pgfkeys{/quantikz,#1}%
       \edef\newoptions{row=\the\pgfmatrixcurrentrow,col=\the\pgfmatrixcurrentcolumn,#1}
       \pgfkeysgetvalue{/quantikz/style}{\options}
       \pgfkeysgetvalue{/quantikz/label style}{\opts}
       \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfutil@g@addto@macro\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\tikzcd@atendlabels\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{%
               \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\gategroup@end\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\newoptions\expandafter\expandafter\expandafter}\expandafter\expandafter\expandafter{\expandafter\options\expandafter}\expandafter{\opts}{#2}%
       }
}
%deferred gate group command
\newcommand{\gategroup@end}[4]{%options, gate style, text style, text
       \pgfkeys{/quantikz,wires=1,style=,label style=,braces=,steps=1}%
       \edef\background{0}%
       \pgfkeys{/quantikz,#1}%
       \pgfkeysgetvalue{/quantikz/wires}{\quantwires}%
       \pgfkeysgetvalue{/quantikz/row}{\row}%
       \pgfkeysgetvalue{/quantikz/col}{\col}%
       \pgfkeysgetvalue{/quantikz/steps}{\steps}%
       \edef\fit{(\tikzcdmatrixname-col\col.west |- \tikzcdmatrixname-row\row.north)(\tikzcdmatrixname-col\the\numexpr\col+\steps-1\relax.east |- \tikzcdmatrixname-row\the\numexpr\row+\quantwires-1\relax.south)}%
       \ifthenelse{\background=1}{%
               \begin{scope}[on background layer]\node (ggroup-\row-\col) [fit=\fit,ggroup,label={[group label,#3]:#4},#2] {};\end{scope}
       }{%
               \node (ggroup-\row-\col) [fit=\fit,ggroup,label={[group label,#3]:#4},#2] {};
       }
}

%use for fudging classical wires that have horizontal and vertical sections
\newcommand{\cwbend}[1]{
       \vcw{#1}\cw
       \edef\cell{\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn}
       \expandafter\pgfutil@g@addto@macro\expandafter\tikzcd@atendlabels\expandafter{%
               \expandafter\latephase@end\expandafter{\cell}
       }
}

\newcommand{\latephase@end}[1]{
       \node [phase,inner sep=2pt] at (\tikzcdmatrixname-#1) {};
}

%patch tikzcd to allow for multiple layers of commands
\patchcmd\tikzcd@{\tikzpicture}{\def\toslice{0}\def\vert{0}%
\begin{tikzpicture}}{}{}
\patchcmd\tikzcd@
   {\global\let\tikzcd@savedpaths\pgfutil@empty}
   {\global\let\tikzcd@savedpaths\pgfutil@empty
   \global\let\tikzcd@atendsavedpaths\pgfutil@empty
   \global\let\tikzcd@atendlabels\pgfutil@empty
   \global\let\tikzcd@atendslices\pgfutil@empty
   \global\let\tikzcd@atendglobals\pgfutil@empty
   \pgfutil@g@addto@macro\tikzcd@savedpaths\DivideRowsCols
   %\pgfmathsetmacro{\mname}{random(100000)}
   \ifthenelse{\toslice=1}{\ifthenelse{\vert=0}{\pgfutil@g@addto@macro\tikzcd@atendslices\sliceallr}{\pgfutil@g@addto@macro\tikzcd@atendslices\sliceallvr}}{}
   }{}{}

%this patching works on modern systems, but I believe is incompatible with the old version that arXiv is running
%\patchcmd\endtikzcd{\tikzcd@savedpaths}{\tikzcd@savedpaths\tikzcd@atendsavedpaths\tikzcd@atendlabels\tikzcd@atendslices{\globaldefs=1\tikzcd@atendglobals}}{}{}

%instead, completely redefine the function
\def\endtikzcd{%
 \pgfmatrixendrow\egroup%
 \pgfextra{\global\let\tikzcdmatrixname\tikzlastnode};%
 \tikzcdset{\the\pgfmatrixcurrentrow-row diagram/.try}%
 \begingroup%
   \pgfkeys{% `quotes' library support
     /handlers/first char syntax/the character "/.initial=\tikzcd@forward@quotes,%
     /tikz/edge quotes mean={%
       edge node={node [execute at begin node=\iftikzcd@mathmode$\fi,%$
                        execute at end node=\iftikzcd@mathmode$\fi,%$
                        /tikz/commutative diagrams/.cd,every label,##2]{##1}}}}%
   \let\tikzcd@errmessage\errmessage% improve error messages
   \def\errmessage##1{\tikzcd@errmessage{##1^^J...^^Jl.\tikzcd@lineno\space%
       I think the culprit is a tikzcd arrow in cell \tikzcd@currentrow-\tikzcd@currentcolumn}}%
   \tikzcd@before@paths@hook%
   \tikzcd@savedpaths\tikzcd@atendsavedpaths\tikzcd@atendlabels\tikzcd@atendslices{\globaldefs=1\tikzcd@atendglobals\globaldefs=0}%I just added stuff here instead
 \endgroup%
 \end{tikzpicture}%
 \ifnum0=`{}\fi}


%end patching
%\makeatother

%this command runs after we've finished the matrix, and makes unified cells for each row and each column. This allows much nicer alignment of large boxes.
\newcommand{\DivideRowsCols}{
       \foreach \n in {1,...,\the\pgfmatrixcurrentrow} {%for each row, construct a master cell that contains all entries
       \xdef\LoopRow{}
               \foreach \m in {1,...,\the\pgfmatrixcurrentcolumn}{
                       \ifnodedefined{\tikzcdmatrixname-\n-\m}{
                               \xdef\LoopRow{\LoopRow(\tikzcdmatrixname-\n-\m)}
                       }{}
                       \ifnodedefined{group\tikzcdmatrixname-\n-\m}{
                               \xdef\LoopRow{\LoopRow(group\tikzcdmatrixname-\n-\m)}
                       }{}
       }
       \node (\tikzcdmatrixname-row\n) [fit=\LoopRow] {};
       }
       \foreach \n in {1,...,\the\pgfmatrixcurrentcolumn} {%for each column, construct a master cell that contains all entries
       \xdef\LoopCol{}
               \foreach \m in {1,...,\the\pgfmatrixcurrentrow}{
                       \ifnodedefined{\tikzcdmatrixname-\m-\n}{
                               \xdef\LoopCol{\LoopCol(\tikzcdmatrixname-\m-\n)}
                       }{}
                       \ifnodedefined{group\tikzcdmatrixname-\m-\n}{
                               \xdef\LoopCol{\LoopCol(group\tikzcdmatrixname-\m-\n)}
                       }{}
       }
       \node (\tikzcdmatrixname-col\n) [fit=\LoopCol] {};
       }
}

%take a parameter, row number, where we want to set the baseline. if not integer, use the two rows spanned
\providecommand{\setmiddle}[1]{%
\IfInteger{#1}{
\pgfmathtruncatemacro\wholepart{floor(#1)}
\edef\temp{\noexpand\tikzset{%
/tikz/baseline={([yshift=-\MathAxis]\noexpand\tikzcdmatrixname-\wholepart-1.base)}
}}
%\show\temp
\temp
}{%
\pgfmathtruncatemacro\wholepart{floor(#1)}
\pgfmathtruncatemacro\neighbour{floor(#1)+1}
\pgfmathsetmacro\fractionalpart{#1-floor(#1)}
\edef\temp{
%\noexpand\tikzset{every matrix/.append style={baseline=([yshift=-\MathAxis]$(\noexpand\tikzcdmatrixname-\wholepart-1.base)!\fractionalpart!(\noexpand\tikzcdmatrixname-\neighbour-1.base)$)}%
\noexpand\tikzset{%
/tikz/baseline={([yshift=-\MathAxis]$(\noexpand\tikzcdmatrixname-\wholepart-1.base)!\fractionalpart!(\noexpand\tikzcdmatrixname-\neighbour-1.base)$)}
}}
%\show\temp
\temp
}
}

%initialise all the pgfkeys for key=value parameter passing in macro options
\pgfkeys{/tikz/slice all/.code={\def\toslice{1}},/tikz/remove end slices/.initial=0,/tikz/slice titles/.initial={\col},/tikz/slice style/.initial={},/tikz/slice label style/.initial={},/tikz/thin lines/.code={\resetstyles},/tikz/transparent/.code={\maketransparent},/tikz/vertical slice labels/.code={\def\vert{1}},/tikz/align equals at/.code={\setmiddle{#1}}}
%\tikzcdset{slice all/.code={\def\toslice{1}},remove end slices/.initial=0,slice titles/.initial={\col},slice style/.initial={},slice label style/.initial={},thin lines/.code={\resetstyles},transparent/.code={\maketransparent},vertical slice labels/.code={\def\vert{1}},align equals at/.code={\setmiddle{#1}}
%}
\pgfkeys{/quantikz/.is family,/quantikz,%
unknown/.style={%
       /quantikz/wires=\pgfkeyscurrentname
},%
%wires/.store in=\quantwires,%
wires/.initial=1,%
style/.initial={},label style/.initial={},braces/.initial={},background/.code={\def\background{1}},alternate/.default=1,alternate/.code={\def\helper{#1}},row/.initial=1,col/.initial=1,steps/.initial=1,Strike Width/.initial=0.08cm,Strike Height/.initial=0.12cm,swap/.code={\def\toswap{1}},disable auto height/.code={\def\DisableMinSize{1}},cwires/.initial={-1},nwires/.initial={-1},bundle/.initial={-1},brackets/.is choice,brackets/.initial=both}
\pgfkeys{/quantikz,brackets/.cd,none/.code={\def\leftbrace{0}\def\rightbrace{0}},left/.code={\def\leftbrace{1}\def\rightbrace{0}},right/.code={\def\leftbrace{0}\def\rightbrace{1}},both/.code={\def\leftbrace{1}\def\rightbrace{1}}}

%my standard Dirac notation commands. can be overridden by user.
\providecommand{\ket}[1]{\ensuremath{\left|#1\right\rangle}}
\providecommand{\bra}[1]{\ensuremath{\left\langle#1\right |}}
\providecommand{\proj}[1]{\ensuremath{\ket{#1}\!\bra{#1}}}
\providecommand{\braket}[2]{\ensuremath{\left\langle#1\middle|#2\right\rangle}}
\newcommand{\forceredefine}{%
\renewcommand{\ket}[1]{\ensuremath{\left|##1\right\rangle}}
\renewcommand{\bra}[1]{\ensuremath{\left\langle##1\right |}}
\renewcommand{\proj}[1]{\ensuremath{\ket{##1}\!\bra{##1}}}
\renewcommand{\braket}[2]{\ensuremath{\left\langle##1\middle|##2\right\rangle}}
}


%single qubit operations
\newcommand{\phantomgate}[1]{|[linecont,thickness, inner ysep=3pt]| \phantom{#1} \qw}
\newcommand{\hphantomgate}[1]{|[linecont,minimum size=1.5em,thickness]| \hphantom{#1} \qw}
\newcommand{\push}[1]{#1 \qw}
\newcommand{\alias}[1]{|[alias=#1]|}
\DeclareExpandableDocumentCommand{\phase}{O{}m}{|[phase,#1,label={[phase label,#1]#2}]| {} \qw}
\DeclareExpandableDocumentCommand{\control}{O{}m}{|[phase,#1]| {} \qw}
\DeclareExpandableDocumentCommand{\ocontrol}{O{}m}{|[ophase,#1]| {} \qw}
\DeclareExpandableDocumentCommand{\targ}{O{}m}{|[circlewc,#1]| {} \qw}
\DeclareExpandableDocumentCommand{\targX}{O{}m}{|[crossx2,#1]| {} \qw}
\newcommand{\linethrough}{|[linecont, inner ysep=3pt]| }

%measuring
\DeclareExpandableDocumentCommand{\meter}{O{}{m}}{|[meter,label={[my label]#2},#1]| {} \qw}
\DeclareExpandableDocumentCommand{\measuretab}{O{}{m}}{|[measuretab,#1]| {#2} \qw}
\DeclareExpandableDocumentCommand{\meterD}{O{}{m}}{|[meterD,#1]| {#2} \qw}
\DeclareExpandableDocumentCommand{\measure}{O{}{m}}{|[measure,#1]| {#2} \qw}
\DeclareExpandableDocumentCommand{\trash}{O{}{m}}{|[trash,label={below:#2},#1]| {} \qw}


%controlled gates
\def\ctrl#1{\control{}  \vqw{#1}}
\DeclareExpandableDocumentCommand{\ctrlbundle}{O{1}O{}m}{|[phase bundle,#2]| {} \vqw{#3}\qwbundle[alternate=#1]{}}
\def\octrl#1{\ocontrol{}\vqw{#1}}
\def\swap#1{%
       \targX{}
       \edef\start{\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn}
       \edef\end{\the\numexpr#1+\pgfmatrixcurrentrow\relax-\the\pgfmatrixcurrentcolumn}
       \expandafter\expandafter\expandafter\vqwexplicitcenter\expandafter\expandafter\expandafter{\expandafter\start\expandafter}\expandafter{\end}
}
\DeclareExpandableDocumentCommand{\pswap}{O{0.5}mm}{%
       \targX{}
       \edef\start{\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn}
       \edef\end{\the\numexpr#2+\pgfmatrixcurrentrow\relax-\the\pgfmatrixcurrentcolumn}
       \expandafter\expandafter\expandafter\vqwexplicitc\expandafter\expandafter\expandafter{\expandafter\start\expandafter}\expandafter{\end}{#3}{#1}
}

%vertical wires
%classical vertical wire, relative positioning
\newcommand{\vcw}[1]{
       \edef\start{\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn}
       \edef\end{\the\numexpr#1+\pgfmatrixcurrentrow\relax-\the\pgfmatrixcurrentcolumn}
       \expandafter\expandafter\expandafter\vcwexplicit\expandafter\expandafter\expandafter{\expandafter\start\expandafter}\expandafter{\end}
}
%vertical quantum wire, relative positioning
\newcommand{\vqw}[1]{
       \edef\start{\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn}
       \edef\end{\the\numexpr#1+\pgfmatrixcurrentrow\relax-\the\pgfmatrixcurrentcolumn}
       \expandafter\expandafter\expandafter\vqwexplicit\expandafter\expandafter\expandafter{\expandafter\start\expandafter}\expandafter{\end}
}
%quantum wire, absolute positioning
\newcommand{\vqwexplicit}[2]{
       \arrow[from=#1,to=#2,arrows] {}
}
\newcommand{\vqbundleexplicit}[2]{
       \arrow[from=#1,to=#2,arrows] {} \arrow[from=#1,to=#2,arrows,yshift=0.1cm] {}\arrow[from=#1,to=#2,arrows,yshift=-0.1cm] {}
}
%classical vertical wire, absolute positioning
\newcommand{\vcwexplicit}[2]{
       \arrow[from=#1,to=#2,arrows,xshift=0.05cm] {}\arrow[from=#1,to=#2,arrows,xshift=-0.05cm] {}
}
%classical horizontal wire, absolute positioning
\newcommand{\vcwhexplicit}[2]{
       \arrow[from=#1,to=#2,arrows,yshift=0.05cm] {}\arrow[from=#1,to=#2,arrows,yshift=-0.05cm] {}
}
%quantum wire, absolute positioning, going to centres of cell, not edge.
\newcommand{\vqwexplicitcenter}[2]{
       \arrow[from=#1,to=#2,arrows,start anchor=center,end anchor=center] {}
}
%quantum wire, absolute positioning, going to centres of cell, not edge. Add a label contianing circle
\newcommand{\vqwexplicitc}[4]{
       \arrow[from=#1,to=#2,arrows,start anchor=center,end anchor=center,"{#3}"{grade,pos=#4}]{}
}

%horizontal wires
\newcommand{\qw}{\ifthenelse{\the\pgfmatrixcurrentcolumn>1}{\arrow[arrows]{l}}{}}
\newcommand{\cw}{\ifthenelse{\the\pgfmatrixcurrentcolumn>1}{\arrow[arrows,yshift=0.05cm]{l}\arrow[arrows,yshift=-0.05cm]{l}}{}}
%define the strike distance for strike-through on qwbundle.
%\newcommand*{\StrikeDistance}{0.1cm}%
%a bundle of horizontal quantum wires
\newcommand{\qwbundle}[2][]{\ifthenelse{\the\pgfmatrixcurrentcolumn>1}{
       \def\helper{0}
       \pgfset{/quantikz,#1}
       \ifthenelse{\helper=3}{
\arrow[arrows,yshift=0.05cm]{l}
\arrow[arrows,yshift=-0.05cm]{l}
       }{
       \ifthenelse{\helper>0}{
               \arrow[arrows,yshift=0.1cm]{l}
               \ifthenelse{\helper=1}{\arrow[arrows]{l}}{}
               \arrow[arrows,yshift=-0.1cm]{l}
       }{
       \arrow[phantom,strike arrow]{l}[xshift=\pgfkeysvalueof{/quantikz/Strike Width}, yshift=\pgfkeysvalueof{/quantikz/Strike Height},anchor=south west,inner sep=0pt]{\scriptstyle #2}\qw
       }}}{}}


\pgfdeclareshape{rectangle with rounded corners}{
 \inheritsavedanchors[from=rectangle] % this is nearly a rectangle
 \inheritanchorborder[from=rectangle]
 \inheritanchor[from=rectangle]{center}
 \inheritanchor[from=rectangle]{north}
 \inheritanchor[from=rectangle]{south}
 \inheritanchor[from=rectangle]{west}
 \inheritanchor[from=rectangle]{east}
 \inheritanchor[from=rectangle]{north east}
 \inheritanchor[from=rectangle]{south east}
 \inheritanchor[from=rectangle]{north west}
 \inheritanchor[from=rectangle]{south west}
 \backgroundpath{% this is new
   % store lower right in xa/ya and upper right in xb/yb
   \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
   \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
   % construct main path
   \pgfkeysgetvalue{/tikz/rectangle with rounded corners north west}{\pgf@rectc}
   \pgfsetcornersarced{\pgfpoint{\pgf@rectc}{\pgf@rectc}}
   \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
   \pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
   \pgfkeysgetvalue{/tikz/rectangle with rounded corners north east}{\pgf@rectc}
   \pgfsetcornersarced{\pgfpoint{\pgf@rectc}{\pgf@rectc}}
   \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
   \pgfkeysgetvalue{/tikz/rectangle with rounded corners south east}{\pgf@rectc}
   \pgfsetcornersarced{\pgfpoint{\pgf@rectc}{\pgf@rectc}}
   \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
   \pgfkeysgetvalue{/tikz/rectangle with rounded corners south west}{\pgf@rectc}
   \pgfsetcornersarced{\pgfpoint{\pgf@rectc}{\pgf@rectc}}
   \pgfpathclose
}
}

%configure some of the style properties.
%annoyingly, this first one will affect all tikzcd instances, not just quantum circuits. I should have only provided the quantikz environment as a modified version of tikzcd, and not allowed direct use of tikzcd. Probably too late now.
\tikzcdset{row sep/normal=0.5cm,column sep/normal=0.5cm,thick,nodes in empty cells,
       every cell/.style={
       anchor=center,minimum size=0pt,inner sep=0pt,outer sep=0pt,thick
   },
   arrows/.style={dash,thick},
   1-row diagram/.style={},
   grade/.style={description,circle,draw=black,fill=white,inner sep=0pt, outer sep=0pt,font=\tiny}
   }
\tikzset{
       thickness/.style={thick},
   operator/.style={draw,fill=\pgfkeysvalueof{/tikz/commutative diagrams/background color}, inner sep=2pt,thickness,align=center},
   ggroup/.style={draw,minimum size=1.5em,thickness,align=center,inner sep=4pt},
   leftinternal/.style={anchor=mid west,font=\scriptsize,inner sep=4pt,align=center},
   rightinternal/.style={anchor=mid east,font=\scriptsize,inner sep=4pt,align=center},
   wave/.style={inner sep=-3pt,tape,fill=\pgfkeysvalueof{/tikz/commutative diagrams/background color},apply={draw=black} except on segments {5,6,1,2,9}},
   phase/.style={fill,shape=circle,minimum size=4pt},
   phase bundle/.style={fill,shape=rectangle,rounded corners=1.5pt,minimum width=4pt,minimum height=10pt},
   phase label/.style={label distance=2mm,anchor=mid,label position=45},
   ophase/.style={fill=\pgfkeysvalueof{/tikz/commutative diagrams/background color},draw,shape=circle,minimum size=4pt},
   internal/.style={thickness},
   rectangle with rounded corners north west/.initial=0pt,
         rectangle with rounded corners south west/.initial=0pt,
         rectangle with rounded corners north east/.initial=8pt,
         rectangle with rounded corners south east/.initial=8pt,
   line/.style={path picture={
\draw[internal](path picture bounding box.west) -- (path picture bounding box.east);
}},
       linecont/.style={circle,line},
   cross/.style={path picture={
\draw[internal](path picture bounding box.north) -- (path picture bounding box.south) (path picture bounding box.west) -- (path picture bounding box.east);
}},
   circlewc/.style={draw,circle,cross,minimum width=4pt,inner sep=3pt},
   crossx/.style={path picture={
\draw[internal,inner sep=0pt]
(path picture bounding box.south east) -- (path picture bounding box.north west) (path picture bounding box.south west) -- (path picture bounding box.north east) (path picture bounding box.west) -- (path picture bounding box.east);
}},
       crossx2/.style={circle,crossx,minimum size=1em},
       trash/.style={path picture={\draw[internal,inner sep=0pt,-stealth] (path picture bounding box.west) -- (path picture bounding box.center) -- (path picture bounding box.south);},minimum height=2.5em,minimum width=2em},
       hidden bend/.style={path picture={\draw[internal,inner sep=0pt] (path picture bounding box.west) -- (path picture bounding box.center) -- (path picture bounding box.south);},minimum height=1.5em,minimum width=1em},
   dd/.style={decoration={brace},decorate,thickness},
   dm/.style={decoration={brace,mirror},decorate,thickness},
   slice/.style={thickness,red,dash pattern=on 5pt off 3pt,align=center},
   meter/.style={draw,
       fill=\pgfkeysvalueof{/tikz/commutative diagrams/background color},
       minimum width=2em,
       minimum height=1.5em,
       rectangle,
       font=\vphantom{A},
       thickness,
       path picture={
           \draw ([shift={(.1,-.06)}]path picture bounding box.west) to[bend left=50] ([shift={(-.1,-.06)}]path picture bounding box.east);
           \draw[-{Latex[scale=0.6]}] ([shift={(0,-.1)}]path picture bounding box.center) -- ([shift={(-.1,.2)}]path picture bounding box.east);
       }
   },
       measuretab/.style={draw,signal,signal to=west,inner sep=4pt,fill=\pgfkeysvalueof{/tikz/commutative diagrams/background color}},
   meterD/.style={
       draw,
       shape=rectangle with rounded corners,
       inner sep=4pt,
       fill=\pgfkeysvalueof{/tikz/commutative diagrams/background color}
   },
       measure/.style={draw,rounded rectangle,inner sep=4pt,fill=\pgfkeysvalueof{/tikz/commutative diagrams/background color}},
       my label/.style={yshift=0.1cm,above,align=center},
       gg label/.style={label position=center,align=center},
       group label/.style={label position=above,yshift=0.2cm,anchor=mid},
       strike arrow/.style={
   decoration={markings, mark=at position 0.5 with {
       \draw [internal,-]
           ++ (-\pgfkeysvalueof{/quantikz/Strike Width},-\pgfkeysvalueof{/quantikz/Strike Height} )
           -- ( \pgfkeysvalueof{/quantikz/Strike Width}, \pgfkeysvalueof{/quantikz/Strike Height});}   %can I use pgfkeys and do some maths here?
   },
   postaction={decorate},
}
}

\def\resetstyles{
\tikzcdset{thin,every cell/.append style={thin},arrows/.append style={thin}
   }
\tikzset{
       thickness/.style={thin},
       %operator/.append style={thin},
       %internal/.append style={thin},
       %dd/.append style={thin},
       %dm/.append style={thin},
       %slice/.append style={thin},
       meter/.append style={thin},
       phase/.append style={minimum size=3pt},
       ophase/.append style={minimum size=3pt},
       %circlewc/.append style={minimum size=3pt,inner sep=2pt}
}
}

\def\maketransparent{
\tikzset{
       operator/.append style={fill opacity=0},
       meter/.append style={fill opacity=0},
       measuretab/.append style={fill opacity=0},
       meterD/.append style={fill opacity=0},
       measure/.append style={fill opacity=0},
       wave/.append style={fill opacity=0},
       ophase/.append style={fill opacity=0}
}
}
\def\bin{\begin{tikzpicture}[thick,scale=0.2]
\draw (0,0) -- (1,0) -- (1,-0.2) -- (2,-0.8) -- (1.4,-3) -- (-0.4,-3) -- (-1,-0.8) -- (0,-0.2) -- cycle;
\draw (2,-0.8) arc (360:180:1.5 and 0.2);
\draw (-0.2,-1.1) -- (0.3,-2.8);
\draw (1.2,-1.1) -- (0.7,-2.8);
\end{tikzpicture}}