%%
%% This is file `tikzlibrarybraids.code.tex',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% braids_code.dtx  (with options: `library')
%% ----------------------------------------------------------------
%% braids --- a style file for drawing braid diagrams with TikZ/PGF
%% E-mail: loopspace@mathforge.org
%% Released under the LaTeX Project Public License v1.3c or later
%% See http://www.latex-project.org/lppl.txt
%% ----------------------------------------------------------------
%% 
\ProvidesFile{tikzlibrarybraids.code.tex}[%
  2022/10/26 v2.2 Tikz/PGF library for drawing braid diagrams%
]
\RequirePackage{expl3}
\ExplSyntaxOn
\tl_new:N \l__braid_tmpa_tl
\tl_new:N \l__braid_tmpb_tl
\tl_new:N \l__braid_tmpc_tl
\tl_new:N \l__braid_tmpd_tl
\tl_new:N \l__braid_anchor_strand_tl
\tl_new:N \l__braid_anchor_level_tl
\fp_new:N \l__braid_height_fp
\fp_new:N \l__braid_width_fp
\fp_new:N \l__braid_nudge_fp
\fp_new:N \l__braid_control_fp
\fp_new:N \l__braid_ctrlax_fp
\fp_new:N \l__braid_ctrlay_fp
\fp_new:N \l__braid_ctrlbx_fp
\fp_new:N \l__braid_ctrlby_fp
\fp_new:N \l__braid_endx_fp
\fp_new:N \l__braid_endy_fp
\fp_new:N \l__braid_anchor_x_fp
\fp_new:N \l__braid_anchor_y_fp
\int_new:N \l__braid_tmpa_int
\int_new:N \l__braid_tmpb_int
\int_new:N \l__braid_length_int
\int_new:N \l__braid_strands_int
\int_new:N \l__braid_crossing_int
\int_new:N \l__braid_crossing_start_int
\int_new:N \l__braid_crossing_end_int
\int_new:N \l__braid_crossing_width_int
\int_new:N \l__braid_crossing_long_int
\int_new:N \l__braid_crossing_start_factor_int
\int_new:N \l__braid_crossing_end_factor_int
\int_new:N \l__braid_anchor_level_int
\int_new:N \l__braid_floor_int
\seq_new:N \l__braid_tmpa_seq
\seq_new:N \l__braid_word_seq
\seq_new:N \l__braid_crossing_seq
\seq_new:N \l__braid_anchor_seq
\seq_new:N \l__braid_floors_seq
\str_new:N \l__braid_tmpa_str
\str_new:N \l__braid_sup_str
\str_set:Nn \l__braid_sup_str {^}
\str_new:N \l__braid_sub_str
\str_set:Nn \l__braid_sub_str {_}
\str_new:N \l__braid_hyphen_str
\str_set:Nn \l__braid_hyphen_str {-}
\str_new:N \l__braid_bar_str
\str_set:Nn \l__braid_bar_str {|}
\str_new:N \l__braid_one_str
\str_set:Nn \l__braid_one_str {1}
\bool_new:N \l__braid_step_level_bool
\bool_new:N \l__braid_swap_crossing_bool
\bool_new:N \l__braid_floor_bool
\prop_new:N \l__braid_strands_prop
\prop_new:N \l__braid_permutation_prop
\prop_new:N \l__braid_crossing_permutation_prop
\prop_new:N \l__braid_inverse_prop
\prop_new:N \l__braid_anchor_prop
\cs_generate_variant:Nn \seq_set_split:Nnn {NVn}
\tikzset{
   braid/.pic={
     \__braid_parse_word:n {#1}
     \__braid_count:
     \__braid_render:
   },
   floor/.pic={
     \path[pic~ actions, draw=none] (0,0) rectangle (1,1);
     \path[pic~ actions, fill=none] (0,0) -- (1,0) (0,1) -- (1,1);
   },
   /tikz/braid/.search~ also={/tikz},
   braid/.cd,
   anchor/.initial=1-s,
   number~ of~ strands/.initial=0,
   height/.initial=-1cm,
   width/.initial=1cm,
   gap/.initial=.05,
   border~ height/.initial=.25cm,
   floor~ border/.initial=.25cm,
   add~ floor/.code={
     \seq_push:Nn \l__braid_floors_seq {#1}
   },
   control~ factor/.initial=.5,
   nudge~ factor/.initial=.05
}
\cs_new_nopar:Npn \__braid_parse_word:n #1
{
  \seq_clear:N \l__braid_word_seq
  \tl_clear:N \l__braid_tmpa_tl
  \tl_set:Nn \l__braid_tmpb_tl {#1}

  \bool_until_do:nn { \tl_if_empty_p:N \l__braid_tmpb_tl }
  {
    \str_set:Nx \l__braid_tmpa_str {\tl_head:N \l__braid_tmpb_tl}
    \tl_set:Nx \l__braid_tmpb_tl {\tl_tail:N \l__braid_tmpb_tl}
    \str_case_e:nnTF {\l__braid_tmpa_str}
    {
      {_}
     {
       \tl_put_right:Nx \l__braid_tmpa_tl
       {
         \exp_not:N \__braid_parse_index:n {\tl_head:N \l__braid_tmpb_tl}
       }
       \tl_set:Nx \l__braid_tmpb_tl {\tl_tail:N \l__braid_tmpb_tl}
     }
     {^}
     {
       \tl_put_left:Nx \l__braid_tmpa_tl
       {
         \exp_not:N \__braid_parse_exponent:n {\tl_head:N \l__braid_tmpb_tl}
       }
       \tl_set:Nx \l__braid_tmpb_tl {\tl_tail:N \l__braid_tmpb_tl}
     }
     {|}
     {
      \tl_if_empty:NF \l__braid_tmpa_tl
      {
        \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl
        \tl_clear:N \l__braid_tmpa_tl
      }

      \tl_set:Nn \l__braid_tmpa_tl {
        \bool_set_false:N \l__braid_step_level_bool
        \bool_set_true:N \l__braid_floor_bool
      }
      \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl
      \tl_clear:N \l__braid_tmpa_tl
     }
     {-}
     {
       \tl_put_right:Nn \l__braid_tmpa_tl
       {
         \bool_set_false:N \l__braid_step_level_bool
       }
     }
     {1}
     {
      \tl_if_empty:NF \l__braid_tmpa_tl
      {
        \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl
        \tl_clear:N \l__braid_tmpa_tl
      }
       \tl_put_right:Nn \l__braid_tmpa_tl {\__braid_do_identity:}
     }
     {~}
     {
     }
    }
    {
    }
    {
      \tl_if_empty:NF \l__braid_tmpa_tl
      {
        \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl
        \tl_clear:N \l__braid_tmpa_tl
      }
    }
  }
  \tl_if_empty:NF \l__braid_tmpa_tl
  {
    \seq_put_right:NV \l__braid_word_seq \l__braid_tmpa_tl
    \tl_clear:N \l__braid_tmpa_tl
  }
}
\cs_new_nopar:Npn \__braid_parse_index:n #1
{
  \seq_clear:N \l__braid_crossing_seq
  \clist_map_inline:nn {#1}
  {
    \tl_if_in:nnTF {##1} {-}
    {
      \seq_set_split:Nnn \l__braid_tmpa_seq {-} {##1}
      \int_compare:nTF {\seq_item:Nn \l__braid_tmpa_seq {1} < \seq_item:Nn \l__braid_tmpa_seq {2} }
      {
        \int_set:Nn \l__braid_tmpa_int {1}
      }
      {
        \int_set:Nn \l__braid_tmpa_int {-1}
      }
      \int_step_inline:nnnn {\seq_item:Nn \l__braid_tmpa_seq {1}} {\l__braid_tmpa_int} {\seq_item:Nn \l__braid_tmpa_seq {2}}
      {
        \seq_put_right:Nn \l__braid_crossing_seq {####1}
      }
    }
    {
      \seq_put_right:Nn \l__braid_crossing_seq {##1}
    }
  }
  \int_compare:nT {\seq_count:N \l__braid_crossing_seq == 1}
  {
    \seq_put_right:Nx \l__braid_crossing_seq {\int_eval:n {#1 + 1} }
  }
  \bool_if:NF \l__braid_swap_crossing_bool
  {
    \seq_reverse:N \l__braid_crossing_seq
  }
}
\cs_new_nopar:Npn \__braid_parse_exponent:n #1
{
  \int_compare:nTF {#1 == -1}
  {
    \bool_set_true:N \l__braid_swap_crossing_bool
  }
  {
    \bool_set_false:N \l__braid_swap_crossing_bool
  }
}
\cs_new_nopar:Npn \__braid_do_identity:
{
}
\cs_new_nopar:Npn \__braid_count:
{
  \int_zero:N \l__braid_length_int
  \int_set:Nn \l__braid_strands_int {\__braid_value:n {number~of~strands}}
  \prop_clear:N \l__braid_permutation_prop
  \prop_clear:N \l__braid_crossing_permutation_prop
  \prop_clear:N \l__braid_anchor_prop
  \prop_clear:N \l__braid_inverse_prop

  \seq_map_inline:Nn \l__braid_word_seq
  {
    \seq_clear:N \l__braid_crossing_seq
    \bool_set_true:N \l__braid_step_level_bool
    \bool_set_false:N \l__braid_swap_crossing_bool
    ##1
    \bool_if:NT \l__braid_step_level_bool
    {
      \int_incr:N \l__braid_length_int
    }
    \seq_if_empty:NF \l__braid_crossing_seq
    {
      \seq_map_inline:Nn \l__braid_crossing_seq
      {
        \int_set:Nn \l__braid_strands_int
        {
          \int_max:nn {\l__braid_strands_int} {####1}
        }
      }
    }
  }
  \int_step_inline:nnnn {1} {1} {\l__braid_strands_int}
  {
    \prop_put:Nnn \l__braid_permutation_prop {##1} {##1}
    \prop_put:Nnn \l__braid_anchor_prop {##1} {##1}
    \prop_put:Nnn \l__braid_crossing_permutation_prop {##1} {##1}
  }
  \tl_set:Nx \l__braid_tmpa_tl {\__braid_value:n {anchor}}
  \tl_if_in:NnTF \l__braid_tmpa_tl {-}
  {
    \seq_set_split:NnV \l__braid_anchor_seq {-} \l__braid_tmpa_tl

    \tl_set:Nx \l__braid_tmpa_tl {\seq_item:Nn \l__braid_anchor_seq {1}}
    \tl_if_eq:VnTF \l__braid_tmpa_tl {rev}
    {
      \tl_set:Nx \l__braid_anchor_strand_tl {\seq_item:Nn \l__braid_anchor_seq {2}}
      \tl_set:Nx \l__braid_anchor_level_tl {\seq_item:Nn \l__braid_anchor_seq {3}}
    }
    {
      \tl_set:Nx \l__braid_anchor_strand_tl {\seq_item:Nn \l__braid_anchor_seq {1}}
      \tl_set:Nx \l__braid_anchor_level_tl {\seq_item:Nn \l__braid_anchor_seq {2}}
    }
    \tl_if_eq:VnTF \l__braid_anchor_level_tl {s}
    {
      \int_set:Nn \l__braid_anchor_level_int {-1}
    }
    {
      \tl_if_eq:VnTF \l__braid_anchor_level_tl {e}
      {
        \int_set:Nn \l__braid_anchor_level_int {-1}
      }
      {
        \int_set:Nn \l__braid_anchor_level_int
        {\tl_use:N \l__braid_anchor_level_tl}
      }
    }
  }
  {
    \int_set:Nn \l__braid_anchor_level_int {-1}
    \tl_set:Nn \l__braid_anchor_strand_tl {-1}
  }

  \int_zero:N \l__braid_crossing_int
  \int_incr:N \l__braid_crossing_int
  \seq_map_inline:Nn \l__braid_word_seq
  {
    \bool_set_true:N \l__braid_step_level_bool
    \seq_clear:N \l__braid_crossing_seq
    \bool_set_false:N \l__braid_swap_crossing_bool
    ##1
    \seq_if_empty:NF \l__braid_crossing_seq
    {
      \int_step_inline:nnn {2} {\seq_count:N \l__braid_crossing_seq}
      {
        \int_set:Nn \l__braid_tmpa_int {####1}
        \int_set:Nn \l__braid_tmpb_int {####1 - 1}

        \prop_get:NxN \l__braid_permutation_prop
        {
          \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}
        } \l__braid_tmpa_tl
        \prop_get:NxN \l__braid_permutation_prop
        {
          \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}
        } \l__braid_tmpb_tl

        \prop_put:NxV \l__braid_permutation_prop
        {
          \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}
        } \l__braid_tmpa_tl
        \prop_put:NxV \l__braid_permutation_prop
        {
          \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}
        } \l__braid_tmpb_tl
      }
    }
    \int_compare:nT {\l__braid_crossing_int = \l__braid_anchor_level_int}
    {
      \prop_set_eq:NN \l__braid_anchor_prop \l__braid_permutation_prop
    }
    \bool_if:NT \l__braid_step_level_bool
    {
      \int_incr:N \l__braid_crossing_int
    }
  }
  \int_step_inline:nnnn {1} {1} {\l__braid_strands_int}
  {
    \prop_get:NnN \l__braid_anchor_prop {##1} \l__braid_tmpa_tl
    \prop_put:NVn \l__braid_inverse_prop \l__braid_tmpa_tl {##1}
  }
  \prop_set_eq:NN \l__braid_anchor_prop \l__braid_inverse_prop
  \int_step_inline:nnnn {1} {1} {\l__braid_strands_int}
  {
    \prop_get:NnN \l__braid_permutation_prop {##1} \l__braid_tmpa_tl
    \prop_put:NVn \l__braid_inverse_prop \l__braid_tmpa_tl {##1}
  }
  \tl_if_eq:VnF \l__braid_anchor_strand_tl {-1}
  {
    \tl_set:Nx \l__braid_tmpa_tl {\seq_item:Nn \l__braid_anchor_seq {1}}
    \tl_if_eq:VnT \l__braid_tmpa_tl {rev}
    {
      \prop_get:NVN \l__braid_permutation_prop
      \l__braid_anchor_strand_tl \l__braid_anchor_strand_tl
    }
    \tl_if_eq:VnF \l__braid_anchor_level_tl {s}
    {
      \tl_if_eq:VnTF \l__braid_anchor_level_tl {e}
      {
        \prop_get:NVN \l__braid_inverse_prop
        \l__braid_anchor_strand_tl \l__braid_anchor_strand_tl
      }
      {
        \prop_get:NVN \l__braid_anchor_prop
        \l__braid_anchor_strand_tl \l__braid_anchor_strand_tl
      }
    }
  }
}
\cs_new_nopar:Npn \__braid_dim_value:n #1
{
  \dim_to_fp:n {\pgfkeysvalueof{/tikz/braid/#1}}
}
\cs_new_nopar:Npn \__braid_value:n #1
{
  \pgfkeysvalueof{/tikz/braid/#1}
}
\cs_generate_variant:Nn \prop_get:NnN {NxN}
\cs_generate_variant:Nn \prop_put:Nnn {NxV}
\cs_generate_variant:Nn \tl_if_eq:nnTF {VnTF}
\cs_generate_variant:Nn \tl_if_eq:nnF {VnF}
\cs_generate_variant:Nn \tl_if_eq:nnT {VnT}

\cs_new_nopar:Npn \__braid_render:
{
  \tl_if_eq:VnTF \l__braid_anchor_strand_tl {-1}
  {
    \tl_set:cn {pgf@sh@ns@temporary braid node}{rectangle}
    \tl_set:cx {pgf@sh@np@temporary braid node}{%
      \exp_not:N\def
      \exp_not:N\southwest
      {
        \exp_not:N\pgfqpoint
        {0pt}
        {0pt}
      }
      \exp_not:N\def
      \exp_not:N\northeast
      {
        \exp_not:N\pgfqpoint
        {
          \fp_to_dim:n
          {
            (\l__braid_strands_int - 1)
            *
            abs(\__braid_dim_value:n {width})
          }
        }
        {
          \fp_to_dim:n
          {
            \l__braid_length_int * abs(\__braid_dim_value:n {height})
            + 2 * \__braid_dim_value:n {border~ height}
          }
        }
      }
    }%
    \pgfgettransform\l__braid_tmpa_tl
    \tl_set:cV {pgf@sh@nt@temporary braid node} \l__braid_tmpa_tl
    \tl_set:cV {pgf@sh@pi@temporary braid node} \pgfpictureid
    \pgfpointanchor{temporary braid node} {\__braid_value:n {anchor}}
    \fp_set:Nn \l__braid_anchor_x_fp {
      - \dim_use:c {pgf@x}
      - (1 - sign(\__braid_dim_value:n {width})) / 2
      * (\l__braid_strands_int - 1)
      * \__braid_dim_value:n {width}
    }
    \fp_set:Nn \l__braid_anchor_y_fp {
      - \dim_use:c {pgf@y}
      - (1 - sign(\__braid_dim_value:n {height})) / 2
      * (
      \l__braid_length_int * abs(\__braid_dim_value:n {height})
      + 2 * \__braid_dim_value:n {border~ height}
      ) * sign(\__braid_dim_value:n {height})
    }
  }
  {
    \fp_set:Nn \l__braid_anchor_x_fp { - 1 * (\tl_use:N \l__braid_anchor_strand_tl - 1) * \__braid_dim_value:n {width} }

    \tl_if_eq:VnTF \l__braid_anchor_level_tl {s}
    {
      \fp_set:Nn \l__braid_anchor_y_fp {0}
    }
    {
      \tl_if_eq:VnTF \l__braid_anchor_level_tl {e}
      {
        \fp_set:Nn \l__braid_anchor_y_fp {
          -1 * \l__braid_length_int * \__braid_dim_value:n {height}
          - sign(\__braid_dim_value:n {height})
          * 2 * \__braid_dim_value:n {border~ height}
        }
      }
      {
        \fp_set:Nn \l__braid_anchor_y_fp {
          -1 * \l__braid_anchor_level_tl * \__braid_dim_value:n {height}
          - sign(\__braid_dim_value:n {height})
          * \__braid_dim_value:n {border~ height}
        }
      }
    }
  }

  \begin{scope}[
    shift={
      (\fp_to_decimal:N \l__braid_anchor_x_fp pt,
      \fp_to_decimal:N \l__braid_anchor_y_fp pt
      )
    }
  ]
  \prop_clear:N \l__braid_strands_prop
  \fp_zero:N \l__braid_height_fp
  \fp_zero:N \l__braid_nudge_fp
  \fp_zero:N \l__braid_control_fp
  \fp_set:Nn \l__braid_height_fp
  {
    sign(\__braid_dim_value:n {height})
    * \__braid_dim_value:n {border~ height}
  }
  \fp_set:Nn \l__braid_width_fp
  {
    (\l__braid_strands_int - 1) * \__braid_dim_value:n {width}
    + 2 * sign(\__braid_dim_value:n{width})
    * \__braid_dim_value:n {floor~ border}
  }
  \fp_set:Nn \l__braid_nudge_fp
  {
    \__braid_value:n {nudge~ factor} * \__braid_dim_value:n {height}
  }
  \fp_set:Nn \l__braid_control_fp
  {
    \__braid_value:n {control~ factor} * \__braid_dim_value:n {height}
  }
  \fp_sub:Nn \l__braid_control_fp {\l__braid_nudge_fp}
  \int_step_inline:nnnn {1} {1} {\l__braid_strands_int}
  {
    \prop_get:NnN \l__braid_inverse_prop {##1} \l__braid_tmpa_tl
    \prop_put:Nnx \l__braid_strands_prop {##1}
    {
      \exp_not:N \draw[
        braid/every~ strand/.try,
        braid/strand~ ##1/.try
      ]
      \exp_not:N \__braid_moveto:nn {
        \fp_eval:n {(##1 - 1) * \__braid_dim_value:n {width} }
      } {0}
      \exp_not:N \__braid_lineto:nn  {
        \fp_eval:n {(##1 - 1) * \__braid_dim_value:n {width} }
      } { \fp_to_decimal:N \l__braid_height_fp}
    }
    \__braid_coordinate:xxxx {-##1-s} {-rev-\l__braid_tmpa_tl-s}
    {\fp_eval:n {(##1 - 1) * \__braid_dim_value:n {width} }} {0}

    \__braid_coordinate:xxxx {-##1-0} {-rev-\l__braid_tmpa_tl-0}
    {\fp_eval:n {(##1 - 1) * \__braid_dim_value:n {width} }}
    { \fp_to_decimal:N \l__braid_height_fp}
  }
  \seq_map_inline:Nn \l__braid_floors_seq
  {
    \tl_set:Nx \l__braid_tmpa_tl {\clist_item:nn {##1} {5}}
    \__braid_do_floor:Vxxxx \l__braid_tmpa_tl
    {\fp_eval:n
      {
        -1*sign(\__braid_dim_value:n{width})
        * \__braid_dim_value:n {floor~ border}
        + (\__braid_dim_value:n {width}) * (\clist_item:nn {##1} {1} - 1)
      }
      pt
    }
    {\fp_eval:n
      {
        \l__braid_height_fp + ( \__braid_dim_value:n {height} ) * (\clist_item:nn {##1} {2})
      }
      pt
    }
    {\fp_eval:n {
        ( (\clist_item:nn {##1} {3}) * \__braid_dim_value:n {width}
        + 2 * sign(\__braid_dim_value:n{width})
        * \__braid_dim_value:n {floor~ border} ) / \dim_to_fp:n {1cm}
      }
    }
    {\fp_eval:n {
        (\clist_item:nn {##1} {4}) * ( \__braid_dim_value:n {height} ) / \dim_to_fp:n {1cm}
      }
    }
  }
  \int_zero:N \l__braid_crossing_int
  \int_incr:N \l__braid_crossing_int

  \seq_map_inline:Nn \l__braid_word_seq
  {
    \seq_clear:N \l__braid_crossing_seq
    \bool_set_true:N \l__braid_step_level_bool
    \bool_set_false:N \l__braid_floor_bool
    \bool_set_false:N \l__braid_swap_crossing_bool
    ##1
    \bool_if:NT \l__braid_floor_bool
    {
      \__braid_do_floor:Vxxxx \l__braid_crossing_int
      {\fp_eval:n
        {
          -1*sign(\__braid_dim_value:n{width})
          * \__braid_dim_value:n {floor~ border}
        }
        pt
      }
      {\fp_to_decimal:N \l__braid_height_fp pt}
      {\fp_eval:n { \l__braid_width_fp / \dim_to_fp:n {1cm} }}
      {\fp_eval:n { ( \__braid_dim_value:n {height} ) / \dim_to_fp:n {1cm}}}
    }
    \seq_if_empty:NF \l__braid_crossing_seq
    {
      \int_set:Nn \l__braid_crossing_long_int
      {
        %        \seq_item:Nn \l__braid_crossing_seq {\seq_count:N \l__braid_crossing_seq}
        \seq_item:Nn \l__braid_crossing_seq {1}
      }
      \int_set:Nn \l__braid_crossing_start_int
      {
        \int_min:nn
        {
          \seq_item:Nn \l__braid_crossing_seq {1}
        }
        {
          \seq_item:Nn \l__braid_crossing_seq {\seq_count:N \l__braid_crossing_seq}
        }
      }
      \int_set:Nn \l__braid_crossing_end_int
      {
        \int_max:nn
        {
          \seq_item:Nn \l__braid_crossing_seq {1}
        }
        {
          \seq_item:Nn \l__braid_crossing_seq {\seq_count:N \l__braid_crossing_seq}
        }

      }
      \int_set:Nn \l__braid_crossing_width_int
      {
        \l__braid_crossing_end_int
        -
        \l__braid_crossing_start_int
      }
      \int_step_inline:nnn {2} {\seq_count:N \l__braid_crossing_seq}
      {
        \int_set:Nn \l__braid_tmpa_int {####1}
        \int_set:Nn \l__braid_tmpb_int {####1 - 1}
      \prop_get:NxN \l__braid_crossing_permutation_prop
      {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}} \l__braid_tmpa_tl
      \prop_get:NxN \l__braid_crossing_permutation_prop
      {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}} \l__braid_tmpb_tl

      \prop_put:NxV \l__braid_crossing_permutation_prop
      {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}} \l__braid_tmpa_tl
      \prop_put:NxV \l__braid_crossing_permutation_prop
      {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}} \l__braid_tmpb_tl
      \prop_get:NxN \l__braid_strands_prop
      {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}} \l__braid_tmpa_tl
      \prop_get:NxN \l__braid_strands_prop
      {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}} \l__braid_tmpb_tl
        \int_set:Nn \l__braid_crossing_start_factor_int {0}
        \int_set:Nn \l__braid_crossing_end_factor_int {0}

        \int_compare:nT {
          ####1 = \seq_count:N \l__braid_crossing_seq
        }
        {
          \int_set:Nn \l__braid_crossing_end_factor_int {1}
        }
        \int_compare:nT {
          ####1 = 2
        }
        {
          \int_set:Nn \l__braid_crossing_start_factor_int {1}
        }

      \tl_put_right:Nx \l__braid_tmpa_tl
      {
        \exp_not:N \__braid_lineto:nn

        {\fp_eval:n
          {
            (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} - 1)
            * \__braid_dim_value:n {width}
          }
        }
        {\fp_eval:n { \l__braid_height_fp + \l__braid_nudge_fp * \l__braid_crossing_start_factor_int
            + \__braid_dim_value:n {height} * (####1 - 2)/(\seq_count:N \l__braid_crossing_seq - 1)
 } }

        \exp_not:N \__braid_curveto:nnnnnn

        {0}
        {\fp_eval:n { \l__braid_control_fp
            * 1/(\seq_count:N \l__braid_crossing_seq - 1)}}

        {0}
        {\fp_eval:n {- \l__braid_control_fp
            * 1/(\seq_count:N \l__braid_crossing_seq - 1)}}

        {\fp_eval:n
          {
            (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int} - 1)
            * \__braid_dim_value:n {width}
          }
        }
        {\fp_eval:n
          {
            \l__braid_height_fp
            + \__braid_dim_value:n {height} * (####1 - 1)/(\seq_count:N \l__braid_crossing_seq - 1)
            - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int
          }
        }
      }
        \int_set:Nn \l__braid_crossing_start_factor_int {0}
        \int_set:Nn \l__braid_crossing_end_factor_int {0}

        \int_compare:nT {
          ####1 = \seq_count:N \l__braid_crossing_seq
        }
        {
          \int_set:Nn \l__braid_crossing_end_factor_int {1}
        }
        \int_compare:nT {
          ####1 = 2
        }
        {
          \int_set:Nn \l__braid_crossing_start_factor_int {1}
        }

      \tl_put_right:Nx \l__braid_tmpb_tl
      {
        \exp_not:N \__braid_lineto:nn

        {\fp_eval:n
          {
            (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int} - 1)
            * \__braid_dim_value:n {width}
          }
        }
        {\fp_eval:n { \l__braid_height_fp + \l__braid_nudge_fp * \l__braid_crossing_start_factor_int
            + \__braid_dim_value:n {height} * (####1 - 2)/(\seq_count:N \l__braid_crossing_seq - 1)

        } }

        \exp_not:N \__braid_curveto:nnnnnn

        {0}
        {
          \fp_eval:n {
            \l__braid_control_fp  * (.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) ) * 1/(\seq_count:N \l__braid_crossing_seq - 1)
          }
        }

        {
          \fp_eval:n {
            - (.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) ) / 3 *
            \__braid_bezier_tangent:nnnnn
            {.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) }
            {0}
            {0}
            {
              (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}
              - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int})
              * \__braid_dim_value:n {width}
            }
            {
              (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}
              - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int})
              * \__braid_dim_value:n {width}
            }
          }
        }
        {
          \fp_eval:n {
            -(.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) ) / 3 *
            \__braid_bezier_tangent:nnnnn
            {.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) }
            {0}
            {
              \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1)
            }
            {
              \__braid_dim_value:n {height} * 1/(\seq_count:N \l__braid_crossing_seq - 1)
              - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int
              - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int
              - \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1)
            }
            {
              \__braid_dim_value:n {height} *  1/(\seq_count:N \l__braid_crossing_seq - 1)
              - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int
              - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int
            }
          }
        }

        {
          \fp_eval:n {
            (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int} - 1)
            * \__braid_dim_value:n {width} +
            \__braid_bezier_point:nnnnn
            {.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) }
            {0}
            {0}
            {
              (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}
              - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int})
              * \__braid_dim_value:n {width}
            }
            {
              (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}
              - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int})
              * \__braid_dim_value:n {width}
            }
          }
        }
        {
          \fp_eval:n {
            \l__braid_height_fp
            + \l__braid_nudge_fp * \l__braid_crossing_start_factor_int
            + \__braid_dim_value:n {height} * (####1 - 2)/(\seq_count:N \l__braid_crossing_seq - 1)
            +
            \__braid_bezier_point:nnnnn
            {.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) }
            {0}
            {
              \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1)
            }
            {
              \__braid_dim_value:n {height} *  1/(\seq_count:N \l__braid_crossing_seq - 1)
              - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int
              - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int
              - \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1)
            }
            {\__braid_dim_value:n {height} *  1/(\seq_count:N \l__braid_crossing_seq - 1)
              - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int
              - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int
            }
          }
        }

        \exp_not:N \__braid_moveto:nn
        {
          \fp_eval:n {
            (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int} - 1)
            * \__braid_dim_value:n {width} +
            \__braid_bezier_point:nnnnn
            {.5 + \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) }
            {0}
            {0}
            {
              (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}
              - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int})
              * \__braid_dim_value:n {width}
            }
            {
              (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}
              - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int})
              * \__braid_dim_value:n {width}
            }
          }
        }
        {
          \fp_eval:n {
            \l__braid_height_fp
            + \l__braid_nudge_fp * \l__braid_crossing_start_factor_int
            + \__braid_dim_value:n {height} * (####1 - 2)/(\seq_count:N \l__braid_crossing_seq - 1)
            +
            \__braid_bezier_point:nnnnn
            {.5 + \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) }
            {0}
            {
              \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1)
            }
            {
              \__braid_dim_value:n {height} *  1/(\seq_count:N \l__braid_crossing_seq - 1)
              - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int
              - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int
              - \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1)
            }
            {\__braid_dim_value:n {height} *  1/(\seq_count:N \l__braid_crossing_seq - 1)
              - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int
              - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int
            }
          }
        }

        \exp_not:N \__braid_curveto:nnnnnn

        {
          \fp_eval:n {
            (.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) ) / 3 *
            \__braid_bezier_tangent:nnnnn
            {.5 + \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) }
            {0}
            {0}
            {
              (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}
              - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int})
              * \__braid_dim_value:n {width}
            }
            {
              (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}
              - \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int})
              * \__braid_dim_value:n {width}
            }
          }
        }
        {
          \fp_eval:n {
            (.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) ) / 3 *
            \__braid_bezier_tangent:nnnnn
            {.5 + \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) }
            {0}
            {
              \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1)
            }
            {
              \__braid_dim_value:n {height} *  1/(\seq_count:N \l__braid_crossing_seq - 1)
              - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int
              - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int
              - \l__braid_control_fp * 1/(\seq_count:N \l__braid_crossing_seq - 1)
            }
            {\__braid_dim_value:n {height} *  1/(\seq_count:N \l__braid_crossing_seq - 1)
              - \l__braid_nudge_fp * \l__braid_crossing_start_factor_int
              - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int
            }
          }
        }

        {0}
        {\fp_eval:n {
            - \l__braid_control_fp  * (.5 - \__braid_value:n {gap} * (\seq_count:N \l__braid_crossing_seq - 1) )
            * 1/(\seq_count:N \l__braid_crossing_seq - 1)}
        }

        {\fp_eval:n
          {
            (\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int} - 1)
            * \__braid_dim_value:n {width}
          }
        }
        {\fp_eval:n
          {
            \l__braid_height_fp
            + \__braid_dim_value:n {height} * (####1 - 1)/(\seq_count:N \l__braid_crossing_seq - 1)
            - \l__braid_nudge_fp * \l__braid_crossing_end_factor_int
          }
        }

      }
      \prop_put:NxV \l__braid_strands_prop
      {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}} \l__braid_tmpa_tl
      \prop_put:NxV \l__braid_strands_prop
      {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}} \l__braid_tmpb_tl
      \int_compare:nT
      {
        \int_max:nn
        {
          \seq_item:Nn \l__braid_crossing_seq {####1 - 1}
        }
        {
          \seq_item:Nn \l__braid_crossing_seq {####1}
        }
        -
        \int_min:nn
        {
          \seq_item:Nn \l__braid_crossing_seq {####1 - 1}
        }
        {
          \seq_item:Nn \l__braid_crossing_seq {####1}
        }
        > 1
      }
      {
        \int_step_inline:nnnn
        {
          \int_min:nn
          {
            \seq_item:Nn \l__braid_crossing_seq {####1 - 1}
          }
          {
            \seq_item:Nn \l__braid_crossing_seq {####1}
          }
          + 1}
        {1}
        {
          \int_max:nn
          {
            \seq_item:Nn \l__braid_crossing_seq {####1 - 1}
          }
          {
            \seq_item:Nn \l__braid_crossing_seq {####1}
          }
          - 1
        }
        {

          \prop_get:NnN \l__braid_strands_prop {########1} \l__braid_tmpa_tl
          \tl_put_right:Nx \l__braid_tmpa_tl
            {
              \exp_not:N \__braid_lineto:nn
              {\fp_eval:n {(########1 - 1) * \__braid_dim_value:n {width} }}
              {\fp_eval:n
                {
                  \l__braid_height_fp + \l__braid_nudge_fp
                  + .5 * \l__braid_control_fp / (\seq_count:N \l__braid_crossing_seq - 1)
                  + \__braid_dim_value:n {height} * (####1 - 2)/(\seq_count:N \l__braid_crossing_seq - 1)
                }
              }
              \exp_not:N \__braid_moveto:nn
              {\fp_eval:n {(########1 - 1) * \__braid_dim_value:n {width} }}
              {\fp_eval:n
                {
                  \l__braid_height_fp
                  - \l__braid_nudge_fp - .5 * \l__braid_control_fp / (\seq_count:N \l__braid_crossing_seq - 1)
                  + \__braid_dim_value:n {height} * (####1 - 1)/(\seq_count:N \l__braid_crossing_seq - 1)
                }
              }
            }

            \prop_put:NnV \l__braid_strands_prop {########1} \l__braid_tmpa_tl
          }
      }
      \int_compare:nTF
      {
        \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}
        =
        \l__braid_crossing_long_int
      }
      {
        \int_set:Nn \l__braid_crossing_long_int {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}}
      }
      {
      \int_compare:nT
      {
        \seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpb_int}
        =
        \l__braid_crossing_long_int
      }
      {
        \int_set:Nn \l__braid_crossing_long_int {\seq_item:Nn \l__braid_crossing_seq {\l__braid_tmpa_int}}
      }

      }
      }
    }
    \bool_if:NT \l__braid_step_level_bool
    {
      \fp_add:Nn \l__braid_height_fp { \__braid_dim_value:n {height} }

      \int_step_inline:nnnn {1} {1} {\l__braid_strands_int}
      {
        \prop_get:NnN \l__braid_crossing_permutation_prop
        {####1} \l__braid_tmpb_tl
        \prop_get:NVN \l__braid_inverse_prop
        \l__braid_tmpb_tl \l__braid_tmpa_tl

        \__braid_coordinate:xxxx
        {-\l__braid_tmpb_tl-\int_use:N \l__braid_crossing_int}
        {-rev-\l__braid_tmpa_tl-\int_use:N \l__braid_crossing_int }
        {\fp_eval:n { (####1 - 1) * \__braid_dim_value:n {width} }}
        {\fp_to_decimal:N \l__braid_height_fp}
      }

      \int_incr:N \l__braid_crossing_int
    }
  }

  \fp_add:Nn \l__braid_height_fp
  {
    sign(\__braid_dim_value:n {height})
    * \__braid_dim_value:n {border~ height}
  }
  \int_step_inline:nnnn {1} {1} {\l__braid_strands_int}
  {
    \prop_get:NxN \l__braid_strands_prop {##1} \l__braid_tmpa_tl
    \prop_get:NxN \l__braid_permutation_prop {##1} \l__braid_tmpb_tl

    \tl_put_right:Nx \l__braid_tmpa_tl {
      \exp_not:N \__braid_lineto:nn
      {\fp_eval:n { (##1 - 1) * \__braid_dim_value:n {width} }}
      {\fp_to_decimal:N \l__braid_height_fp}
      coordinate (-rev-##1-e)
      coordinate (-\l__braid_tmpb_tl-e)
      ;
    }

    \prop_put:NnV \l__braid_strands_prop {##1} \l__braid_tmpa_tl
  }
  \int_step_inline:nnnn {1} {1} {\l__braid_strands_int}
  {
    \prop_get:NnN \l__braid_strands_prop {##1} \l__braid_tmpa_tl
    \tl_use:N \l__braid_tmpa_tl
  }
  \tl_if_empty:cF {tikz@fig@name}
  {
    \tl_gset:cn {pgf@sh@ns@ \tl_use:c{tikz@fig@name} }{rectangle}
    \tl_gset:cx {pgf@sh@np@ \tl_use:c{tikz@fig@name} }{%
      \exp_not:N\def
      \exp_not:N\southwest
      {
        \exp_not:N\pgfqpoint
        {
          \fp_to_dim:n
          {
            min(0,
            (\l__braid_strands_int - 1)
            *
            (\__braid_dim_value:n {width})
            )
          }
        }
        {
          \fp_to_dim:n
          {
            min(0,
            \l__braid_length_int * (\__braid_dim_value:n {height})
            + 2 * sign(\__braid_dim_value:n {height}) *
            \__braid_dim_value:n {border~ height}
            )
          }
        }
      }
      \exp_not:N\def
      \exp_not:N\northeast
      {
        \exp_not:N\pgfqpoint
        {
          \fp_to_dim:n
          {
            max(0,
            (\l__braid_strands_int - 1)
            *
            (\__braid_dim_value:n {width})
            )
          }
        }
        {
          \fp_to_dim:n
          {
            max(0,
            \l__braid_length_int * (\__braid_dim_value:n {height})
            + 2 * sign(\__braid_dim_value:n {height}) *
            \__braid_dim_value:n {border~ height}
            )
          }
        }
      }
    }%
    \pgfgettransform\l__braid_tmpa_tl
    \tl_gset:cV {pgf@sh@nt@ \tl_use:c{tikz@fig@name} } \l__braid_tmpa_tl
    \tl_gset:cV {pgf@sh@pi@ \tl_use:c{tikz@fig@name} } \pgfpictureid
  }
  \end{scope}
}
\cs_new_nopar:Npn \__braid_moveto:nn #1#2
{
  (#1 pt, #2 pt)
}
\cs_new_nopar:Npn \__braid_lineto:nn #1#2
{
  -- (#1 pt, #2 pt)
}
\cs_new_nopar:Npn \__braid_curveto:nnnnnn #1#2#3#4#5#6
{
  .. controls +(#1 pt, #2 pt) and +(#3 pt, #4 pt)
  .. (#5 pt, #6 pt)
}
\cs_new_nopar:Npn \__braid_coordinate:nnnn #1#2#3#4
{
  \coordinate[alias=#2] (#1) at (#3 pt,#4 pt);
}
\cs_generate_variant:Nn \__braid_coordinate:nnnn {xxxx}
\cs_new_nopar:Npn \__braid_bezier_point:nnnnn #1#2#3#4#5
{
  \fp_eval:n
  {
    (1 - (#1)) * (1 - (#1)) * (1 - (#1)) * (#2)
    +
    3 * (1 - (#1)) * (1 - (#1)) * (#1) * (#3)
    +
    3 * (1 - (#1)) * (#1) * (#1) * (#4)
    +
    (#1) * (#1) * (#1) * (#5)
  }
}
\cs_new_nopar:Npn \__braid_bezier_tangent:nnnnn #1#2#3#4#5
{
  \fp_eval:n
  {
    3 * (1 - (#1)) * (1 - (#1)) * (#3 - (#2))
    +
    6 * (1 - (#1)) * (#1) * (#4 - (#3))
    +
    3 * (#1) * (#1) * (#5 - (#4))
  }
}
\cs_new_nopar:Npn \__braid_do_floor:nnnnn #1#2#3#4#5
{
  \pic[pic~ type=floor,
    xscale=#4,
    yscale=#5,
    at={(#2,#3)},
    braid/every~ floor/.try,
    braid/floor~#1/.try,
  ];
}
\cs_generate_variant:Nn \__braid_do_floor:nnnnn {Vxxxx}
\ExplSyntaxOff

%% 
%% Copyright (C) 2011-2022 by Andrew Stacey <loopspace@mathforge.org>
%% 
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License (LPPL), either
%% version 1.3c of this license or (at your option) any later
%% version.  The latest version of this license is in the file:
%% 
%% http://www.latex-project.org/lppl.txt
%% 
%% This work is "maintained" (as per LPPL maintenance status) by
%% Andrew Stacey.
%% 
%% This work consists of the files  braids.dtx
%%                                  braids_doc.tex
%% and the derived files            README.txt,
%%                                  braids.ins,
%%                                  braids.pdf,
%%                                  braids.sty,
%%                                  tikzlibrarybraids.code.tex,
%%                                  braids_doc.pdf.
%% 
%%
%% End of file `tikzlibrarybraids.code.tex'.
