%%
%% This is file `keys3.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% keys3.dtx  (with options: `package')
%% ---------------------------------------------------------------
%% The keys3 package --- Key management for LaTeX3
%% Maintained by Joseph Wright
%% E-mail: joseph.wright@morningstar2.co.uk
%% Released under the LaTeX Project Public License v1.3c or later
%% See http://www.latex-project.org/lppl.txt
%% ---------------------------------------------------------------
%% 
%% EXPERIMENTAL CODE
%% 
%% Do not distribute this file without also distributing the
%% source files specified above.
%% 
%% Do not distribute a modified version of this file.
%% 
\RequirePackage{expl3}
\GetIdInfo$Id: keys3.dtx 101 2009-06-10 12:16:20Z josephwright $
  {Key management for LaTeX3}
\ProvidesExplPackage
  {\filename}{\filedate}{\fileversion}{\filedescription}
\tl_new:cn { c_keys_0_empty_tl } {}
\tl_new:cn { c_keys_1_empty_tl } { {} }
\tl_new:cn { c_keys_2_empty_tl } { {} {} }
\tl_new:cn { c_keys_3_empty_tl } { {} {} {} }
\tl_new:cn { c_keys_4_empty_tl } { {} {} {} {} }
\tl_new:cn { c_keys_5_empty_tl } { {} {} {} {} {} }
\tl_new:cn { c_keys_6_empty_tl } { {} {} {} {} {} {} }
\tl_new:cn { c_keys_7_empty_tl } { {} {} {} {} {} {} {} }
\tl_new:cn { c_keys_8_empty_tl } { {} {} {} {} {} {} {} {} }
\tl_new:cn { c_keys_9_empty_tl } { {} {} {} {} {} {} {} {} {} }
\tl_new:Nn \c_keys_cs_prefix_tl { keys-root }
\tl_new:Nn \c_keys_errors_path_tl     { /keys/errors }
\tl_new:Nn \c_keys_properties_path_tl { /keys/properties }
\tl_new:Nn \c_keys_utilities_path_tl  { /keys }
\tl_new:Nn \c_keys_root_tl { / }
\tl_new:N \l_keys_choice_code_tl
\tl_new:N \l_keys_current_choice_tl
\int_new:N \l_keys_current_choice_int
\tl_new:N \l_keys_current_key_full_tl
\tl_new:N \l_keys_current_default_tl
\tl_new:N \l_keys_current_module_tl
\tl_new:N \l_keys_current_path_tl
\tl_new:N \l_keys_default_path_tl
\tl_set_eq:NN \l_keys_default_path_tl \c_keys_root_tl
\tl_new:N \l_keys_choice_path_tl
\toks_new:N \l_keys_current_value_toks
\bool_new:N \l_keys_no_value_bool
\bool_new:N \l_keys_success_bool
\tl_new:N \l_keys_tmpa_tl
\cs_new:Nn \keys_manage:n {
  \cs_set_eq:NN \keys_parse:n \KV_parse_space_removal_sanitize:n
  \tl_clear:N \l_keys_current_module_tl
  \keys_manage_internal:n {#1}
}
\cs_new:Nn \keys_manage_quick:n {
  \cs_set_eq:NN \keys_parse:n \KV_parse_no_space_removal_no_sanitize:n
  \tl_clear:N \l_keys_current_module_tl
  \keys_manage_internal:n {#1}
}
\cs_new:Nn \keys_manage_internal:n {
  \keys_manage_aux:Vn \l_keys_default_path_tl {#1}
}
\cs_new:Nn \keys_manage_aux:nn {
  \tl_set_eq:NN \l_keys_default_path_tl \c_keys_root_tl
  \keys_parse_list:n {#2}
  \tl_set:Nn \l_keys_default_path_tl {#1}
}
\cs_generate_variant:Nn \keys_manage_aux:nn { Vn }
\cs_new:Nn \keys_manage:nn {
  \cs_set_eq:NN \keys_parse:n \KV_parse_space_removal_sanitize:n
  \keys_manage_aux:Vnn \l_keys_default_path_tl {#1} {#2}
}
\cs_new:Nn \keys_manage_quick:nn {
  \cs_set_eq:NN \keys_parse:n \KV_parse_space_no_removal_no_sanitize:n
  \keys_manage_aux:Vnn \l_keys_default_path_tl {#1} {#2}
}
\cs_new:Nn \keys_manage_aux:nnn {
  \tl_set:Nn \l_keys_default_path_tl {#2}
  \tl_clear:N \l_keys_current_module_tl
  \keys_parse_list:n {#3}
  \tl_set:Nn \l_keys_default_path_tl {#1}
}
\cs_generate_variant:Nn \keys_manage_aux:nnn { Vnn }
\cs_new_nopar:Nn \keys_bool_new:n {
  \bool_new:c { \c_keys_cs_prefix_tl #1 }
  \bool_set_true:c { \c_keys_cs_prefix_tl #1 }
}
\cs_new_nopar:Nn \keys_bool_set:nN {
  \keys_parse_list:n {
    \c_keys_properties_path_tl /.code:n = {
      \cs_if_exist:cTF { bool_ #1 _ ##1 :N } {
        \use:c { bool_ #1 _ ##1 :N } #2
      }{
        \keys_error:nn { Boolean~expected } {##1}
      }
    },
    \l_keys_current_path_tl /.default:n = true
  }
}
\cs_new_nopar:Nn \keys_bool_set:nnn {
  \keys_parse_list:n {
    \c_keys_properties_path_tl /.code:x = {
      \exp_not:N \cs_if_exist:cTF { bool_ #1 _ ##1 :c } {
        \exp_not:N \use:c { bool_ #1 _ ##1 :c }
          { #2 \l_keys_current_module_tl #3 _bool }
      }{
        \keys_error:nn { Boolean~expected } {##1}
      }
    },
    \l_keys_current_path_tl /.default:n = true
  }
}
\cs_new_nopar:Nn \keys_bool_set_inverse:n {
  \tl_if_eq:nnTF {#1} { true } { false } { true }
}
\cs_new_nopar:Nn \keys_bool_set_inverse:nN {
  \keys_parse_list:n {
    \c_keys_properties_path_tl /.code:n = {
      \cs_if_exist:cTF { bool_ #1 _ ##1 :N } {
        \use:c { bool_ #1 _ \keys_bool_set_inverse:n {##1} :N } #2
      }{
        \keys_error:nn { Boolean~expected } {##1}
      }
    },
    \l_keys_current_path_tl /.default:n = true
  }
}
\cs_new_nopar:Nn \keys_bool_set_inverse:nnn {
  \keys_parse_list:n {
    \c_keys_properties_path_tl /.code:x = {
      \exp_not:N \cs_if_exist:cTF { bool_ #1 _ ##1 :c } {
         \exp_not:N \use:c {
           bool_ #1 _ \exp_not:N \keys_bool_set_inverse:n {##1} :c
         } { #2 \l_keys_current_module_tl #3 _bool }
      }{
        \keys_error:nn { Boolean~expected } {##1}
      }
    },
    \l_keys_current_path_tl /.default:n = true
  }
}
\cs_new_nopar:Nn \keys_check_exists:NN {
  \cs_if_exist:NF #1 {
    #2 #1
  }
}
\cs_generate_variant:Nn \keys_check_exists:NN { cN }
\cs_new:Nn \keys_choices_create:Nnn {
  \tl_set_eq:NN \l_keys_choice_path_tl \l_keys_current_path_tl
  \int_zero:N \l_keys_current_choice_int
  \use:c { keys_choices_create_aux: #1 } {#3}
  \clist_map_function:nN {#2} \keys_choice_create:n
  \keys_manage_internal:n { \l_keys_choice_path_tl  /.expects_choice: }
}
\cs_new:Nn \keys_choices_create_aux:n {
  \tl_set:Nn \l_keys_choice_code_tl { \exp_not:n {#1} }
}
\cs_new:Nn \keys_choices_create_aux:x {
  \tl_set:Nn \l_keys_choice_code_tl {#1}
}
\cs_new_nopar:Nn \keys_choice_create:n {
  \int_incr:N \l_keys_current_choice_int
  \keys_parse_list:n {
    \l_keys_choice_path_tl / #1 /.code:x = {
      \exp_not:n { \int_set:Nn \l_keys_current_choice_int }
        { \int_use:N \l_keys_current_choice_int }
      \exp_not:n { \tl_set:Nn \l_keys_current_choice_tl } {#1}
      \l_keys_choice_code_tl
    }
  }
}
\cs_new_nopar:Nn \keys_clear_properties:n {
  \keys_undefine:n { #1 /._cmd:w }
  \keys_undefine:n { #1 /._default_tl }
  \keys_undefine:n { #1 /._forbidden_bool }
  \keys_undefine:n { #1 /._num_args_tl }
  \keys_undefine:n { #1 /._required_bool }
}
\cs_new_nopar:Nn \keys_default_add: {
  \bool_if:NT \l_keys_no_value_bool {
    \keys_if_exist:nT
      { \l_keys_current_key_full_tl /._default_tl } {
      \keys_toks_set:Nn \l_keys_current_value_toks
        { \l_keys_current_key_full_tl /._default_tl }
      \bool_set_false:N \l_keys_no_value_bool
    }
  }
}
\cs_new_nopar:Nn \keys_find_code_full: {
  \keys_if_cmd_exist:nTF { \l_keys_current_key_full_tl } {
    \keys_use_cmd:n { \l_keys_current_key_full_tl }
  }{
    \keys_if_exist:nTF { \l_keys_current_key_full_tl } {
      \bool_if:NTF \l_keys_no_value_bool {
        \keys_use:n { \l_keys_current_key_full_tl }
      }{
        \keys_store:nx { \l_keys_current_key_full_tl }
          { \toks_use:N \l_keys_current_value_toks }
      }
    }{
      \keys_find_code_name:
    }
  }
}
\cs_new_nopar:Nn \keys_find_code_name: {
  \keys_separate_path:
  \keys_if_cmd_exist:nTF
    { \c_keys_properties_path_tl / \l_keys_current_key_name_tl } {
    \keys_use_cmd:n
      {\c_keys_properties_path_tl / \l_keys_current_key_name_tl}
  }{
    \keys_if_cmd_exist:nTF
      { \l_keys_current_path_tl / unknown } {
      \keys_use_cmd:n { \l_keys_current_path_tl / unknown }
    }{
      \keys_error:n { unknown~key }
    }
  }
}
\prg_new_conditional:Nnn \keys_if_cmd_exist:n {TF,T,F} {
 \if_cs_exist:w \c_keys_cs_prefix_tl #1 /._cmd:w \cs_end:
   \prg_return_true:
  \else:
    \prg_return_false:
  \fi:
}
\prg_new_conditional:Nnn \keys_if_exist:n {TF,T,F} {
 \if_cs_exist:w \c_keys_cs_prefix_tl #1 \cs_end:
   \prg_return_true:
  \else:
    \prg_return_false:
  \fi:
}
\prg_new_conditional:Nnn \keys_if_value:n {TF,T,F} {
 \if_cs_exist:w
   \c_keys_cs_prefix_tl \l_keys_current_key_full_tl /._ #1 _bool
 \cs_end:
   \prg_return_true:
  \else:
    \prg_return_false:
  \fi:
}
\cs_new:Nn \keys_no_value_elt:n {
  \bool_set_true:N \l_keys_no_value_bool
  \keys_process_elt:nn {#1} { }
}
\cs_new:Nn \keys_value_elt:nn {
  \bool_set_false:N \l_keys_no_value_bool
  \keys_process_elt:nn {#1} {#2}
}
\cs_new:Nn \keys_parse:n { \ERROR }
\cs_new:Nn \keys_parse_list:n {
  \cs_set_eq:NN \KV_key_value_elt:nn \keys_value_elt:nn
  \cs_set_eq:NN \KV_key_no_value_elt:n \keys_no_value_elt:n
  \keys_parse:n {#1}
}
\cs_new_nopar:Nn \keys_path_add:N {
  \exp_after:wN \keys_path_add:w #1 \q_stop
}
\cs_new_nopar:Npn \keys_path_add:w {
  \exp_after:wN \peek_meaning:NTF \c_keys_root_tl {
    \use_none_delimit_by_q_stop:w
  }{
    \keys_path_add_aux:w
  }
}
\cs_new_nopar:Npn \keys_path_add_aux:w #1 \q_stop {
  \tl_set:Nx \l_keys_current_key_full_tl {\l_keys_default_path_tl #1}
}
\cs_new:Nn \keys_process_elt:nn {
  \tl_set:Nx \l_keys_current_key_full_tl {#1}
  \toks_set:Nn \l_keys_current_value_toks {#2}
  \keys_path_add:N \l_keys_current_key_full_tl
  \keys_default_add:
  \keys_if_value:nTF { required } {
    \bool_if:NTF \l_keys_no_value_bool {
      \keys_error:n { value~required }
    }{
      \keys_process_elt_aux:
    }
  }{
    \keys_process_elt_aux:
  }
}
\cs_new:Nn \keys_process_elt_aux: {
  \keys_if_value:nTF { forbidden } {
    \bool_if:NTF \l_keys_no_value_bool {
      \keys_find_code_full:
    }{
      \keys_error:nn { value~forbidden }
        { \toks_use:N \l_keys_current_value_toks }
    }
  }{
    \keys_find_code_full:
  }
}
\cs_new_nopar:Nn \keys_separate_path: {
  \tl_clear:N \l_keys_current_path_tl
  \exp_after:wN \keys_separate_path:w \l_keys_current_key_full_tl
    / \q_stop
}
\cs_new_nopar:Npn \keys_separate_path:w / #1 / #2 \q_stop {
  \tl_if_empty:nTF {#2} {
    \tl_set:Nn \l_keys_current_key_name_tl {#1}
  }{
     \tl_put_right:Nn \l_keys_current_path_tl { / #1 }
     \keys_separate_path:w /#2 \q_stop
  }
}
\cs_new_nopar:Nn \keys_set:NN {
  \keys_parse_list:n {
    \c_keys_properties_path_tl /.code:n = {
      #1 #2 {##1}
    }
  }
}
\cs_new_nopar:Nn \keys_set:Nnn {
  \keys_parse_list:n {
    \c_keys_properties_path_tl /.code:x = {
      \exp_not:N #1 { #2 \l_keys_current_module_tl #3 } {##1}
    }
  }
}
\cs_new:Nn \keys_set_cmd:nn {
  \keys_clear_properties:n {#1}
  \cs_set:cpn { \c_keys_cs_prefix_tl #1 /._cmd:w } ##1 {#2}
}
\cs_new:Nn \keys_set_cmd:nx {
  \keys_clear_properties:n {#1}
  \cs_set:cpx { \c_keys_cs_prefix_tl #1 /._cmd:w } ##1 {#2}
}
\cs_new:Nn \keys_set_cmd:nNn {
  \keys_clear_properties:n {#1}
  \cs_generate_from_arg_count:cNnn { \c_keys_cs_prefix_tl #1 /._cmd:w }
      \cs_set:Npn #2 {#3}
  \keys_store:nn { #1 /._num_args_tl} {#2}
}
\cs_new:Nn \keys_set_cmd:nNx {
  \keys_clear_properties:n {#1}
  \cs_generate_from_arg_count:cNnn { \c_keys_cs_prefix_tl #1 /._cmd:w }
      \cs_set:Npx #2 {#3}
  \keys_store:nn { #1 /._num_args_tl} {#2}
}
\cs_new:Nn \keys_store:nn {
  \tl_set:cn { \c_keys_cs_prefix_tl #1 } {#2}
}
\cs_new:Nn \keys_store:nx {
  \tl_set:cx { \c_keys_cs_prefix_tl #1 } {#2}
}
\cs_new_nopar:Nn \keys_toks_set:Nn {
  \exp_args:NNv \toks_set:Nn #1 { \c_keys_cs_prefix_tl #2 }
}
\cs_new_nopar:Nn \keys_try: {
  \bool_set_false:N \l_keys_success_bool
  \keys_if_cmd_exist:nT { \l_keys_current_path_tl } {
    \bool_set_true:N \l_keys_success_bool
    \bool_if:NT \l_keys_no_value_bool {
      \keys_if_exist:nT
        { \l_keys_current_path_tl /._default_tl } {
        \keys_toks_set:Nn \l_keys_current_value_toks
          { \l_keys_current_path_tl /._default_tl }
      }
    }
    \cs_set_eq:NN \l_keys_current_key_full_tl \l_keys_current_path_tl
    \keys_use_cmd:n { \l_keys_current_path_tl }
  }
}
\cs_new_nopar:Nn \keys_undefine:n {
  \cs_set_eq:cN { \c_keys_cs_prefix_tl #1 } \c_undefined
}
\cs_new_nopar:Nn \keys_use:n {
  \use:c { \c_keys_cs_prefix_tl #1 }
}
\cs_new_nopar:Nn \keys_use_cmd:n {
  \exp_args:Nno \keys_use_cmd:nn {#1}
    { \toks_use:N \l_keys_current_value_toks }
}
\cs_new_nopar:Nn \keys_use_cmd:nn {
  \keys_if_exist:nTF { #1 /._num_args_tl } {
     \keys_use_cmd_aux:nn {#1} {#2}
  }{
    \keys_use:n {#1/._cmd:w} {#2}
  }
}
\cs_new_nopar:Nn \keys_use_cmd_aux:nn {
  \tl_if_empty:nTF {#2} {
    \cs_set:Npn \keys_use_cmd_aux:w {
      \keys_use:n { #1 /._cmd:w }
    }
    \exp_after:wN \exp_after:wN \exp_after:wN \keys_use_cmd_aux:w
      \cs:w
        c_keys_ \keys_use:n { #1 /._num_args_tl } _empty_tl
      \cs_end:
  }{
    \keys_use:n { #1 /._cmd:w } #2
  }
}
\cs_new_nopar:Npn \keys_msg_new:nn #1 {
  \msg_new:nnn { keys } {#1}
}
\cs_new_protected_nopar:Nn \keys_error:nn {
  \msg_error:nnxx { keys } {#1} { \l_keys_current_key_full_tl } {#2}
}
\cs_new_protected_nopar:Nn \keys_error:n {
  \msg_error:nnx { keys } {#1} { \l_keys_current_key_full_tl }
}
\keys_msg_new:nn
  { unknown~key }
  {The key `#1' is unknown and is being ignored.}
\keys_msg_new:nn
  { value~required }
  {The key `#1' requires a value\\%
  and is being ignored.}
\keys_msg_new:nn
  { value~forbidden }
  {The key `#1' cannot taken a value:\\%
   the given input `#2' is being ignored.}
\keys_msg_new:nn
  { Boolean~expected }
  {Key `#1' takes the Boolean values\\%
  `true' and `false'~only.\\%
   The given value `#2' is being ignored.}
\keys_msg_new:nn
  { not_boolean }
  {Key `#1' is not a Boolean key: you cannot create a complement.}
\keys_msg_new:nn
  { unknown~choice }
  {Choice `#2' unknown for key `#1':\\%
   the key is being ignored.}
\keys_set_cmd:nn { \c_keys_properties_path_tl /.code:n } {
  \keys_set_cmd:nn { \l_keys_current_path_tl } {#1}
}
\keys_set_cmd:nNn { \c_keys_properties_path_tl /.code:Nn } 2 {
  \keys_set_cmd:nNn { \l_keys_current_path_tl } #1 {#2}
}
\keys_manage_quick:n {
  \c_keys_errors_path_tl /unknown/.code:n = {
    \keys_error:n { unknown~key }
  }
}
\keys_manage_quick:n {
  \c_keys_properties_path_tl /.code:x/.code:n = {
    \keys_set_cmd:nx { \l_keys_current_path_tl } {#1}
  },
  \c_keys_properties_path_tl /.code:Nx/.code:Nn = 2 {
    \keys_set_cmd:nNx { \l_keys_current_path_tl } {#1} {#2}
  }
}
\keys_manage_quick:n {
    \c_keys_properties_path_tl /.cd:/.code:n = {
    \tl_set:Nx \l_keys_default_path_tl { \l_keys_current_path_tl / }
  }
}
\keys_manage_quick:n {
  \c_keys_properties_path_tl /.value_required:/.code:n = {
    \keys_bool_new:n { \l_keys_current_path_tl /._required_bool }
    \keys_undefine:n { \l_keys_current_path_tl /._forbidden_bool }
  },
  \c_keys_properties_path_tl /.value_forbidden:/.code:n = {
    \keys_bool_new:n { \l_keys_current_path_tl /._forbidden_bool }
    \keys_undefine:n { \l_keys_current_path_tl /._required_bool }
  }
}
\keys_manage_quick:n {
  \c_keys_properties_path_tl /.default:n/.code:n = {
    \keys_store:nn { \l_keys_current_path_tl /._default_tl } {#1}
    \keys_undefine:n { \l_keys_current_path_tl /._required_bool }
  }
}
\keys_manage_quick:n {
  \c_keys_properties_path_tl /.tl_set:N/.code:n = {
    \keys_check_exists:NN #1 \tl_new:N
    \keys_set:NN \tl_set:Nn #1
  },
  \c_keys_properties_path_tl /.tl_set_x:N/.code:n = {
    \keys_check_exists:NN #1 \tl_new:N
    \keys_set:NN \tl_set:Nx #1
  },
  \c_keys_properties_path_tl /.tl_gset:N/.code:n = {
    \keys_check_exists:NN #1 \tl_new:N
    \keys_set:NN \tl_gset:Nn #1
  },
  \c_keys_properties_path_tl /.tl_gset_x:N/.code:n = {
    \keys_check_exists:NN #1 \tl_new:N
    \keys_set:NN \tl_gset:Nx #1
  }
}
\keys_manage_quick:n {
  \c_keys_properties_path_tl /.int_set:N/.code:n = {
    \keys_check_exists:NN #1 \int_new:N
    \keys_set:NN \int_set:Nn #1
  },
  \c_keys_properties_path_tl /.int_gset:N/.code:n = {
    \keys_check_exists:NN #1 \int_new:N
    \keys_set:NN \int_gset:Nn #1
  },
  \c_keys_properties_path_tl /.skip_set:N/.code:n = {
    \keys_check_exists:NN #1 \skip_new:N
    \keys_set:NN \skip_set:Nn #1
  },
  \c_keys_properties_path_tl /.skip_gset:N/.code:n = {
    \keys_check_exists:NN #1 \skip_new:N
    \keys_set:NN \skip_gset:Nn #1
  },
  \c_keys_properties_path_tl /.toks_set:N/.code:n = {
    \keys_check_exists:NN #1 \toks_new:N
    \keys_set:NN \toks_set:Nn #1
  },
  \c_keys_properties_path_tl /.toks_gset:N/.code:n = {
    \keys_check_exists:NN #1 \toks_new:N
    \keys_set:NN \toks_gset:Nn #1
  }
}
\keys_manage_quick:n {
  \c_keys_utilities_path_tl /current_module:n/.code:n = {
    \tl_if_empty:nTF {#1} {
      \tl_clear:N \l_keys_current_module_tl
    }{
      \tl_set:Nn \l_keys_current_module_tl { #1 _ }
    }
  }
}
\keys_manage_quick:n {
  \c_keys_properties_path_tl /.tl_set:n/.code:n = {
    \keys_check_exists:cN { l_ #1 _tl } \tl_new:N
    \keys_set:Nnn \tl_set:cn { l_ } { #1 _tl }
  },
  \c_keys_properties_path_tl /.tl_set_x:n/.code:n = {
    \keys_check_exists:cN { l_ #1 _tl } \tl_new:N
    \keys_set:Nnn \tl_set:cx { l_ } { #1 _tl }
  },
  \c_keys_properties_path_tl /.tl_gset:n/.code:n = {
    \keys_check_exists:cN { g_ #1 _tl } \tl_new:N
    \keys_set:Nnn \tl_gset:cn { g_ } { #1 _tl }
  },
  \c_keys_properties_path_tl /.tl_gset_x:n/.code:n = {
    \keys_check_exists:cN { g_ #1 _tl } \tl_new:N
    \keys_set:Nnn \tl_gset:cx { g_ } { #1 _tl }
  },
  \c_keys_properties_path_tl /.int_set:n/.code:n = {
    \keys_check_exists:cN { l_ #1 _int } \int_new:N
    \keys_set:Nnn \int_set:cn { l_ } { #1 _int }
  },
  \c_keys_properties_path_tl /.int_gset:n/.code:n = {
    \keys_check_exists:cN { g_ #1 _int } \int_new:N
    \keys_set:Nnn \int_gset:cn { g_ } { #1 _int }
  },
  \c_keys_properties_path_tl /.skip_set:n/.code:n = {
    \keys_check_exists:cN { l_ #1 _skip } \skip_new:N
    \keys_set:Nnn \skip_set:cn { l_ } { #1 _skip }
  },
  \c_keys_properties_path_tl /.skip_gset:n/.code:n = {
    \keys_check_exists:cN { g_ #1 _skip } \skip_new:N
    \keys_set:Nnn \skip_gset:cn { g_ } { #1 _skip }
  },
  \c_keys_properties_path_tl /.toks_set:n/.code:n = {
   \keys_check_exists:cN { g_ #1 _toks } \toks_new:N
    \keys_set:Nnn \toks_set:cn { l_ } { #1 _toks }
  },
  \c_keys_properties_path_tl /.toks_gset:n/.code:n = {
    \keys_check_exists:cN { g_ #1 _toks } \toks_new:N
    \keys_set:Nnn \toks_gset:cn { g_ } { #1 _toks }
  },
}
\keys_manage_quick:n {
  \c_keys_properties_path_tl /.bool_set:N/.code:n = {
    \keys_bool_set:nN { set } #1
  },
  \c_keys_properties_path_tl /.bool_gset:N/.code:n = {
    \keys_bool_set:nN { gset } #1
  },
  \c_keys_properties_path_tl /.bool_set:n/.code:n = {
    \keys_bool_set:nnn { set } { l_ } { #1 }
  },
  \c_keys_properties_path_tl /.bool_gset:n/.code:n = {
    \keys_bool_set:nnn { gset } { g_ } { #1 }
  },
}
\keys_manage_quick:n {
  \c_keys_properties_path_tl /.bool_set_inverse:N/.code:n = {
    \keys_bool_set_inverse:nN { set } #1
  },
  \c_keys_properties_path_tl /.bool_gset_inverse:N/.code:n = {
    \keys_bool_set_inverse:nN { gset } #1
  },
  \c_keys_properties_path_tl /.bool_set_inverse:n/.code:n = {
    \keys_bool_set_inverse:nnn { set } { l_ } { #1 }
  },
  \c_keys_properties_path_tl /.bool_gset_inverse:n/.code:n = {
    \keys_bool_set_inverse:nnn { gset } { g_ } { #1 }
  },
}
\keys_manage_quick:n {
  \c_keys_properties_path_tl /.expects_choice:/.code:n = {
    \keys_manage_internal:n {
      \l_keys_current_path_tl /.cd:,
      .code:n = {
        \tl_set:Nn \l_keys_current_choice_tl {##1}
        \int_zero:N \l_keys_current_choice_int
        \exp_args:No \keys_parse_list:n
          { \l_keys_current_key_full_tl / ##1 }
      },
      unknown/.code:n = {
        \keys_error:nn { unknown~choice }
          { \l_keys_current_key_name_tl }
      }
    }
  },
}
\keys_manage_quick:n {
  \c_keys_properties_path_tl /.create_choices:nn/.code:Nn = 2 {
    \keys_choices_create:Nnn n {#1} {#2}
  },
  \c_keys_properties_path_tl /.create_choices:nx/.code:Nn = 2 {
    \keys_choices_create:Nnn x {#1} {#2}
  },
}
\keys_manage_quick:n {
  \c_keys_properties_path_tl /.use_keys:n/.code:n = {
    \keys_manage_internal:n {
      \l_keys_current_path_tl /.code:n = { \keys_parse_list:n {#1} }
    }
  },
  \c_keys_properties_path_tl /.use_keys:x/.code:n = {
    \keys_manage_internal:n {
      \l_keys_current_path_tl /.code:x = {
        \exp_not:N \keys_parse_list:n {#1}
      }
    }
  },
  \c_keys_properties_path_tl /.use_keys:Nn/.code:Nn = 2 {
    \keys_manage_internal:n {
      \l_keys_current_path_tl /.code:Nn = #1 { \keys_parse_list:n {#2} }
    }
  },
  \c_keys_properties_path_tl /.use_keys:Nx/.code:Nn = 2 {
    \keys_manage_internal:n {
      \l_keys_current_path_tl /.code:Nx =
        #1 { \exp_not:N \keys_parse_list:n {#2} }
    }
  }
}
\keys_manage_quick:n {
  \c_keys_properties_path_tl /.try:n/.code:n = { \keys_try: },
  \c_keys_properties_path_tl /.retry:n/.code:n = {
    \bool_if:NF \l_keys_success_bool { \keys_try: }
  }
}
\keys_manage_quick:n {
  \c_keys_properties_path_tl /.show_code:/.code:n = {
    \cs_show:c {
      \c_keys_cs_prefix_tl \l_keys_current_path_tl /._cmd:w
    }
  },
  \c_keys_properties_path_tl /.show_key:/.code:n = {
    \cs_show:c { \c_keys_cs_prefix_tl \l_keys_current_path_tl }
  }
}
%% 
%% Copyright (C) 2008-2009 by
%%   Joseph Wright <joseph.wright@morningstar2.co.uk>
%% 
%% It 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
%%   Joseph Wright.
%% 
%% This work consists of the file  keys3.dtx
%%           and the derived files keys3.pdf,
%%                                 keys3.sty and
%%                                 keys3.ins.
%% 
%%
%% End of file `keys3.sty'.
