%%
%% This is file `tikzlibrarytilings.code.tex',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% tilings_code.dtx  (with options: `tilings')
%% ----------------------------------------------------------------
%% tilings --- TikZ library for producing tilings
%% E-mail: loopspace@mathforge.org
%% Released under the LaTeX Project Public License v1.3c or later
%% See http://www.latex-project.org/lppl.txt
%% ----------------------------------------------------------------
%% 
\ProvidesExplFile
      {tikzlibrarytilings.code.tex}
      {2023/06/01}
      {2.0}
      {TikZ pics for tilings such as Penrose tiles}
\RequirePackage{tikz}
\usetikzlibrary{spath3}
\ExplSyntaxOn
\tl_new:N \g__tilings_side_a_tl
\tl_new:N \g__tilings_side_b_tl
\tl_new:N \g__tilings_side_c_tl
\tl_new:N \g__tilings_side_d_tl
\tl_new:N \g__tilings_side_e_tl
\tl_new:N \g__tilings_side_A_tl
\tl_new:N \g__tilings_side_B_tl
\tl_new:N \g__tilings_side_C_tl
\tl_new:N \g__tilings_side_D_tl
\tl_new:N \g__tilings_side_E_tl
\tl_new:c {g__tilings_side_1_tl}
\tl_new:c {g__tilings_side_2_tl}
\tl_new:c {g__tilings_side_3_tl}
\tl_gset:Nn \g__tilings_side_a_tl
{
  \pgfsyssoftpath@movetotoken{0pt}{0pt}
  \pgfsyssoftpath@linetotoken{1pt}{0pt}
}
\tl_gset_eq:NN \g__tilings_side_b_tl \g__tilings_side_a_tl
\tl_gset_eq:NN \g__tilings_side_c_tl \g__tilings_side_a_tl
\tl_gset_eq:NN \g__tilings_side_d_tl \g__tilings_side_a_tl
\tl_gset_eq:NN \g__tilings_side_e_tl \g__tilings_side_a_tl
\tl_gset_eq:NN \g__tilings_side_A_tl \g__tilings_side_a_tl
\tl_gset_eq:NN \g__tilings_side_B_tl \g__tilings_side_a_tl
\tl_gset_eq:NN \g__tilings_side_C_tl \g__tilings_side_a_tl
\tl_gset_eq:NN \g__tilings_side_D_tl \g__tilings_side_a_tl
\tl_gset_eq:NN \g__tilings_side_E_tl \g__tilings_side_a_tl
\tl_gset_eq:cN {g__tilings_side_1_tl} \g__tilings_side_a_tl
\tl_gset_eq:cN {g__tilings_side_2_tl} \g__tilings_side_a_tl
\tl_gset_eq:cN {g__tilings_side_3_tl} \g__tilings_side_a_tl
\fp_new:N \l__tilings_tmpa_fp
\fp_new:N \l__tilings_tmpb_fp
\fp_new:N \l__tilings_tmpc_fp
\fp_new:N \l__tilings_saved_x_fp
\fp_new:N \l__tilings_saved_y_fp
\str_new:N \l__tilings_tmpa_str
\str_new:N \l__tilings_tmpb_str
\seq_new:N \l__tilings_tmpa_seq
\tl_new:N \l__tilings_tmpa_tl
\tl_new:N \l__tilings_tmpb_tl
\tl_new:N \l__tilings_tmpc_tl
\tl_new:N \l__tilings_tmpd_tl
\tl_new:N \l__tilings_tmp_tile_path_tl
\tl_new:N \l__tilings_action_lms_tl
\tl_new:N \l__tilings_parameters_lms_tl
\int_new:N \l__tilings_tmpa_int
\int_new:N \l__tilings_tmpb_int
\fp_new:N \l__tilings_xa_fp
\fp_new:N \l__tilings_ya_fp
\fp_new:N \l__tilings_xb_fp
\fp_new:N \l__tilings_yb_fp
\dim_new:N \l__tilings_xa_dim
\dim_new:N \l__tilings_ya_dim
\dim_new:N \l__tilings_xb_dim
\dim_new:N \l__tilings_yb_dim
\dim_new:N \g__tilings_xa_dim
\dim_new:N \g__tilings_ya_dim
\dim_new:N \g__tilings_xb_dim
\dim_new:N \g__tilings_yb_dim
\prop_new:N \l__tilings_tmpa_prop
\bool_new:N \l__tilings_cw_bool
\bool_new:N \l__tilings_update_saved_bool
\bool_new:N \l__tilings_relative_bool
\bool_new:N \l__tilings_edge_bool
\str_const:Nn \c__tilings_colon_str {:}
\str_const:Nn \c__tilings_comma_str {,}
\fp_const:Nn \c__tilings_cm_fp {\dim_to_fp:n {1cm}}
\tl_new:N \g__tilings_output_tl
\fp_new:N \g__tilings_output_a_fp
\fp_new:N \g__tilings_output_b_fp
\prop_new:N \g__tilings_tilenames_prop
\regex_const:Nn \c__tilings_anchor_regex {\s\w+\Z}
\cs_generate_variant:Nn \seq_set_split:Nnn {NVV}
\cs_generate_variant:Nn \regex_extract_once:NnNTF {NVNTF}
\cs_generate_variant:Nn \tl_if_eq:nnT {nVT}
\cs_generate_variant:Nn \tl_if_in:NnT {NVT}
\cs_generate_variant:Nn \prop_item:Nn {cV}
\cs_generate_variant:Nn \tl_if_head_is_group_p:n {V}
\msg_new:nnn { tilings }{ not baked }
{ Tile~ #1~ has~ not~ been~ baked. }
\msg_new:nnn { tilings }{ no tile }
{ Tile~ #1~ has~ not~ been~ defined. }
\msg_new:nnn { tilings }{ no side }
{ Tile~ side~ #1~ has~ not~ been~ defined,~ using~ default. }
\msg_new:nnn { tilings }{ tile no edge }
{ Tile~ #1~ doesn't~ have~ an~ edge~ labelled~ #2;
  ~ available~ edges~ are~ #3.}
\msg_new:nnn { tilings }{ no edge }
{ Either~ tile~ #1~ doesn't~ exist
  ~ or~ it~ doesn't~ have~ an~ edge~ labelled~ #2.}
\cs_new_nopar:Npn \__tilings_normalise_path:Nn #1#2
{
  \group_begin:
  \spath_initialpoint:Nn \l__tilings_tmpa_tl {#2}
  \fp_set:Nn \l__tilings_tmpa_fp {\tl_head:N \l__tilings_tmpa_tl}
  \tl_set:Nx \l__tilings_tmpa_tl {\tl_tail:N \l__tilings_tmpa_tl}
  \fp_set:Nn \l__tilings_tmpb_fp {\tl_head:N \l__tilings_tmpa_tl}
  \spath_finalpoint:Nn \l__tilings_tmpa_tl {#2}
  \fp_set:Nn \l__tilings_tmpa_fp
  {\tl_head:N \l__tilings_tmpa_tl - \l__tilings_tmpa_fp}
  \tl_set:Nx \l__tilings_tmpa_tl {\tl_tail:N \l__tilings_tmpa_tl}
  \fp_set:Nn \l__tilings_tmpb_fp
  {\tl_head:N \l__tilings_tmpa_tl - \l__tilings_tmpb_fp}
  \fp_set:Nn \l__tilings_tmpc_fp
  {\l__tilings_tmpa_fp^2 + \l__tilings_tmpb_fp^2}
  \fp_set:Nn \l__tilings_tmpa_fp {\l__tilings_tmpa_fp/\l__tilings_tmpc_fp}
  \fp_set:Nn \l__tilings_tmpb_fp {\l__tilings_tmpb_fp/\l__tilings_tmpc_fp}
  \fp_set:Nn \l__tilings_tmpc_fp {-\l__tilings_tmpb_fp}
  \tl_set:Nx \l__tilings_tmpb_tl
  {
    {\fp_use:N \l__tilings_tmpa_fp}
    {\fp_use:N \l__tilings_tmpc_fp} % swapped
    {\fp_use:N \l__tilings_tmpb_fp} % swapped
    {\fp_use:N \l__tilings_tmpa_fp}
  }
  \spath_initialpoint:Nn \l__tilings_tmpa_tl {#2}
  \fp_set:Nn \l__tilings_tmpa_fp
  {
    (-1) * \l__tilings_tmpa_fp * \tl_head:N \l__tilings_tmpa_tl
    + (-1) * \l__tilings_tmpb_fp * \tl_tail:N \l__tilings_tmpa_tl
  }
  \fp_set:Nn \l__tilings_tmpb_fp
  {
    (-1) * \l__tilings_tmpa_fp * \tl_tail:N \l__tilings_tmpa_tl
    +  \l__tilings_tmpb_fp * \tl_head:N \l__tilings_tmpa_tl
  }
  \tl_put_right:Nx \l__tilings_tmpb_tl {
    {\fp_to_dim:N \l__tilings_tmpa_fp}
    {\fp_to_dim:N \l__tilings_tmpb_fp}
  }
  \spath_transform:NnV \l__tilings_tmpa_tl {#2} \l__tilings_tmpb_tl
  \tl_gset_eq:NN \g__tilings_output_tl \l__tilings_tmpa_tl
  \group_end:
  \tl_set_eq:NN #1 \g__tilings_output_tl
  \tl_gclear:N \g__tilings_output_tl
}
\cs_generate_variant:Nn \__tilings_normalise_path:Nn {NV, cn, cV}
\cs_new_protected_nopar:Npn \__tilings_normalise_path:N #1
{
  \__tilings_normalise_path:NV #1#1
}
\cs_generate_variant:Nn \__tilings_normalise_path:N {c}
\cs_new_protected_nopar:Npn \__tilings_set_tiling_path:n #1
{
  \group_begin:
  \pgfsyssoftpath@getcurrentpath\l__tilings_tmpa_tl
  \__tilings_normalise_path:N \l__tilings_tmpa_tl
  \tl_gset_eq:cN {g__tilings_side_#1_tl} \l__tilings_tmpa_tl
  \group_end:
}

\NewDocumentCommand \SetTilingPath { m }
{
  \__tilings_set_tiling_path:n {#1}
}
\cs_new_nopar:Npn \tikz_scan_point:n #1
{
  \tikz@scan@one@point\pgfutil@firstofone#1\relax
}
\cs_generate_variant:Nn \tikz_scan_point:n {V}
\prg_new_conditional:Npnn \tikz_node_if_defined:n #1 {p,T,F,TF}
{
  \tl_if_exist:cTF {pgf@sh@ns@\use:c{tikz@pp@name}{#1}}
  {
    \prg_return_true:
  }{
    \tl_if_exist:cTF
    {pgf@sh@ns@not yet positionedPGFINTERNAL\use:c{tikz@pp@name}{#1}}
    {
      \pgf_return_true:
    }
    {
      \prg_return_false:
    }
  }
}
\cs_new_nopar:Npn \__tilings_keys_get:Nn #1#2
{
  \pgfkeysgetvalue{/tikz/tiling/#2}{#1}
}
\cs_new_nopar:Npn \__tilings_keys_get:n #1
{
  \pgfkeysvalueof{/tikz/tiling/#1}
}
\cs_new_nopar:Npn \__tilings_tikz_keys_get:Nn #1#2
{
  \pgfkeysgetvalue{/tikz/#2}{#1}
}
\cs_new_nopar:Npn \__tilings_tikz_keys_get:n #1
{
  \pgfkeysvalueof{/tikz/#1}
}
\cs_new_nopar:Npn \__tilings_pgf_keys_get:Nn #1#2
{
  \pgfkeysgetvalue{#2}{#1}
}
\cs_new_nopar:Npn \__tilings_pgf_keys_get:n #1
{
  \pgfkeysvalueof{#1}
}
\cs_new_nopar:Npn \__tilings_make_tile:nnn #1#2#3
{
  \group_begin:
  \tl_set:Nn \l__tilings_tmpa_tl {#3}
  \tl_set:Nx \l__tilings_tmpb_tl {\tl_head:N \l__tilings_tmpa_tl}
  \tl_set:Nn \l__tilings_tmpa_tl {\pgfsyssoftpath@movetotoken}
  \tl_put_right:Nx \l__tilings_tmpa_tl
  {
    {
      \fp_to_dim:n
      {(\tl_item:Nn \l__tilings_tmpb_tl {1}) * \c__tilings_cm_fp}
    }
    {
      \fp_to_dim:n
      {(\tl_item:Nn \l__tilings_tmpb_tl {2}) * \c__tilings_cm_fp}
    }
  }
  \tl_set_eq:NN \l__tilings_tmp_tile_path_tl \l__tilings_tmpa_tl
  \tl_set:Nn \l__tilings_tmpa_tl {#3}
  \tl_put_right:Nx \l__tilings_tmpa_tl {{\tl_head:N \l__tilings_tmpa_tl}}
  \tl_map_inline:nn {#2} {
    \tl_set:Nx \l__tilings_tmpc_tl {\tl_head:n {##1}}
    \tl_if_exist:cF {g__tilings_side_ \tl_use:N \l__tilings_tmpc_tl _tl}
    {
      \msg_error:nnx { tilings }{ no side } { \tl_use:N \l__tilings_tmpc_tl }
      \tl_gset_eq:cc
      {g__tilings_side_ \tl_use:N \l__tilings_tmpc_tl _tl}
      {g__tilings_side_a_tl}
    }
    \tl_set_eq:Nc \l__tilings_tmpd_tl
    {g__tilings_side_ \tl_use:N \l__tilings_tmpc_tl _tl}
    \tl_set:Nx \l__tilings_tmpb_tl {\tl_head:N \l__tilings_tmpa_tl}
    \tl_set:Nx \l__tilings_tmpa_tl {\tl_tail:N \l__tilings_tmpa_tl}
    \fp_set:Nn \l__tilings_tmpa_fp
    { \tl_item:Nn \l__tilings_tmpb_tl {1} }
    \fp_set:Nn \l__tilings_tmpb_fp
    { \tl_item:Nn \l__tilings_tmpb_tl {2} }
    \tl_set:Nx \l__tilings_tmpb_tl {\tl_head:N \l__tilings_tmpa_tl}
    \fp_set:Nn \l__tilings_tmpa_fp
    {\tl_item:Nn \l__tilings_tmpb_tl {1} - \l__tilings_tmpa_fp}
    \fp_set:Nn \l__tilings_tmpb_fp
    {\tl_item:Nn \l__tilings_tmpb_tl {2} - \l__tilings_tmpb_fp}
    \fp_set:Nn \l__tilings_tmpc_fp {-\l__tilings_tmpb_fp}
    \tl_set:Nx \l__tilings_tmpb_tl
    {
      {\fp_to_dim:n { \l__tilings_tmpa_fp * \c__tilings_cm_fp }}
      {\fp_to_dim:n { \l__tilings_tmpb_fp * \c__tilings_cm_fp }}% not swapped
      {\fp_to_dim:n { \l__tilings_tmpc_fp * \c__tilings_cm_fp }}% not swapped
      {\fp_to_dim:n { \l__tilings_tmpa_fp * \c__tilings_cm_fp }}
      {0}
      {0}
    }
    \spath_transform:NV \l__tilings_tmpd_tl \l__tilings_tmpb_tl
    \spath_weld:NV \l__tilings_tmp_tile_path_tl \l__tilings_tmpd_tl
  }
  \spath_close:N \l__tilings_tmp_tile_path_tl
  \tl_gset_eq:NN \g__tilings_output_tl \l__tilings_tmp_tile_path_tl
  \group_end:
  \tl_gclear_new:c {g__tilings_tile_#1_tl}
  \tl_gset_eq:cN {g__tilings_tile_#1_tl} \g__tilings_output_tl
  \tl_gclear:N \g__tilings_output_tl
}
\cs_new_nopar:Npn \__tilings_make_tile:nn #1#2
{
  \__tilings_make_tile:nnn {#1} #2
}
\cs_generate_variant:Nn \__tilings_make_tile:nn {nV}
\prop_new:N \g__tilings_tiles_prop
\cs_new_nopar:Npn \__tilings_add_coordinate:Nnn #1#2#3 {
  \group_begin:
  \fp_set:Nn \l__tilings_tmpa_fp {#2}
  \fp_set:Nn \l__tilings_tmpb_fp {#3}
  \bool_if:NT \l__tilings_relative_bool
  {
    \fp_add:Nn \l__tilings_tmpa_fp {\l__tilings_saved_x_fp}
    \fp_add:Nn \l__tilings_tmpb_fp {\l__tilings_saved_y_fp}
  }
  \fp_gset_eq:NN \g__tilings_output_a_fp \l__tilings_tmpa_fp
  \fp_gset_eq:NN \g__tilings_output_b_fp \l__tilings_tmpb_fp
  \group_end:
  \tl_put_right:Nx #1
  {
    {{\fp_use:N \g__tilings_output_a_fp}{\fp_use:N \g__tilings_output_b_fp}}
  }
  \bool_if:NT \l__tilings_update_saved_bool
  {
    \fp_set_eq:NN \l__tilings_saved_x_fp \g__tilings_output_a_fp
    \fp_set_eq:NN \l__tilings_saved_y_fp \g__tilings_output_b_fp
  }
  \fp_gzero:N \g__tilings_output_a_fp
  \fp_gzero:N \g__tilings_output_b_fp
}
\cs_new_nopar:Npn \__tilings_add_xy_coordinate:w #1#2,#3 \q_stop
{
  \__tilings_add_coordinate:Nnn #1 {#2}{#3}
}
\cs_new_nopar:Npn \__tilings_add_rth_coordinate:w #1#2:#3 \q_stop
{
  \__tilings_add_coordinate:Nnn #1 {(#3) * cosd(#2)}{(#3) * sind(#2)}
}
\cs_new_nopar:Npn \__tilings_transform_side_to_axis:Nnn #1#2#3
{
  \group_begin:
  \prop_get:NnNTF \g__tilings_tiles_prop {#2} \l__tilings_tmpa_tl
  {
  \int_zero:N \l__tilings_tmpb_int
  \int_incr:N \l__tilings_tmpb_int
  \tl_set:Nx \l__tilings_tmpc_tl {\tl_head:N \l__tilings_tmpa_tl}
    \bool_set_false:N \l__tilings_edge_bool
    \tl_map_inline:Nn \l__tilings_tmpc_tl {
      \str_if_eq:nnT {##1} {#3} {
        \bool_set_true:N \l__tilings_edge_bool
        \tl_map_break:
      }
      \int_incr:N \l__tilings_tmpb_int
    }
    \bool_if:NTF \l__tilings_edge_bool
    {
      \tl_set:Nx \l__tilings_tmpc_tl {\tl_tail:N \l__tilings_tmpa_tl}
      \tl_set:Nx \l__tilings_tmpc_tl {\tl_item:Nn \l__tilings_tmpc_tl {1}}
      \tl_put_right:Nx \l__tilings_tmpc_tl
      {{\tl_item:Nn \l__tilings_tmpc_tl {1}}}
      \tl_set:Nx \l__tilings_tmpa_tl
      {\tl_item:Nn \l__tilings_tmpc_tl {\int_use:N \l__tilings_tmpb_int}}
      \tl_set:Nx \l__tilings_tmpb_tl
      {\tl_item:Nn \l__tilings_tmpc_tl {\int_use:N \l__tilings_tmpb_int + 1}}
      \bool_if:NT #1
      {
        \tl_set:NV \l__tilings_tmpc_tl \l__tilings_tmpa_tl
        \tl_set:NV \l__tilings_tmpa_tl \l__tilings_tmpb_tl
        \tl_set:NV \l__tilings_tmpb_tl \l__tilings_tmpc_tl
      }
      \fp_set:Nn \l__tilings_xa_fp {\tl_item:Nn \l__tilings_tmpb_tl {1}}
      \fp_set:Nn \l__tilings_ya_fp {\tl_item:Nn \l__tilings_tmpb_tl {2}}
      \fp_set:Nn \l__tilings_xb_fp
      {\tl_item:Nn \l__tilings_tmpa_tl {1} - \l__tilings_xa_fp}
      \fp_set:Nn \l__tilings_yb_fp
      {\tl_item:Nn \l__tilings_tmpa_tl {2} - \l__tilings_ya_fp}
      \fp_set:Nn \l__tilings_tmpa_fp
      {(\l__tilings_xb_fp)^2 + (\l__tilings_yb_fp)^2}
      \fp_set:Nn \l__tilings_xb_fp { \l__tilings_xb_fp / \l__tilings_tmpa_fp}
      \fp_set:Nn \l__tilings_yb_fp { \l__tilings_yb_fp / \l__tilings_tmpa_fp}
      \tl_gset:Nx \g__tilings_output_tl
      {
        \exp_not:N \pgftransformtriangle
        {
          \exp_not:N \pgfpoint{0pt}{0pt}
        }
        {
          \exp_not:N \pgfpoint
          {\fp_to_dim:N \l__tilings_xb_fp}{\fp_to_dim:n {-\l__tilings_yb_fp}}
        }
        {
          \exp_not:N \pgfpoint
          {\fp_to_dim:N \l__tilings_yb_fp}{\fp_to_dim:N \l__tilings_xb_fp}
        }
        \exp_not:N \pgftransformshift
        {
          \exp_not:N \pgfpoint
          {
            \fp_to_dim:n {-\l__tilings_xa_fp * \c__tilings_cm_fp}
          }
          {
            \fp_to_dim:n {-\l__tilings_ya_fp * \c__tilings_cm_fp}
          }
        }
      }
    }
    {
      \msg_error:nnxxx {tilings} {tile no edge} {#2} {#3}
      {\tl_use:N  \l__tilings_tmpc_tl }
      \tl_gclear:N \g__tilings_output_tl
    }
  }
  {
    \msg_error:nnn {tilings} {no tile} {#2}
    \tl_gclear:N \g__tilings_output_tl
  }
  \group_end:
  \tl_use:N \g__tilings_output_tl
  \tl_gclear:N \g__tilings_output_tl
}
\cs_generate_variant:Nn
\__tilings_transform_side_to_axis:Nnn {Nnx,NnV,NVV}
\cs_new_nopar:Npn \__tilings_translate_vertex_to_origin:Nnn #1#2#3
{
  \group_begin:
  \prop_get:NnNTF \g__tilings_tiles_prop {#2} \l__tilings_tmpa_tl
  {
  \int_zero:N \l__tilings_tmpb_int
  \int_incr:N \l__tilings_tmpb_int
  \tl_set:Nx \l__tilings_tmpc_tl {\tl_head:N \l__tilings_tmpa_tl}
    \bool_set_false:N \l__tilings_edge_bool
    \tl_map_inline:Nn \l__tilings_tmpc_tl {
      \str_if_eq:nnT {##1} {#3} {
        \bool_set_true:N \l__tilings_edge_bool
        \tl_map_break:
      }
      \int_incr:N \l__tilings_tmpb_int
    }
    \bool_if:NTF \l__tilings_edge_bool
    {
      \tl_set:Nx \l__tilings_tmpc_tl {\tl_tail:N \l__tilings_tmpa_tl}
      \tl_set:Nx \l__tilings_tmpc_tl {\tl_item:Nn \l__tilings_tmpc_tl {1}}
      \tl_put_right:Nx \l__tilings_tmpc_tl
      {{\tl_item:Nn \l__tilings_tmpc_tl {1}}}
      \tl_set:Nx \l__tilings_tmpa_tl
      {\tl_item:Nn \l__tilings_tmpc_tl {\int_use:N \l__tilings_tmpb_int}}
      \tl_set:Nx \l__tilings_tmpb_tl
      {\tl_item:Nn \l__tilings_tmpc_tl {\int_use:N \l__tilings_tmpb_int + 1}}
      \bool_if:NT #1
      {
        \tl_set:NV \l__tilings_tmpc_tl \l__tilings_tmpa_tl
        \tl_set:NV \l__tilings_tmpa_tl \l__tilings_tmpb_tl
        \tl_set:NV \l__tilings_tmpb_tl \l__tilings_tmpc_tl
      }
      \fp_set:Nn \l__tilings_xa_fp {\tl_item:Nn \l__tilings_tmpb_tl {1}}
      \fp_set:Nn \l__tilings_ya_fp {\tl_item:Nn \l__tilings_tmpb_tl {2}}
      \tl_gset:Nx \g__tilings_output_tl
      {
        \exp_not:N \pgftransformshift
        {
          \exp_not:N \pgfpoint
          {
            \fp_to_dim:n {-\l__tilings_xa_fp * \c__tilings_cm_fp}
          }
          {
            \fp_to_dim:n {-\l__tilings_ya_fp * \c__tilings_cm_fp}
          }
        }
      }
    }
    {
      \msg_error:nnxxx {tilings} {tile no edge} {#2} {#3}
      {\tl_use:N  \l__tilings_tmpc_tl }
      \tl_gclear:N \g__tilings_output_tl
    }
  }
  {
    \msg_error:nnn {tilings} {no tile} {#2}
    \tl_gclear:N \g__tilings_output_tl
  }
  \group_end:
  \tl_use:N \g__tilings_output_tl
  \tl_gclear:N \g__tilings_output_tl
}
\cs_generate_variant:Nn
\__tilings_translate_vertex_to_origin:Nnn {Nnx,NnV,NVV}
\DeclareDocumentCommand \TransformAlongSide {s m m}
{
  \IfBooleanTF {#1}
  {
    \bool_set_true:N \l__tilings_cw_bool
  }
  {
    \bool_set_false:N \l__tilings_cw_bool
  }
  \__tilings_transform_side_to_axis:Nnx \l__tilings_cw_bool {#2}{#3}
}
\cs_new_nopar:Npn \__tilings_coordinates_at_vertices:n #1
{
  \group_begin:
  \prop_get:NnN \g__tilings_tiles_prop {#1} \l__tilings_tmpa_tl
  \tl_set:Nx \l__tilings_tmpb_tl {\tl_head:N \l__tilings_tmpa_tl}
  \tl_set:Nx \l__tilings_tmpc_tl {\tl_tail:N \l__tilings_tmpa_tl}
  \tl_set:Nx \l__tilings_tmpc_tl
  {\tl_item:Nn \l__tilings_tmpc_tl {1}}
  \tl_put_right:Nx \l__tilings_tmpc_tl
  {{\tl_item:Nn \l__tilings_tmpc_tl {1}}}
  \tl_set:Nx \l__tilings_tmpa_tl {\tl_head:N \l__tilings_tmpc_tl}
  \tl_set:Nx \l__tilings_tmpc_tl {\tl_tail:N \l__tilings_tmpc_tl}
  \tl_map_inline:Nn \l__tilings_tmpb_tl {
    \tl_set:Nx \l__tilings_tmpd_tl {
      \exp_not:N \coordinate
      (-edge~ ##1~ start)~
      at (
      \tl_item:Nn \l__tilings_tmpa_tl {1},
      \tl_item:Nn \l__tilings_tmpa_tl {2}
      );
    }
    \tl_use:N \l__tilings_tmpd_tl
    \tl_set:Nx \l__tilings_tmpa_tl {\tl_head:N \l__tilings_tmpc_tl}
    \tl_set:Nx \l__tilings_tmpc_tl {\tl_tail:N \l__tilings_tmpc_tl}
    \tl_set:Nx \l__tilings_tmpd_tl {
      \exp_not:N \coordinate
      (-edge~ ##1~ end)~
      at (
      \tl_item:Nn \l__tilings_tmpa_tl {1},
      \tl_item:Nn \l__tilings_tmpa_tl {2}
      );
    }
    \tl_use:N \l__tilings_tmpd_tl
  }
  \group_end:
}
\DeclareDocumentCommand \CoordinatesAtVertices {m}
{
  \__tilings_coordinates_at_vertices:n {#1}
}
\tikzset{
  transform~ to~ tile/.code~ args={#1~ along~ #2}{%
    \group_begin:
    \tl_if_in:nnTF {#1} {back}
    {
      \tikzset{
        tiling/alignment~ set~ location=#1,
        tiling/alignment~ direction={backwards}
      }
    }
    {
      \tikzset{
        tiling/alignment~ location=#1,
        tiling/alignment~ direction={forewards}
      }
    }
    \tl_if_in:nnTF {#2} {using}
    {
      \tikzset{
        tiling/alignment~ set~ edges=#2,
      }
    }
    {
      \tikzset{
        tiling/alignment~ edge=#2,
      }
    }
    \tikz_scan_point:n {
      (\__tilings_keys_get:n {alignment~ location}
      -edge~ \__tilings_keys_get:n {alignment~ edge}~ start)
    }
    \dim_set_eq:Nc \l__tilings_xa_dim {pgf@x}
    \dim_set_eq:Nc \l__tilings_ya_dim {pgf@y}
    \tikz_scan_point:n {
      (\__tilings_keys_get:n {alignment~ location}
      -edge~ \__tilings_keys_get:n {alignment~ edge}~ end)
    }
    \dim_set_eq:Nc \l__tilings_xb_dim {pgf@x}
    \dim_set_eq:Nc \l__tilings_yb_dim {pgf@y}
    \__tilings_keys_get:Nn \l__tilings_tmpb_tl {alignment~ direction}
    \tl_if_eq:NnTF \l__tilings_tmpb_tl {forewards}
    {
      \dim_gset_eq:NN \g__tilings_xa_dim \l__tilings_xa_dim
      \dim_gset_eq:NN \g__tilings_ya_dim \l__tilings_ya_dim
      \dim_gset_eq:NN \g__tilings_xb_dim \l__tilings_xb_dim
      \dim_gset_eq:NN \g__tilings_yb_dim \l__tilings_yb_dim
    }
    {
      \dim_gset_eq:NN \g__tilings_xa_dim \l__tilings_xb_dim
      \dim_gset_eq:NN \g__tilings_ya_dim \l__tilings_yb_dim
      \dim_gset_eq:NN \g__tilings_xb_dim \l__tilings_xa_dim
      \dim_gset_eq:NN \g__tilings_yb_dim \l__tilings_ya_dim
    }
    \dim_gsub:Nn \g__tilings_xb_dim {\g__tilings_xa_dim}
    \dim_gsub:Nn \g__tilings_yb_dim {\g__tilings_ya_dim}
    \dim_gset:Nn \g__tilings_xb_dim
    {\g__tilings_xb_dim * \dim_ratio:nn {1pt}{1cm}}
    \dim_gset:Nn \g__tilings_yb_dim
    {\g__tilings_yb_dim * \dim_ratio:nn {1pt}{1cm}}
    \group_end:
    \pgftransformshift{\pgfpoint{\g__tilings_xa_dim}{\g__tilings_ya_dim}}
    \pgftransformtriangle
    {\pgfpoint{0pt}{0pt}}
    {\pgfpoint{\g__tilings_xb_dim}{\g__tilings_yb_dim}}
    {\pgfpoint{-\g__tilings_yb_dim}{\g__tilings_xb_dim}}
  },
  align~ with/.code~ args={#1~ along~ #2}{%
    \tl_if_in:nnTF {#1} {back}
    {
      \tikzset{
        tiling/alignment~ set~ location=#1,
        tiling/alignment~ direction={backwards}
      }
    }
    {
      \tikzset{
        tiling/alignment~ location=#1,
        tiling/alignment~ direction={forewards}
      }
    }
    \tl_if_in:nnTF {#2} {using}
    {
      \tikzset{
        tiling/alignment~ set~ edges=#2,
      }
    }
    {
      \tikzset{
        tiling/alignment~ edge=#2,
      }
    }
    \tikz_node_if_defined:nTF
    {
      \__tilings_keys_get:n {alignment~ location}
      -edge~ \__tilings_keys_get:n {alignment~ edge}~ start
    }
    {
      \tikzset{
        tiling/alignment~ start/.expanded={
          (\__tilings_keys_get:n {alignment~ location}
          -edge~ \__tilings_keys_get:n {alignment~ edge}~ start)
        },
        tiling/alignment~ end/.expanded={
          (\__tilings_keys_get:n {alignment~ location}
          -edge~ \__tilings_keys_get:n {alignment~ edge}~ end)
        },
      }
    }
    {
      \__tilings_keys_get:Nn \l__tilings_tmpa_tl {alignment~ location}
      \tl_set:Nx \l__tilings_tmpa_tl {\tl_use:N \l__tilings_tmpa_tl}
      \prop_get:NVNTF \g__tilings_tilenames_prop
      \l__tilings_tmpa_tl \l__tilings_tmpb_tl
      {
        \prop_get:NVN \g__tilings_tiles_prop
        \l__tilings_tmpb_tl \l__tilings_tmpc_tl
        \msg_error:nnxxx { tilings }{ tile no edge }
        {
          \tl_use:N \l__tilings_tmpa_tl \c_space_tl
          (type~ \tl_use:N \l__tilings_tmpb_tl)
        }
        {\__tilings_keys_get:n {alignment~ edge} }
        { \tl_item:Nn \l__tilings_tmpc_tl {1} }
      }
      {
        \msg_error:nnx { tilings }{ no tile }
        {\__tilings_keys_get:n {alignment~ location} }
      }
    }
  },
  tiling/.is~ family,
  tiling/alignment~ set~ location/.code~ args={#1~ back}{
    \tikzset{
      tiling/alignment~ location=#1,
    }
  },
  tiling/alignment~ set~ edges/.code~ args={#1~ using~ #2}{
    \tikzset{
      tiling/alignment~ edge=#1,
      tiling/alignment~ new~ edge=#2
    }
  },
  align~ between/.code~ args={#1~ and~ #2~ using~ #3}{
    \tikzset{
      tiling/alignment~ start={#1},
      tiling/alignment~ end={#2},
    }
    \str_set:Nn \l__tilings_tmpa_str {#3}
    \str_set:Nx \l__tilings_tmpb_str {\str_tail:N \l__tilings_tmpa_str}
    \tikzset{
      tiling/alignment~ new~ edge/.expanded={\str_use:N \l__tilings_tmpb_str}
    }
    \str_set:Nx \l__tilings_tmpa_str {\str_head:N \l__tilings_tmpa_str}
    \str_set:Nx \l__tilings_tmpb_str {\str_lowercase:f { \l__tilings_tmpa_str}}
    \str_if_eq:NNT \l__tilings_tmpa_str \l__tilings_tmpb_str
    {
      \str_set:Nx \l__tilings_tmpb_str
      {\str_uppercase:f { \l__tilings_tmpa_str}}
    }
    \tikzset{
      tiling/alignment~ edge/.expanded={\str_use:N \l__tilings_tmpb_str},
    }
  },
  tiling/alignment~ location/.initial={},
  tiling/alignment~ edge/.initial=a,
  tiling/alignment~ new~ edge/.initial={},
  tiling/alignment~ direction/.initial={forewards},
  tiling/alignment~ start/.initial={},
  tiling/alignment~ end/.initial={},
  tiling/anchor/.initial={},
  every~ tile~ clip/.style={clip}
}
\DeclareDocumentCommand \DefineTile { s m m m }
{
  \tl_clear:N \l__tilings_tmpa_tl
  \int_zero:N \l__tilings_tmpa_int
  \fp_zero:N \l__tilings_saved_x_fp
  \fp_zero:N \l__tilings_saved_y_fp
  \tl_map_inline:nn {#4} {
    \str_set:Nn \l__tilings_tmpa_str {##1}
    \str_if_eq:VnTF \l__tilings_tmpa_str {+}
    {
      \int_incr:N \l__tilings_tmpa_int
    }
    {
      \int_case:nn {\l__tilings_tmpa_int}
      {
        {0} {
          \bool_set_false:N \l__tilings_relative_bool
          \bool_set_true:N \l__tilings_update_saved_bool
        }
        {1} {
          \bool_set_true:N \l__tilings_relative_bool
          \bool_set_false:N \l__tilings_update_saved_bool
        }
        {2} {
          \bool_set_true:N \l__tilings_relative_bool
          \bool_set_true:N \l__tilings_update_saved_bool
        }

      }
      \str_if_in:NnTF \l__tilings_tmpa_str {:}
      {
        \seq_set_split:NVV \l__tilings_tmpa_seq \c__tilings_colon_str \l__tilings_tmpa_str
        \__tilings_add_coordinate:Nnn \l__tilings_tmpa_tl
        {
          (\seq_item:Nn \l__tilings_tmpa_seq {2}) * cosd (\seq_item:Nn \l__tilings_tmpa_seq {1})
        }
        {
          (\seq_item:Nn \l__tilings_tmpa_seq {2}) * sind (\seq_item:Nn \l__tilings_tmpa_seq {1})
        }
      }
      {
        \seq_set_split:NVV \l__tilings_tmpa_seq \c__tilings_comma_str \l__tilings_tmpa_str
        \__tilings_add_coordinate:Nnn \l__tilings_tmpa_tl
        {
          (\seq_item:Nn \l__tilings_tmpa_seq {1})
        }
        {
          (\seq_item:Nn \l__tilings_tmpa_seq {2})
        }
      }
      \int_zero:N \l__tilings_tmpa_int
    }
  }
  \prop_clear:N \l__tilings_tmpa_prop
  \tl_map_inline:nn {#3} {
    \prop_if_in:NnTF \l__tilings_tmpa_prop {##1}
    {
      \prop_put:Nnn \l__tilings_tmpa_prop {##1} {1}
    }
    {
      \prop_put:Nnn \l__tilings_tmpa_prop {##1} {0}
    }
  }
  \tl_clear:N \l__tilings_tmpb_tl
  \tl_map_inline:nn {#3}
  {
    \tl_clear:N \l__tilings_tmpc_tl
    \tl_put_right:Nn \l__tilings_tmpc_tl {##1}
    \int_compare:nF {\prop_item:Nn \l__tilings_tmpa_prop {##1} == 0} {
      \tl_put_right:Nx \l__tilings_tmpc_tl
      {\prop_item:Nn \l__tilings_tmpa_prop {##1}}
      \prop_put:Nnx \l__tilings_tmpa_prop {##1}
      {\int_eval:n {\prop_item:Nn \l__tilings_tmpa_prop {##1} + 1}}
    }
    \tl_put_right:Nx \l__tilings_tmpb_tl {{ \l__tilings_tmpc_tl }}
  }
  \prop_gput:Nnx \g__tilings_tiles_prop {#2}
  {{\tl_use:N \l__tilings_tmpb_tl} {\tl_use:N \l__tilings_tmpa_tl}}
  \tikzset{
    #2/.pic={
      \begin{scope}[
        every~ tile~ scope/.try,
        every~ #2~ scope/.try,
        this~ tile~ scope/.try
      ]
      \tikz@fig@mustbenamed
      \prop_gput:NVn \g__tilings_tilenames_prop \tikz@fig@name {#2}
      \__tilings_keys_get:Nn \l__tilings_tmpa_tl {alignment~ start}
      \tl_if_empty:NTF \l__tilings_tmpa_tl
      {
        \prop_get:NnN \g__tilings_tiles_prop {#2} \l__tilings_tmpa_tl
        \tl_set:Nx \l__tilings_tmpc_tl {\tl_head:N \l__tilings_tmpa_tl}
        \__tilings_keys_get:Nn \l__tilings_tmpa_tl {anchor}
        \tl_if_empty:NTF \l__tilings_tmpa_tl
        {
          \bool_if:NT \l__tilings_cw_bool
          {
            \pgftransformxscale {-1}
          }
        }
        {
          \regex_extract_once:NVNTF
          \c__tilings_anchor_regex \l__tilings_tmpa_tl \l__tilings_tmpb_tl
          {
            \regex_replace_once:NnN \c__tilings_anchor_regex {} \l__tilings_tmpa_tl
            \tl_if_eq:NnTF \l__tilings_tmpb_tl {~end}
            {
              \bool_set_true:N \l__tilings_cw_bool
            }
            {
              \bool_set_false:N \l__tilings_cw_bool
            }
          }
          {
            \bool_set_false:N \l__tilings_cw_bool
          }
          \tl_set:Nx \l__tilings_tmpb_tl {{\tl_use:N \l__tilings_tmpa_tl}}
          \tl_if_in:NVT \l__tilings_tmpc_tl \l__tilings_tmpb_tl
          {
            \__tilings_translate_vertex_to_origin:NnV
            \l__tilings_cw_bool {#2} \l__tilings_tmpa_tl
          }
        }
      }
      {
        \group_begin:
        \tikzset{
          name~ prefix~ ..
        }
        \tikz_scan_point:n {
          \__tilings_keys_get:n {alignment~ start}
        }
        \dim_set_eq:Nc \l__tilings_xa_dim {pgf@x}
        \dim_set_eq:Nc \l__tilings_ya_dim {pgf@y}
        \tikz_scan_point:n {
          \__tilings_keys_get:n {alignment~ end}
        }
        \dim_set_eq:Nc \l__tilings_xb_dim {pgf@x}
        \dim_set_eq:Nc \l__tilings_yb_dim {pgf@y}
        \__tilings_keys_get:Nn \l__tilings_tmpb_tl {alignment~ direction}
        \tl_if_eq:NnTF \l__tilings_tmpb_tl {forewards}
        {
          \dim_gset_eq:NN \g__tilings_xa_dim \l__tilings_xa_dim
          \dim_gset_eq:NN \g__tilings_ya_dim \l__tilings_ya_dim
          \dim_gset_eq:NN \g__tilings_xb_dim \l__tilings_xb_dim
          \dim_gset_eq:NN \g__tilings_yb_dim \l__tilings_yb_dim
        }
        {
          \dim_gset_eq:NN \g__tilings_xa_dim \l__tilings_xb_dim
          \dim_gset_eq:NN \g__tilings_ya_dim \l__tilings_yb_dim
          \dim_gset_eq:NN \g__tilings_xb_dim \l__tilings_xa_dim
          \dim_gset_eq:NN \g__tilings_yb_dim \l__tilings_ya_dim
        }
        \dim_gsub:Nn \g__tilings_xb_dim {\g__tilings_xa_dim}
        \dim_gsub:Nn \g__tilings_yb_dim {\g__tilings_ya_dim}
        \dim_gset:Nn \g__tilings_xb_dim {\g__tilings_xb_dim * \dim_ratio:nn {1pt}{1cm}}
        \dim_gset:Nn \g__tilings_yb_dim {\g__tilings_yb_dim * \dim_ratio:nn {1pt}{1cm}}
        \group_end:
        \pgftransformshift{\pgfpoint{\g__tilings_xa_dim}{\g__tilings_ya_dim}}
        \pgftransformtriangle
        {\pgfpoint{0pt}{0pt}}
        {\pgfpoint{\g__tilings_xb_dim}{\g__tilings_yb_dim}}
        {\pgfpoint{-\g__tilings_yb_dim}{\g__tilings_xb_dim}}
        \str_set:Nx \l__tilings_tmpa_str
        {\__tilings_keys_get:n {alignment~ edge}}
        \str_set:Nx \l__tilings_tmpa_str {\str_head:N \l__tilings_tmpa_str}
        \str_put_right:Nx \l__tilings_tmpa_str
        {\__tilings_keys_get:n {alignment~ new~ edge}}
        \str_set:Nx \l__tilings_tmpb_str {\str_lowercase:f { \l__tilings_tmpa_str}}
        \str_if_eq:NNT \l__tilings_tmpa_str \l__tilings_tmpb_str
        {
          \str_set:Nx \l__tilings_tmpb_str
          {\str_uppercase:f { \l__tilings_tmpa_str}}
        }

        \IfBooleanT {#1}
        {
          \bool_set:Nn \l__tilings_cw_bool {!\l__tilings_cw_bool}
        }
        \bool_if:NT \l__tilings_cw_bool
        {
          \pgftransformyscale {-1}
        }
        \__tilings_transform_side_to_axis:NnV \l__tilings_cw_bool {#2} \l__tilings_tmpb_str
      }
      \__tilings_coordinates_at_vertices:n {#2}
      \coordinate[alias=-center] (-centre) at (0,0);
      \UseTile[
        every~ tile~ clip/.try,
        every~ #2~ clip/.try,
        this~ tile~ clip/.try
      ]{#2}
      \tikzset{
        every~ tile~ before~ path/.try,
        every~ #2~ before~ path/.try,
        this~ tile~ before~ path/.try
      }
      \UseTile[
        every~ tile/.try,
        every~ #2/.try,
        this~ tile/.try,
        pic~ actions
      ]{#2}
      \tikzset{
        every~ tile~ after~ path/.try,
        every~ #2~ after~ path/.try,
        this~ tile~ after~ path/.try
      }
      \end{scope}
    },
    #2/.style={
      every~ tile~ pic/.try,
      every~ #2~ pic/.try,
      pic~ type=#2,
    }
  }
}
\cs_new_protected_nopar:Npn \__tilings_bake_tile:n #1
{
  \prop_get:NnN \g__tilings_tiles_prop {#1} \l__tilings_tmpa_tl
  \__tilings_make_tile:nV {#1} \l__tilings_tmpa_tl
}

\NewDocumentCommand \BakeTile {m}
{
  \__tilings_bake_tile:n {#1}
}
\cs_new_protected_nopar:Npn \__tilings_use_tile:nn #1#2
{
  \tl_if_exist:cTF {g__tilings_tile_#2_tl}
  {
    \tl_set_eq:Nc \l__tilings_tmp_tile_path_tl {g__tilings_tile_#2_tl}
    \pgfgettransform \l__tilings_tmpa_tl
    \spath_transform:NV \l__tilings_tmp_tile_path_tl \l__tilings_tmpa_tl
    \spath_tikz_path:nV {#1} \l__tilings_tmp_tile_path_tl
  }
  {
    \msg_error:nnn { tilings }{ not baked }{#2}
  }
}

\NewDocumentCommand \UseTile {O{} m}
{
  \__tilings_use_tile:nn {#1}{#2}
}
\tikzset{
  save~ tiling~ path/.code={
    \tikz@addmode{
      \pgfsyssoftpath@getcurrentpath\l__tilings_tmpa_tl
      \__tilings_normalise_path:N \l__tilings_tmpa_tl
      \tl_gclear_new:c {g__tilings_side_#1_tl}
      \tl_gset_eq:cN {g__tilings_side_#1_tl} \l__tilings_tmpa_tl
      \tl_set:Nx \l__tilings_tmpb_tl {\str_uppercase:n {#1}}
      \spath_reverse:N \l__tilings_tmpa_tl
      \spath_transform:Nnnnnnn \l__tilings_tmpa_tl {-1} {0} {0} {-1} {1} {0}
      \tl_gclear_new:c {g__tilings_side_ \tl_use:N \l__tilings_tmpb_tl _tl}
      \tl_gset_eq:cN {g__tilings_side_ \tl_use:N \l__tilings_tmpb_tl _tl} \l__tilings_tmpa_tl
    }
  },
  clone~ tiling~ side~ path/.style~ 2~ args={
    spath/set~ name=tiling~ side,
    spath/clone~ global={#1}{#2}
  },
  flip~ tile/.code={
    \tl_set:Nn \l__tilings_tmpa_tl {#1}
    \tl_set:Nn \l__tilings_tmpb_tl {true}
    \bool_set:Nn \l__tilings_cw_bool {\tl_if_eq_p:NN \l__tilings_tmpa_tl \l__tilings_tmpb_tl}
  },
  flip~ tile/.default={true},
  spath/prefix/tiling~side/.style={
    spath/set~ prefix=g__tilings_side_,
  },
  spath/suffix/tiling~side/.style={
    spath/set~ suffix=_tl,
  },
  clone~ tile~ path/.style~ 2~ args={
    spath/set~ name=tiling~tile,
    spath/clone~ global={#1}{#2}
  },
  spath/prefix/tiling~tile/.style={
    spath/set~ prefix=g__tilings_tile_,
  },
  spath/suffix/tiling~tile/.style={
    spath/set~ suffix=_tl,
  },
  expand~ key/.code={
    \exp_args:NV \pgfkeysalso #1
  }
}
\cs_new_nopar:Npn \__tilings_make_lms:Nnnn #1#2#3#4
{
  \group_begin:
  \tl_set:Nn \l__tilings_tmpb_tl {#4}
  \prg_replicate:nn {#3} {
    \tl_set_eq:NN \l__tilings_tmpa_tl \l__tilings_tmpb_tl
    \tl_clear:N \l__tilings_tmpb_tl
    \tl_map_inline:Nn \l__tilings_tmpa_tl
    {
      \tl_set:Nx \l__tilings_action_lms_tl {\tl_head:n {##1}}
      \tl_set:Nx \l__tilings_parameters_lms_tl {\tl_tail:n {##1}}
      \prop_if_in:cVTF {g__tilings_#2_lms_rule_prop} \l__tilings_action_lms_tl
      {
        \prop_get:cVN {g__tilings_#2_lms_rule_prop} \l__tilings_action_lms_tl \l__tilings_tmpc_tl
        \tl_put_right:Nx \l__tilings_tmpb_tl {\tl_use:N \l__tilings_tmpc_tl}
      }
      {
        \tl_if_single:nTF {##1}
        {
          \tl_put_right:Nn \l__tilings_tmpb_tl {##1}
        }
        {
          \tl_put_right:Nn \l__tilings_tmpb_tl {{##1}}
        }
      }
    }
  }
  \tl_set:Nn \l__tilings_tmpa_tl {
    \group_end:
    \tl_set:Nn #1
  }
  \tl_put_right:Nx \l__tilings_tmpa_tl {{\tl_use:N \l__tilings_tmpb_tl}}
  \tl_use:N \l__tilings_tmpa_tl
}
\cs_generate_variant:Nn \__tilings_make_lms:Nnnn {Nnnx}
\cs_new_nopar:Npn \__tilings_invoke_lms:nn #1#2
{
  \group_begin:
  \tl_map_inline:nn {#1} {
    \tl_set:Nx \l__tilings_action_lms_tl {\tl_head:n {##1}}
    \tl_set:Nx \l__tilings_parameters_lms_tl {\tl_tail:n {##1}}
    \prop_if_in:cVTF {g__tilings_#2_lms_action_prop} \l__tilings_action_lms_tl
    {
      \prop_item:cV {g__tilings_#2_lms_action_prop} \l__tilings_action_lms_tl
    }
    {
      \prop_if_in:cVT {g__tilings_default_lms_action_prop} \l__tilings_action_lms_tl
      {
        \prop_item:cV {g__tilings_default_lms_action_prop} \l__tilings_action_lms_tl
      }
    }
  }
  \group_end:
}
\cs_generate_variant:Nn \__tilings_invoke_lms:nn {Vn}
\dim_new:N \l__tilings_step_dim
\dim_set:Nn \l__tilings_step_dim {1cm}
\prop_new:N \g__tilings_default_lms_action_prop
\prop_gput:Nnn \g__tilings_default_lms_action_prop {[} {\group_begin:}
\prop_gput:Nnn \g__tilings_default_lms_action_prop {]} {\group_end:}
\prop_gput:Nnn \g__tilings_default_lms_action_prop {f}
{\pgftransformxshift{\l__tilings_step_dim}}
\prop_gput:Nnn \g__tilings_default_lms_action_prop {b}
{\pgftransformxshift{-\l__tilings_step_dim}}
\prop_new:N \g__tilings_drawables_lms_prop
\int_new:N \g__tilings_tile_int
\int_new:N \g__tilings_tiles_int
\cs_new_protected_nopar:Npn \__tilings_tiling_decomposition:nnnn #1#2#3#4
{
  \group_begin:
  \tikzset{
    every~ #2~ decomposition/.try,
    #1
  }
  \__tilings_make_lms:Nnnx \l__tilings_tmpa_tl {#2} {#3} {#4}
  \__tilings_count_lms:Vn \l__tilings_tmpa_tl {#2}
  \int_gzero:N \g__tilings_tile_int
  \__tilings_invoke_lms:Vn \l__tilings_tmpa_tl {#2}
  \group_end:
}
\cs_new_protected_nopar:Npn \__tilings_tiling_decomposition:nnn #1#2#3
{
  \__tilings_tiling_decomposition:nnnn {}{#1}{#2}{#3}
}
\cs_generate_variant:Nn \__tilings_tiling_decomposition:nnn {VVV}

\NewDocumentCommand \TilingDecomposition { O{} m m m }
{
 \__tilings_tiling_decomposition:nnnn {#1}{#2}{#3}{#4}
}

\tikzset{
  pics/decomposition/.style~ n~ args={3}{
    code={
      \__tilings_tiling_decomposition:nnn {#1}{#2}{#3}
    }
  }
}
\cs_new_nopar:Npn \__tilings_count_lms:nn #1#2
{
  \group_begin:
  \int_gzero:N \g__tilings_tiles_int
  \prop_get:NnNT \g__tilings_drawables_lms_prop {#2} \l__tilings_tmpa_tl
  {
    \tl_map_variable:nNn {#1} \l__tilings_tmpb_tl
    {
      \tl_set:Nx \l__tilings_tmpb_tl {\tl_head:N \l__tilings_tmpb_tl}
      \bool_do_while:nn
      {
        !\tl_if_empty_p:N \l__tilings_tmpb_tl
        &&
        \tl_if_head_is_group_p:V \l__tilings_tmpb_tl
      }
      {
        \tl_set:Nx \l__tilings_tmpb_tl {\tl_head:N \l__tilings_tmpb_tl}
      }
      \tl_if_in:NVT \l__tilings_tmpa_tl \l__tilings_tmpb_tl
      {
        \int_gincr:N \g__tilings_tiles_int
      }
    }
  }
  \group_end:
}
\cs_generate_variant:Nn \__tilings_count_lms:nn {Vn}
\tikzset{
  tiling~ step/.code={
    \dim_set:Nn \l__tilings_step_dim {#1}
  }
}
\ExplSyntaxOff
%% 
%% Copyright (C) 2014-2023 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  penrose_code.dtx
%%                                  penrose.tex
%% and the derived files            penrose.ins
%%                                  penrose_code.pdf
%%                                  penrose.pdf
%%                                  tikzlibrarytilings.code.tex
%%                                  tikzlibrarytilings.penrose.code.tex
%%                                  tikzlibrarytilings.polykite.code.tex
%%                                  tikzlibrarypenrose.code.tex
%%                                  README.txt
%% 
%%
%% End of file `tikzlibrarytilings.code.tex'.
