% Figure 1: A+C combo pipeline (full).
% Compile:  pdflatex figure1_pipeline.tex
\documentclass[border=8pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, positioning, calc, decorations.pathreplacing}
\usepackage{amsmath, amssymb}

\definecolor{myorange}{RGB}{230, 126, 34}
\definecolor{myblue}{RGB}{52, 110, 180}
\definecolor{mygreen}{RGB}{46, 139, 87}
\definecolor{mypurple}{RGB}{142, 68, 173}
\definecolor{mygray}{RGB}{170, 170, 170}
\definecolor{mybg}{RGB}{248, 248, 248}

\newcommand{\contrib}{\textcolor{myorange}{\ensuremath{\bigstar}}}

\begin{document}
\begin{tikzpicture}[
  font=\small,
  >={Stealth[length=2.5mm]},
  databox/.style={rectangle, draw=mygray, rounded corners=2pt,
                  minimum height=12mm, minimum width=14mm, align=center, fill=mygray!20},
  box/.style={rectangle, draw=black!70, thick, rounded corners=2pt,
              minimum height=12mm, minimum width=22mm, align=center, fill=white},
  novelbox/.style={rectangle, draw=myorange, line width=1.4pt, rounded corners=2pt,
                   minimum height=12mm, minimum width=22mm, align=center, fill=myorange!10},
  arrow/.style={->, thick},
  losseq/.style={fill=mybg, draw=black!30, rounded corners=2pt, inner sep=5pt}
]

% =========================================================================
%  TRAINING ROW (no row title)
% =========================================================================

% ----- (1) PCAP file icon -----
\begin{scope}[shift={(0.0, -1.2)}]
  \fill[myblue!12] (0,0) -- (0,2.4) -- (1.05,2.4) -- (1.45,2.0) -- (1.45,0) -- cycle;
  \draw[myblue!80, line width=0.6pt]
        (0,0) -- (0,2.4) -- (1.05,2.4) -- (1.45,2.0) -- (1.45,0) -- cycle;
  \fill[myblue!30] (1.05,2.4) -- (1.05,2.0) -- (1.45,2.0) -- cycle;
  \draw[myblue!80, line width=0.4pt] (1.05,2.4) -- (1.05,2.0) -- (1.45,2.0);
  \node[font=\bfseries\scriptsize, text=myblue!90!black] at (0.7, 1.65) {flow.pcap};
  \foreach \y/\rl in {1.30/0.95, 1.10/0.78, 0.90/1.05, 0.70/0.65, 0.50/0.90, 0.30/0.55} {
    \draw[myblue!45, line width=0.3pt] (0.15, \y) -- (0.15+\rl, \y);
  }
\end{scope}

% Arrow: parse  (length = 1.4cm so label fits comfortably)
\draw[arrow, black!60] (1.6, 0) -- (3.0, 0)
  node[midway, above=0.5mm, font=\scriptsize\itshape, text=black!70] {parse};

% ----- (2) Packet stream: pkt0, pkt1, pkt2, ..., pkt_T -----
\begin{scope}[shift={(3.1, -1.1)}]
  % 4 packets at explicit x-offsets; first three are 0,1,2 then a gap with
  % ellipsis and the final one labeled pkt_T.
  \foreach \j/\xoff/\lbl in {0/0.00/0, 1/1.18/1, 2/2.36/2, 3/4.04/T} {
    \pgfmathsetmacro{\xx}{\xoff}
    \draw[fill=white, draw=black!55, line width=0.45pt, rounded corners=1pt]
          (\xx, 0.05) rectangle (\xx+1.05, 2.25);
    \draw[fill=myblue!35, draw=myblue, line width=0.3pt]
          (\xx+0.07, 2.00) rectangle (\xx+0.32, 2.15);
    \node[font=\tiny, anchor=west] at (\xx+0.34, 2.075) {size};
    \draw[fill=mygreen!35, draw=mygreen, line width=0.3pt]
          (\xx+0.07, 1.78) rectangle (\xx+0.32, 1.93);
    \node[font=\tiny, anchor=west] at (\xx+0.34, 1.855) {IAT};
    \draw[fill=mypurple!35, draw=mypurple, line width=0.3pt]
          (\xx+0.07, 1.56) rectangle (\xx+0.20, 1.71);
    \node[font=\tiny, anchor=west] at (\xx+0.22, 1.635) {dir};
    \ifcase\j
      \def\flagS{1}\def\flagF{0}\def\flagR{0}\def\flagP{0}\def\flagA{0}\or
      \def\flagS{1}\def\flagF{0}\def\flagR{0}\def\flagP{0}\def\flagA{1}\or
      \def\flagS{0}\def\flagF{0}\def\flagR{0}\def\flagP{0}\def\flagA{1}\or
      \def\flagS{0}\def\flagF{0}\def\flagR{0}\def\flagP{1}\def\flagA{1}\fi
    \foreach \fname/\fval/\k in {S/\flagS/0, F/\flagF/1, R/\flagR/2, P/\flagP/3, A/\flagA/4} {
      \pgfmathsetmacro{\fx}{\xx + 0.07 + \k*0.18}
      \ifnum\fval=1
        \draw[fill=myorange!70, draw=myorange, line width=0.3pt]
              (\fx, 1.30) rectangle (\fx+0.15, 1.46);
        \node[font=\tiny, white] at (\fx+0.075, 1.38) {\fname};
      \else
        \draw[fill=white, draw=myorange!60, line width=0.3pt]
              (\fx, 1.30) rectangle (\fx+0.15, 1.46);
        \node[font=\tiny, text=myorange!80!black] at (\fx+0.075, 1.38) {\fname};
      \fi
    }
    \draw[fill=myblue!20, draw=myblue!60, line width=0.3pt]
          (\xx+0.07, 1.05) rectangle (\xx+0.32, 1.20);
    \node[font=\tiny, anchor=west] at (\xx+0.34, 1.125) {win};
    \draw[black!30, line width=0.3pt] (\xx+0.07, 0.80) -- (\xx+0.97, 0.80);
    \draw[black!30, line width=0.3pt] (\xx+0.07, 0.65) -- (\xx+0.85, 0.65);
    \draw[black!30, line width=0.3pt] (\xx+0.07, 0.50) -- (\xx+0.95, 0.50);
    \draw[black!30, line width=0.3pt] (\xx+0.07, 0.35) -- (\xx+0.70, 0.35);
    \node[font=\scriptsize, text=black!70] at (\xx+0.525, -0.13) {pkt$_{\lbl}$};
  }
  % Ellipsis between pkt_2 (ends at x=3.41) and pkt_T (starts at x=4.04)
  \node[font=\Large, text=black!55] at (3.72, 1.15) {$\cdots$};
  % Time axis spans full row
  \draw[->, line width=0.35pt, black!55] (-0.05, -0.4) -- (5.20, -0.4);
  \node[font=\tiny, anchor=west, text=black!55] at (5.20, -0.4) {time};
\end{scope}

% Arrow: tokenize  (length = 1.4cm). Packet stream ends at x=3.1+5.09=8.19,
% so arrow must start after that.
\draw[arrow, black!60] (8.3, 0) -- (9.7, 0)
  node[midway, above=0.5mm, font=\scriptsize\itshape, text=black!70] {tokenize};

% ----- (3) Token sequence: [FLOW | P_1 | P_2 | ... | P_n | PAD] -----
% All tokens are 21-d (1 type marker + 20 feature/pad cells). Two paddings:
%  • channel-padding inside packet tokens (cells 10..20, since pkt has 9 feats)
%  • sequence-padding tokens (entire token zeroed when actual flow length < T)
\begin{scope}[shift={(9.8, -1.45)}]
  % --- helper macros for cell drawing inside this scope ---
  % Each token: 1 type cell on top + 20 feature/pad cells below.
  % Cell height 0.085, cell width 0.42.
  % Token x-offsets: FLOW=0, P_1=0.62, P_2=1.22, P_n=2.30, PAD=2.92.
  %
  % FLOW token: type (dark blue) + 20 cont features (light blue), no padding
  \draw[fill=myblue!75, draw=myblue, line width=0.25pt]
        (0.0, 2.55) rectangle (0.42, 2.64);
  \foreach \i in {0,...,19} {
    \pgfmathsetmacro{\yp}{2.46 - \i*0.085}
    \draw[fill=myblue!25, draw=myblue!80, line width=0.25pt]
          (0.0, \yp) rectangle (0.42, \yp+0.075);
  }
  \node[font=\tiny, anchor=north, text=myblue!90!black] at (0.21, 0.72) {\textbf{FLOW}};
  %
  % P_1, P_2, P_n: type (orange) + 3 cont + 6 disc + 11 channel-pad
  \foreach \subi/\xoff in {1/0.62, 2/1.22, n/2.30} {
    % type marker (orange)
    \draw[fill=myorange!75, draw=myorange, line width=0.25pt]
          (\xoff, 2.55) rectangle (\xoff+0.42, 2.64);
    % 3 cont (blue)
    \foreach \i in {0,...,2} {
      \pgfmathsetmacro{\yp}{2.46 - \i*0.085}
      \draw[fill=myblue!25, draw=myblue!80, line width=0.25pt]
            (\xoff, \yp) rectangle (\xoff+0.42, \yp+0.075);
    }
    % 6 disc (orange)
    \foreach \i in {3,...,8} {
      \pgfmathsetmacro{\yp}{2.46 - \i*0.085}
      \draw[fill=myorange!30, draw=myorange!80, line width=0.25pt]
            (\xoff, \yp) rectangle (\xoff+0.42, \yp+0.075);
    }
    % 11 channel-pad (gray hatched)
    \foreach \i in {9,...,19} {
      \pgfmathsetmacro{\yp}{2.46 - \i*0.085}
      \draw[fill=mygray!30, draw=mygray, line width=0.2pt, dash pattern=on 0.4pt off 0.4pt]
            (\xoff, \yp) rectangle (\xoff+0.42, \yp+0.075);
    }
    \node[font=\tiny, anchor=north] at (\xoff+0.21, 0.72) {$P_{\subi}$};
  }
  %
  % Ellipsis centered in gap between P_2 (ends x=1.64) and P_n (starts x=2.30),
  % vertically centered on token cell stack (top=2.64, bottom=0.86)
  \node[font=\Large, text=black!55] at (1.97, 1.75) {$\cdots$};
  %
  % PAD token (sequence-padding): entire token grayed + dashed outer border
  \draw[fill=mygray!20, draw=mygray, dash pattern=on 1pt off 1pt, line width=0.4pt]
        (2.92, 2.55) rectangle (3.34, 2.64);
  \foreach \i in {0,...,19} {
    \pgfmathsetmacro{\yp}{2.46 - \i*0.085}
    \draw[fill=mygray!25, draw=mygray, line width=0.2pt, dash pattern=on 0.5pt off 0.5pt]
          (2.92, \yp) rectangle (3.34, \yp+0.075);
  }
  % outer dashed wrap to emphasize "this whole token is padding"
  \draw[draw=black!50, dashed, line width=0.5pt]
        (2.90, 0.72) rectangle (3.36, 2.66);
  \node[font=\tiny, anchor=north, text=black!65] at (3.13, 0.72) {\textbf{PAD}};
  %
  % Bottom brace + sequence label (below the FLOW/P_i/PAD name labels)
  \draw[decorate, decoration={brace, amplitude=3pt, mirror}, line width=0.4pt, black!60]
        (-0.05, 0.30) -- (3.39, 0.30);
  \node[font=\scriptsize\itshape, text=black!70] at (1.67, -0.05)
        {token sequence (1 flow + $T$ packets, all 21-d)};
\end{scope}

% Arrow: token → velocity (sequence ends at x=9.8+3.34=13.14)
\draw[arrow, black!60] (13.3, 0) -- (14.0, 0);

% ----- (4) Velocity field (with detailed internals, DiT-style) -----
% Outer box at x=14.0..19.0, y=-2.5..2.5  (5cm × 5cm)
\begin{scope}[shift={(14.0, -2.5)}]
  % Outer rounded box
  \draw[fill=myorange!8, draw=myorange, line width=1.4pt, rounded corners=2pt]
        (0, 0) rectangle (5.0, 5.0);
  \node[font=\sffamily\bfseries\small, anchor=north, text=myorange!90!black]
        at (2.5, 4.85) {Velocity Field};
  %
  % Time embedding sub-box (top-left)
  \draw[fill=white, draw=black!55, line width=0.4pt, rounded corners=1pt]
        (0.20, 3.60) rectangle (1.30, 4.45);
  \node[font=\tiny\bfseries, anchor=north] at (0.75, 4.42) {time $t$};
  \node[font=\tiny, anchor=north] at (0.75, 4.20) {sinusoidal};
  \node[font=\tiny, anchor=north] at (0.75, 4.00) {emb + MLP};
  %
  % AdaLN-Zero block 1
  \draw[fill=white, draw=black!60, line width=0.4pt, rounded corners=1pt]
        (1.55, 3.95) rectangle (4.80, 4.45);
  \node[font=\scriptsize] at (3.18, 4.20)
        {AdaLN-Zero \,($\gamma_1, \beta_1, \alpha_1$)};
  % Conditioning arrow from time emb to AdaLN-1
  \draw[->, dashed, line width=0.4pt, black!50]
        (1.30, 4.20) -- (1.55, 4.20);
  %
  % Arrow down
  \draw[->, line width=0.4pt, black!60] (3.18, 3.95) -- (3.18, 3.65);
  %
  % MHA block with causal mask icon
  \draw[fill=myorange!15, draw=myorange, line width=0.7pt, rounded corners=1pt]
        (1.55, 2.05) rectangle (4.80, 3.65);
  \node[font=\scriptsize\bfseries, anchor=north, text=myorange!85!black]
        at (3.18, 3.55) {\contrib\ Multi-Head Self-Attn};
  \node[font=\tiny\itshape, anchor=north, text=myorange!85!black]
        at (3.18, 3.30) {causal-packet mask};
  % Mini 5×5 lower-triangular mask grid
  \begin{scope}[shift={(2.55, 2.30)}]
    \foreach \i in {0,...,4} {
      \foreach \j in {0,...,4} {
        \ifnum\j>\i
          \draw[fill=white, draw=black!40, line width=0.15pt]
                (\j*0.22, -\i*0.16) rectangle (\j*0.22+0.20, -\i*0.16-0.14);
        \else
          \draw[fill=myorange!55, draw=myorange, line width=0.15pt]
                (\j*0.22, -\i*0.16) rectangle (\j*0.22+0.20, -\i*0.16-0.14);
        \fi
      }
    }
  \end{scope}
  %
  % Arrow down
  \draw[->, line width=0.4pt, black!60] (3.18, 2.05) -- (3.18, 1.75);
  %
  % AdaLN-Zero block 2
  \draw[fill=white, draw=black!60, line width=0.4pt, rounded corners=1pt]
        (1.55, 1.25) rectangle (4.80, 1.75);
  \node[font=\scriptsize] at (3.18, 1.50)
        {AdaLN-Zero \,($\gamma_2, \beta_2, \alpha_2$)};
  % Curved conditioning arrow from time emb to AdaLN-2
  \draw[->, dashed, line width=0.4pt, black!50]
        (0.75, 3.60) .. controls (0.40, 2.30) and (0.80, 1.50) .. (1.55, 1.50);
  %
  % Arrow down
  \draw[->, line width=0.4pt, black!60] (3.18, 1.25) -- (3.18, 0.95);
  %
  % MLP block
  \draw[fill=white, draw=black!60, line width=0.4pt, rounded corners=1pt]
        (1.55, 0.45) rectangle (4.80, 0.95);
  \node[font=\scriptsize] at (3.18, 0.70)
        {MLP \,($d \to 4d \to d$)};
  %
  % "× 4 layers" stacking annotation at the bottom
  \node[font=\scriptsize\itshape, anchor=south, text=black!70]
        at (2.5, 0.05) {(stacked $\times\,4$ layers)};
\end{scope}

% Helper coordinates for input/output of velocity field (so arrows still work)
\coordinate (vel_west) at (14.0, 0);
\coordinate (vel_east) at (19.0, 0);

% ----- (5) Two heads -----
\node[box, minimum width=22mm] (vh) at (20.5, 0.7) {%
  $v_\theta$ head\\
  {\scriptsize (continuous)}%
};
\node[novelbox, minimum width=22mm] (dh) at (20.5, -0.7) {%
  \contrib\ logits head\\
  {\scriptsize (discrete)}%
};

\draw[arrow] (vel_east) -- (vh.west);
\draw[arrow] (vel_east) -- (dh.west);

% ----- Loss equation -----
\node[losseq, minimum width=190mm, font=\small, align=center] (loss) at (9.85, -3.7) {%
  $\mathcal{L} \;=\;
   \underbrace{\| v_\theta(x_t,t) - (x_1 - x_0) \|^2}_{\text{continuous CFM}}
   \;+\; \lambda \cdot
   \underbrace{\mathrm{CE}(\mathrm{logits},\, x_{\mathrm{disc}})}_{\text{Discrete FM}\,\contrib}$%
};

% =========================================================================
%  INFERENCE ROW (no row title)
% =========================================================================

\node[databox, minimum width=18mm] (testflow) at (1.5, -5.7) {%
  {\scriptsize test}\\ flow%
};

\node[box, dashed, minimum width=28mm] (frozen) at (4.7, -5.7) {%
  \textsc{Frozen}\\
  \textsc{Backbone}\\
  {\scriptsize $v_\theta$ + logits}%
};

\node[box, minimum width=34mm] (svec) at (8.6, -5.7) {%
  \textsc{Score Vector} (10-d)\\[0.5mm]
  {\scriptsize\texttt{terminal\_norm}}\\
  {\scriptsize\texttt{terminal\_packet}}\\
  {\scriptsize\texttt{disc\_nll\_total}, \dots}%
};

\node[novelbox, minimum width=46mm, minimum height=22mm] (mahal) at (13.7, -5.7) {%
  \contrib\ \textsc{Mahalanobis-OAS Router}\\[1mm]
  $D^2 = (s-\mu)^\top \Sigma^{-1}_{\mathrm{OAS}} (s-\mu)$\\[1mm]
  {\scriptsize\itshape fit on benign val (no labels)}%
};

\node[databox, minimum width=18mm, fill=myblue!10] (out) at (18.5, -5.7) {%
  AUROC\\
  $s_{\text{anomaly}}$%
};

\draw[arrow] (testflow) -- (frozen);
\draw[arrow] (frozen) -- (svec);
\draw[arrow] (svec) -- (mahal);
\draw[arrow] (mahal) -- (out);

% =========================================================================
%  LEGEND
% =========================================================================
\node[draw=black!40, rounded corners=2pt, fill=white, inner sep=5pt, align=left,
      font=\scriptsize, anchor=north west] at (0, -7.3) {%
  \contrib\ \textbf{Our contributions} \quad
  \tikz\fill[myblue!25, draw=myblue, line width=0.4pt] (0,0) rectangle (0.22,0.16);
  \ continuous \quad
  \tikz\fill[myorange!30, draw=myorange, line width=0.4pt] (0,0) rectangle (0.22,0.16);
  \ discrete (DFM bits) \quad
  \tikz\fill[mygray!30, draw=mygray, line width=0.4pt, dash pattern=on 0.4pt off 0.4pt] (0,0) rectangle (0.22,0.16);
  \ channel-pad (9-d feat in 21-d slot) \quad
  \tikz\draw[dashed, draw=black!50, line width=0.4pt] (0,0) rectangle (0.22,0.16);
  \ sequence-pad (whole token, $n<T$)\\[2pt]
  \contrib\ Discrete-FM head on TCP flag bits + direction \quad
  \contrib\ Causal-packet attention (protocol-causal prior) \quad
  \contrib\ Mahalanobis-OAS auto-router (no selection bias)%
};

\end{tikzpicture}
\end{document}
