%%
%% 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}[%
  2019/03/20 v2.0 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_length_int
\int_new:N \l__braid_strands_int
\int_new:N \l__braid_crossing_int
\int_new:N \l__braid_anchor_level_int
\int_new:N \l__braid_floor_int
\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
\tikzset{
   braid/.pic={
     code={
       \__braid_parse_word:n {#1}
       \__braid_count:
       \__braid_render:
     }
   },
   floor/.pic={
     code={
       \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_set_from_clist: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:NT \l__braid_swap_crossing_bool
  {
    \seq_pop_left:NN \l__braid_crossing_seq \l__braid_tmpa_tl
    \seq_put_right:NV \l__braid_crossing_seq \l__braid_tmpa_tl
  }
}
\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
    {
      \int_set:Nn \l__braid_strands_int
      {
        \int_max:nn
        {
          \int_max:nn {\l__braid_strands_int}
          { \seq_item:Nn \l__braid_crossing_seq {1}}
        }
        {
          \seq_item:Nn \l__braid_crossing_seq {2}
        }
      }
    }
  }
  \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}}
  \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_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
    {
      \prop_get:NxN \l__braid_permutation_prop
      {
        \seq_item:Nn \l__braid_crossing_seq {1}
      } \l__braid_tmpa_tl
      \prop_get:NxN \l__braid_permutation_prop
      {
        \seq_item:Nn \l__braid_crossing_seq {2}
      } \l__braid_tmpb_tl

      \prop_put:NxV \l__braid_permutation_prop
      {
        \seq_item:Nn \l__braid_crossing_seq {2}
      } \l__braid_tmpa_tl
      \prop_put:NxV \l__braid_permutation_prop
      {
        \seq_item:Nn \l__braid_crossing_seq {1}
      } \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_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:
{
  \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
    {
      \prop_get:NxN \l__braid_crossing_permutation_prop
      {\seq_item:Nn \l__braid_crossing_seq {1}} \l__braid_tmpa_tl
      \prop_get:NxN \l__braid_crossing_permutation_prop
      {\seq_item:Nn \l__braid_crossing_seq {2}} \l__braid_tmpb_tl

      \prop_put:NxV \l__braid_crossing_permutation_prop
      {\seq_item:Nn \l__braid_crossing_seq {2}} \l__braid_tmpa_tl
      \prop_put:NxV \l__braid_crossing_permutation_prop
      {\seq_item:Nn \l__braid_crossing_seq {1}} \l__braid_tmpb_tl
      \prop_get:NxN \l__braid_strands_prop
      {\seq_item:Nn \l__braid_crossing_seq {1}} \l__braid_tmpa_tl
      \prop_get:NxN \l__braid_strands_prop
      {\seq_item:Nn \l__braid_crossing_seq {2}} \l__braid_tmpb_tl
      \tl_put_right:Nx \l__braid_tmpa_tl
      {
        \exp_not:N \__braid_lineto:nn

        {\fp_eval:n
          {
            (\seq_item:Nn \l__braid_crossing_seq {1} - 1)
            * \__braid_dim_value:n {width}
          }
        }
        {\fp_eval:n { \l__braid_height_fp + \l__braid_nudge_fp } }

        \exp_not:N \__braid_curveto:nnnnnn

        {0}
        {\fp_eval:n { \l__braid_control_fp}}

        {0}
        {\fp_eval:n {- \l__braid_control_fp}}

        {\fp_eval:n
          {
            (\seq_item:Nn \l__braid_crossing_seq {2} - 1)
            * \__braid_dim_value:n {width}
          }
        }
        {\fp_eval:n
          {
            \l__braid_height_fp
            + \__braid_dim_value:n {height}
            - \l__braid_nudge_fp
          }
        }
      }
      \tl_put_right:Nx \l__braid_tmpb_tl
      {
        \exp_not:N \__braid_lineto:nn

        {\fp_eval:n
          {
            (\seq_item:Nn \l__braid_crossing_seq {2} - 1)
            * \__braid_dim_value:n {width}
          }
        }
        {\fp_eval:n { \l__braid_height_fp + \l__braid_nudge_fp } }

        \exp_not:N \__braid_curveto:nnnnnn

        {0}
        {
          \fp_eval:n {
            \l__braid_control_fp  * (.5 - \__braid_value:n {gap} )
          }
        }

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

        {
          \fp_eval:n {
            (\seq_item:Nn \l__braid_crossing_seq {2} - 1)
            * \__braid_dim_value:n {width} +
            \__braid_bezier_point:nnnnn
            {.5 - \__braid_value:n {gap} }
            {0}
            {0}
            {
              (\seq_item:Nn \l__braid_crossing_seq {1}
              - \seq_item:Nn \l__braid_crossing_seq {2})
              * \__braid_dim_value:n {width}
            }
            {
              (\seq_item:Nn \l__braid_crossing_seq {1}
              - \seq_item:Nn \l__braid_crossing_seq {2})
              * \__braid_dim_value:n {width}
            }
          }
        }
        {
          \fp_eval:n {
          \l__braid_height_fp + \l__braid_nudge_fp +
            \__braid_bezier_point:nnnnn
            {.5 - \__braid_value:n {gap} }
            {0}
            {\l__braid_control_fp}
            {
              \__braid_dim_value:n {height}
              - 2* \l__braid_nudge_fp
              - \l__braid_control_fp
            }
            {\__braid_dim_value:n {height} - 2* \l__braid_nudge_fp}
          }
        }

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

        \exp_not:N \__braid_curveto:nnnnnn

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

        {0}
        { \fp_eval:n {
            -\l__braid_control_fp  * (.5 - \__braid_value:n {gap} )
          }
        }

        {\fp_eval:n
          {
            (\seq_item:Nn \l__braid_crossing_seq {1} - 1)
            * \__braid_dim_value:n {width}
          }
        }
        {\fp_eval:n
          {
            \l__braid_height_fp + \__braid_dim_value:n {height}
            - \l__braid_nudge_fp
          }
        }

      }
      \prop_put:NxV \l__braid_strands_prop
      {\seq_item:Nn \l__braid_crossing_seq {2}} \l__braid_tmpa_tl
      \prop_put:NxV \l__braid_strands_prop
      {\seq_item:Nn \l__braid_crossing_seq {1}} \l__braid_tmpb_tl
      \int_compare:nT
      {
        \int_max:nn
        {
          \seq_item:Nn \l__braid_crossing_seq {1}
        }
        {
          \seq_item:Nn \l__braid_crossing_seq {2}
        }
        -
        \int_min:nn
        {
          \seq_item:Nn \l__braid_crossing_seq {1}
        }
        {
          \seq_item:Nn \l__braid_crossing_seq {2}
        }
        > 1
      }
      {
        \int_step_inline:nnnn
        {
          \int_min:nn
          {
            \seq_item:Nn \l__braid_crossing_seq {1}
          }
          {
            \seq_item:Nn \l__braid_crossing_seq {2}
          }
          + 1}
        {1}
        {
          \int_max:nn
          {
            \seq_item:Nn \l__braid_crossing_seq {1}
          }
          {
            \seq_item:Nn \l__braid_crossing_seq {2}
          }
          - 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
                }
              }
              \exp_not:N \__braid_moveto:nn
              {\fp_eval:n {(####1 - 1) * \__braid_dim_value:n {width} }}
              {\fp_eval:n
                {
                  \l__braid_height_fp + \__braid_dim_value:n {height}
                  - \l__braid_nudge_fp - .5 * \l__braid_control_fp
                }
              }
            }

            \prop_put:NnV \l__braid_strands_prop {####1} \l__braid_tmpa_tl
          }
      }
    }
    \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
  }
  \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-2019 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'.
