Permalink
Browse files

* The great tag breakout!

	* Almost all tags are now UserTag definitions. The only exceptions
	  are:

		and bounce goto if label or unless

    * New TagDir directive (default is VENDROOT/code) sets the
	  directory (or directories) which are searched for code definitions
	  set by UserTag and CodeDef.

	* New TagGroup directive establishes groups of ITL tags which can
	  be included.

	  	TagGroup :crufty "banner default ecml html_table onfly sql"

	  The default groups include :core, which contains all of the
	  ITL tags defined in 4.8/early 4.9. The groups are defined
	  in $Vend::Cfg::StdTags and can be undefined if desired
	  with "TagGroup :group".

	* New TagInclude directive allows inclusion of tags (or groups
	  of tags). If a tag is defined as a core tag (with a .coretag
	  or .tag or .ct extension) and is not included, it will not
	  be compiled and placed in the tag map. This is for all catalogs,
	  so if *any* catalog uses a tag it must be included.

	  Examples:

		# Include the base tags
	  	TagInclude :core

		# Not the commerce tags
		TagInclude !:commerce

		# But make sure item-list is included even though
		# it is in :commerce
		TagInclude item-list

		## Double negatives are honored
		TagGroup    :foo "bar !baz buz"
		## With the group above, the below is equivalent
		## to TagInclude !bar baz !buz
		TagInclude !:foo

    * New CodeDef directive allows the setting of filters,
	  order checks, FormAction, ActionMap, ItemAction,
	  and LocaleChange.

			## filters
			CodeDef  mixedcase Filter
			CodeDef  mixedcase Routine <<EOR
			sub {
				my $val = shift;
				## [filter mixedcase]mixed case[/filter]
				## outputs "MiXeD CaSe"
				$val =~ s/(.)(.)/\u$1\l$2/g;
				return $val;
			}
			EOR

			## order checks
			CodeDef  mixedcase OrderCheck
			CodeDef  foo  Routine <<EOR
			sub {
				my ($ref, $var, $val) = @_;
				return (1,$var) if $val eq 'bar';
				return (0,$var, "foo must be bar");
			}
			EOR

	   All work in catalog.cfg; LocaleChange and ItemAction are not
	   global. FormAction, ActionMap, and ItemAction directives
	   are equivalent to their CodeDef equivalents.
  • Loading branch information...
perusionmike committed Jan 29, 2002
1 parent fccf511 commit 8f219b469bac3898eb8e8c8308dbd7ca798529a0
Showing with 10,924 additions and 1,893 deletions.
  1. +6 −0 code/ActionMap/foo.am
  2. +7 −0 code/Filter/lc.filter
  3. +11 −0 code/SystemTag/accessories.coretag
  4. +7 −0 code/SystemTag/area.coretag
  5. +36 −0 code/SystemTag/assign.coretag
  6. +4 −0 code/SystemTag/attr_list.coretag
  7. +72 −0 code/SystemTag/banner.coretag
  8. +3 −0 code/SystemTag/calc.coretag
  9. +4 −0 code/SystemTag/cart.coretag
  10. +52 −0 code/SystemTag/catch.coretag
  11. +29 −0 code/SystemTag/cgi.coretag
  12. +5 −0 code/SystemTag/charge.coretag
  13. +31 −0 code/SystemTag/checked.coretag
  14. +35 −0 code/SystemTag/control.coretag
  15. +26 −0 code/SystemTag/control_set.coretag
  16. +6 −0 code/SystemTag/counter.coretag
  17. +10 −0 code/SystemTag/currency.coretag
  18. +12 −0 code/SystemTag/data.coretag
  19. +14 −0 code/SystemTag/default.coretag
  20. +3 −0 code/SystemTag/description.coretag
  21. +35 −0 code/SystemTag/discount.coretag
  22. +3 −0 code/SystemTag/dump.coretag
  23. +9 −0 code/SystemTag/ecml.coretag
  24. +15 −0 code/SystemTag/either.coretag
  25. +101 −0 code/SystemTag/error.coretag
  26. +7 −0 code/SystemTag/export.coretag
  27. +8 −0 code/SystemTag/field.coretag
  28. +29 −0 code/SystemTag/file.coretag
  29. +4 −0 code/SystemTag/filter.coretag
  30. +8 −0 code/SystemTag/flag.coretag
  31. +5 −0 code/SystemTag/fly_list.coretag
  32. +3 −0 code/SystemTag/fly_tax.coretag
  33. +9 −0 code/SystemTag/handling.coretag
  34. +36 −0 code/SystemTag/harness.coretag
  35. +4 −0 code/SystemTag/html_table.coretag
  36. +9 −0 code/SystemTag/import.coretag
  37. +10 −0 code/SystemTag/include.coretag
  38. +7 −0 code/SystemTag/index.coretag
  39. +9 −0 code/SystemTag/input_filter.coretag
  40. +19 −0 code/SystemTag/item_list.coretag
  41. +6 −0 code/SystemTag/log.coretag
  42. +7 −0 code/SystemTag/loop.coretag
  43. +6 −0 code/SystemTag/mail.coretag
  44. +56 −0 code/SystemTag/msg.coretag
  45. +9 −0 code/SystemTag/mvasp.coretag
  46. +5 −0 code/SystemTag/nitems.coretag
  47. +4 −0 code/SystemTag/onfly.coretag
  48. +4 −0 code/SystemTag/options.coretag
  49. +36 −0 code/SystemTag/order.coretag
  50. +6 −0 code/SystemTag/page.coretag
  51. +7 −0 code/SystemTag/perl.coretag
  52. +13 −0 code/SystemTag/price.coretag
  53. +15 −0 code/SystemTag/process.coretag
  54. +5 −0 code/SystemTag/profile.coretag
  55. +6 −0 code/SystemTag/query.coretag
  56. +3 −0 code/SystemTag/read_cookie.coretag
  57. +48 −0 code/SystemTag/record.coretag
  58. +7 −0 code/SystemTag/region.coretag
  59. +198 −0 code/SystemTag/row.coretag
  60. +10 −0 code/SystemTag/salestax.coretag
  61. +9 −0 code/SystemTag/scratch.coretag
  62. +9 −0 code/SystemTag/scratchd.coretag
  63. +8 −0 code/SystemTag/search_region.coretag
  64. +30 −0 code/SystemTag/selected.coretag
  65. +5 −0 code/SystemTag/set.coretag
  66. +3 −0 code/SystemTag/set_cookie.coretag
  67. +6 −0 code/SystemTag/seti.coretag
  68. +4 −0 code/SystemTag/setlocale.coretag
  69. +9 −0 code/SystemTag/shipping.coretag
  70. +3 −0 code/SystemTag/shipping_desc.coretag
  71. +5 −0 code/SystemTag/soap.coretag
  72. +6 −0 code/SystemTag/sql.coretag
  73. +10 −0 code/SystemTag/strip.coretag
  74. +10 −0 code/SystemTag/subtotal.coretag
  75. +6 −0 code/SystemTag/tag.coretag
  76. +5 −0 code/SystemTag/time.coretag
  77. +6 −0 code/SystemTag/timed_build.coretag
  78. +6 −0 code/SystemTag/tmp.coretag
  79. +10 −0 code/SystemTag/total_cost.coretag
  80. +167 −0 code/SystemTag/tree.coretag
  81. +5 −0 code/SystemTag/try.coretag
  82. +4 −0 code/SystemTag/update.coretag
  83. +7 −0 code/SystemTag/userdb.coretag
  84. +5 −0 code/SystemTag/value.coretag
  85. +5 −0 code/SystemTag/value_extended.coretag
  86. +27 −0 code/SystemTag/warnings.coretag
  87. +57 −0 code/UI_Tag/add_gpg_key.coretag
  88. +13 −0 code/UI_Tag/available_ups_internal.coretag
  89. +75 −0 code/UI_Tag/available_www_shipping.coretag
  90. +221 −0 code/UI_Tag/backup_database.coretag
  91. +36 −0 code/UI_Tag/backup_file.coretag
  92. +1 −0 code/UI_Tag/base_url.coretag
  93. +19 −0 code/UI_Tag/check_upload.coretag
  94. +193 −0 code/UI_Tag/component_editor.coretag
  95. +18 −0 code/UI_Tag/cp.coretag
  96. +7 −0 code/UI_Tag/crypt.coretag
  97. +53 −0 code/UI_Tag/db_columns.coretag
  98. +54 −0 code/UI_Tag/db_hash.coretag
  99. +93 −0 code/UI_Tag/dbinfo.coretag
  100. +52 −0 code/UI_Tag/diff.coretag
  101. +120 −0 code/UI_Tag/diffmerge.coretag
  102. +15 −0 code/UI_Tag/directive_value.coretag
  103. +91 −0 code/UI_Tag/display.coretag
  104. +36 −0 code/UI_Tag/dump_session.coretag
  105. +8 −0 code/UI_Tag/e.coretag
  106. +37 −0 code/UI_Tag/export_database.coretag
  107. +48 −0 code/UI_Tag/file_info.coretag
  108. +312 −0 code/UI_Tag/file_navigator.coretag
  109. +59 −0 code/UI_Tag/filters.coretag
  110. +36 −0 code/UI_Tag/get_gpg_keys.coretag
  111. +9 −0 code/UI_Tag/global_value.coretag
  112. +16 −0 code/UI_Tag/grep_mm.coretag
  113. +19 −0 code/UI_Tag/if_key_exists.coretag
  114. +156 −0 code/UI_Tag/if_mm.coretag
  115. +13 −0 code/UI_Tag/if_sql.coretag
  116. +204 −0 code/UI_Tag/image_collate.coretag
  117. +275 −0 code/UI_Tag/import_fields.coretag
  118. +39 −0 code/UI_Tag/list_databases.coretag
  119. +9 −0 code/UI_Tag/list_glob.coretag
  120. +68 −0 code/UI_Tag/list_keys.coretag
  121. +19 −0 code/UI_Tag/list_pages.coretag
  122. +90 −0 code/UI_Tag/load_templates.coretag
  123. +3 −0 code/UI_Tag/meta_record.coretag
  124. +20 −0 code/UI_Tag/mm_locale.coretag
  125. +46 −0 code/UI_Tag/mm_value.coretag
  126. +30 −0 code/UI_Tag/newer.coretag
  127. +25 −0 code/UI_Tag/quick_table.coretag
  128. +268 −0 code/UI_Tag/read_page.coretag
  129. +20 −0 code/UI_Tag/read_shipping.coretag
  130. +234 −0 code/UI_Tag/read_ui_page.coretag
  131. +184 −0 code/UI_Tag/read_ui_template.coretag
  132. +22 −0 code/UI_Tag/reconfig.coretag
  133. +11 −0 code/UI_Tag/reconfig_time.coretag
  134. +21 −0 code/UI_Tag/reconfig_wait.coretag
  135. +366 −0 code/UI_Tag/regenerate.coretag
  136. +94 −0 code/UI_Tag/return_to.coretag
  137. +9 −0 code/UI_Tag/rotate_file.coretag
  138. +58 −0 code/UI_Tag/rotate_table.coretag
  139. +128 −0 code/UI_Tag/row_edit.coretag
  140. +31 −0 code/UI_Tag/run_profile.coretag
  141. +13 −0 code/UI_Tag/set_alias.coretag
  142. +106 −0 code/UI_Tag/substitute_file.coretag
  143. +1,568 −0 code/UI_Tag/table_editor.coretag
  144. +9 −0 code/UI_Tag/uneval.coretag
  145. +15 −0 code/UI_Tag/unlink_file.coretag
  146. +154 −0 code/UI_Tag/version.coretag
  147. +51 −0 code/UI_Tag/widget.coretag
  148. +3 −0 code/UI_Tag/with.coretag
  149. +103 −0 code/UI_Tag/write_page.coretag
  150. +30 −0 code/UI_Tag/write_relative_file.coretag
  151. +32 −0 code/UI_Tag/write_shipping.coretag
  152. +16 −0 code/UserTag/bar_button.tag
  153. +209 −0 code/UserTag/button.tag
  154. +66 −0 code/UserTag/convert_date.tag
  155. +32 −0 code/UserTag/db_date.tag
  156. +10 −0 code/UserTag/delete_cart.tag
  157. +47 −0 code/UserTag/email.tag
  158. +44 −0 code/UserTag/email_raw.tag
  159. +60 −0 code/UserTag/env.tag
  160. +13 −0 code/UserTag/fcounter.tag
  161. +379 −0 code/UserTag/fedex_query.tag
  162. +245 −0 code/UserTag/formel.tag
  163. +42 −0 code/UserTag/fortune.tag
  164. +31 −0 code/UserTag/get_url.tag
  165. +35 −0 code/UserTag/history_scan.tag
  166. +284 −0 code/UserTag/image.tag
  167. +17 −0 code/UserTag/load_cart.tag
  168. +25 −0 code/UserTag/loc.tag
  169. +14 −0 code/UserTag/rand.tag
  170. +37 −0 code/UserTag/save_cart.tag
  171. +35 −0 code/UserTag/summary.tag
  172. +324 −0 code/UserTag/table_organize.tag
  173. +18 −0 code/UserTag/title_bar.tag
  174. +29 −0 code/UserTag/ups_query.tag
  175. +3 −0 code/UserTag/usertrack.tag
  176. +26 −0 code/UserTag/var.tag
  177. +277 −0 code/UserTag/xml_generator.tag
  178. +770 −318 lib/Vend/Config.pm
  179. +27 −996 lib/Vend/Interpolate.pm
  180. +26 −7 lib/Vend/Order.pm
  181. +15 −570 lib/Vend/Parse.pm
  182. +19 −2 lib/Vend/Util.pm
@@ -0,0 +1,6 @@
CodeDef foo ActionMap
CodeDef foo Routine <<EOR
sub {
$CGI->{mv_nextpage} = 'aboutus';
}
EOR
@@ -0,0 +1,7 @@
CodeDef lc Filter
CodeDef lc Routine <<EOR
sub {
use locale;
return lc(shift);
}
EOR
@@ -0,0 +1,11 @@
UserTag accessories Order code arg
UserTag accessories addAttr
UserTag accessories attrAlias db table
UserTag accessories attrAlias base table
UserTag accessories attrAlias database table
UserTag accessories attrAlias col column
UserTag accessories attrAlias row code
UserTag accessories attrAlias field column
UserTag accessories attrAlias key code
UserTag accessories PosNumber 2
UserTag accessories MapRoutine Vend::Interpolate::tag_accessories
@@ -0,0 +1,7 @@
UserTag area Order href arg
UserTag area addAttr
UserTag area Implicit secure secure
UserTag area PosNumber 2
UserTag area replaceAttr form action
UserTag area replaceAttr a href
UserTag area MapRoutine Vend::Interpolate::tag_area
@@ -0,0 +1,36 @@
UserTag assign addAttr
UserTag assign PosNumber 0
UserTag assign Routine <<EOR
my %_assignable = (qw/
salestax 1
shipping 1
handling 1
subtotal 1
/);
sub {
my ($opt) = @_;
if($opt->{clear}) {
delete $Vend::Session->{assigned};
return;
}
$Vend::Session->{assigned} ||= {};
for(keys %$opt) {
next unless $_assignable{$_};
my $value = $opt->{$_};
$value =~ s/^\s+//;
$value =~ s/\s+$//;
if($value =~ /^-?\d+\.?\d*$/) {
$Vend::Session->{assigned}{$_} = $value;
}
else {
logError(
"Attempted assign of non-numeric '%s' to %s. Deleted.",
$value,
$_,
);
delete $Vend::Session->{assigned}{$_};
}
}
return;
}
EOR
@@ -0,0 +1,4 @@
UserTag attr-list Order hash
UserTag attr-list hasEndTag
UserTag attr-list PosNumber 1
UserTag attr-list MapRoutine Vend::Interpolate::tag_attr_list
@@ -0,0 +1,72 @@
UserTag banner Order category
UserTag banner addAttr
UserTag banner PosNumber 1
UserTag banner Routine <<EOR
sub {
my ($place, $opt) = @_;
sub tag_weighted_banner {
my ($category, $opt) = @_;
my $dir = catfile($Vend::Cfg->{ScratchDir}, 'Banners');
mkdir $dir, 0777 if ! -d $dir;
if($category) {
my $c = $category;
$c =~ s/\W//g;
$dir .= "/$c";
}
my $statfile = $Vend::Cfg->{ConfDir};
$statfile .= "/status.$Vend::Cat";
my $start_time;
if($opt->{once}) {
$start_time = 0;
}
elsif(! -f $statfile) {
Vend::Util::writefile( $statfile, "banners initialized " . time() . "\n");
$start_time = time();
}
else {
$start_time = (stat(_))[9];
}
my $weight_file = "$dir/total_weight";
initialize_banner_directory($dir, $category, $opt)
if (
! -f $weight_file
or
(stat(_))[9] < $start_time
);
my $n = int( rand( readfile($weight_file) ) );
return Vend::Util::readfile("$dir/$n");
}
return tag_weighted_banner($place, $opt) if $opt->{weighted};
my $table = $opt->{table} || 'banner';
my $r_field = $opt->{r_field} || 'rotate';
my $b_field = $opt->{b_field} || 'banner';
my $sep = $opt->{separator} || ':';
my $delim = $opt->{delimiter} || "{or}";
$place = 'default' if ! $place;
my $totrot;
do {
my $banner_data;
$totrot = tag_data($table, $r_field, $place);
if(! length $totrot) {
# No banner present
unless ($place =~ /$sep/ or $place eq 'default') {
$place = 'default';
redo;
}
}
elsif ($totrot) {
my $current = $::Scratch->{"rotate_$place"}++ || 0;
my $data = tag_data($table, $b_field, $place);
my(@banners) = split /\Q$delim/, $data;
return '' unless @banners;
return $banners[$current % scalar(@banners)];
}
else {
return tag_data($table, $b_field, $place);
}
} while $place =~ s/(.*)$sep.*/$1/;
return;
}
EOR
@@ -0,0 +1,3 @@
UserTag calc hasEndTag
UserTag calc Interpolate
UserTag calc MapRoutine Vend::Interpolate::tag_calc
@@ -0,0 +1,4 @@
UserTag cart Order name
UserTag cart InvalidateCache
UserTag cart PosNumber 1
UserTag cart MapRoutine Vend::Interpolate::tag_cart
@@ -0,0 +1,52 @@
UserTag catch Order label
UserTag catch addAttr
UserTag catch hasEndTag
#UserTag catch Test <<EOT
#EOT
UserTag catch Routine <<EOR
sub {
my ($label, $opt, $body) = @_;
$label = 'default' unless $label;
my $patt;
return pull_else($body)
unless $patt = $Vend::Session->{try}{$label};
$body = pull_if($body);
if ( $opt->{exact} ) {
#----------------------------------------------------------------
# Convert multiple errors to 'or' list and compile it.
# Note also the " at (eval ...)" kludge to strip the line numbers
$patt =~ s/(?: +at +\(eval .+\).+)?\n\s*/|/g;
$patt =~ s/^\s*//;
$patt =~ s/\|$//;
$patt = qr($patt);
#----------------------------------------------------------------
}
my $found;
while ($body =~ s{
\[/
(.+?)
/\]
(.*?)
\[/
(?:\1)?/?
\]}{}sx ) {
my $re;
my $error = $2;
eval {
$re = qr{$1}
};
next if $@;
next unless $patt =~ $re;
$found = $error;
last;
}
$body = $found if $found;
$body =~ s/\s+$//;
$body =~ s/^\s+//;
return $body;
}
EOR
@@ -0,0 +1,29 @@
UserTag cgi Order name
UserTag cgi addAttr
UserTag cgi InvalidateCache
UserTag cgi PosNumber 1
UserTag cgi Routine <<EOR
sub {
my($var, $opt) = @_;
my($value);
local($^W) = 0;
$CGI::values{$var} = $opt->{set} if defined $opt->{set};
$value = defined $CGI::values{$var} ? ($CGI::values{$var}) : '';
if ($value) {
# Eliminate any Interchange tags
$value =~ s~<([A-Za-z]*[^>]*\s+[Mm][Vv]\s*=\s*)~&lt;$1~g;
$value =~ s/\[/&#91;/g;
}
if($opt->{filter}) {
$value = filter_value($opt->{filter}, $value, $var);
$CGI::values{$var} = $value unless $opt->{keep};
}
return '' if $opt->{hide};
$value =~ s/</&lt;/g
unless $opt->{enable_html};
return $value;
}
EOR
@@ -0,0 +1,5 @@
UserTag charge Order route
UserTag charge addAttr
UserTag charge InvalidateCache
UserTag charge PosNumber 1
UserTag charge MapRoutine Vend::Payment::charge
@@ -0,0 +1,31 @@
UserTag checked Order name value
UserTag checked addAttr
UserTag checked Implicit multiple multiple
UserTag checked Implicit default default
UserTag checked InvalidateCache
UserTag checked PosNumber 2
UserTag checked replaceAttr input checked
UserTag checked Routine <<EOR
sub {
my ($field,$value,$opt) = @_;
$value = 'on' unless defined $value;
my $ref = $opt->{cgi} ? $CGI::values{$field} : $::Values->{$field};
return 'CHECKED' if ! length($ref) and $opt->{default};
if(! $opt->{case}) {
$ref = lc($ref);
$value = lc($value);
}
return 'CHECKED' if $ref eq $value;
if ($opt->{multiple}) {
my $regex = quotemeta $value;
return 'CHECKED' if $ref =~ /(?:^|\0)$regex(?:$|\0)/i;
}
return '';
}
EOR
@@ -0,0 +1,35 @@
UserTag control Order name default
UserTag control addAttr
UserTag control PosNumber 2
UserTag control Routine <<EOR
sub {
my ($name, $default, $opt) = @_;
use vars qw/$Tmp/;
if(! $name) {
# Here we either reset the index or increment it
# Done this way for speed, no blocks to enter other than top one
if($opt->{space}) {
$::Control = $Tmp->{$opt->{space}} ||= [];
return set_tmp('control_index', 0);
}
else {
($::Scratch->{control_index} = 0, return) if $opt->{reset};
return set_tmp('control_index', ++$::Scratch->{control_index});
}
}
$name = lc $name;
$name =~ s/-/_/g;
$opt ||= {};
if (! defined $default and $opt->{set}) {
$::Control->[$::Scratch->{control_index}]{$name} = $::Scratch->{$name};
return;
}
return defined $::Control->[$::Scratch->{control_index}]{$name}
? ( $::Control->[$::Scratch->{control_index}]{$name} || $default )
: ( length($::Scratch->{$name}) ? ($::Scratch->{$name}) : $default )
}
EOR
@@ -0,0 +1,26 @@
UserTag control-set Order index
UserTag control-set addAttr
UserTag control-set hasEndTag
UserTag control-set PosNumber 1
UserTag control-set Routine <<EOR
# Batch sets a set of controls without affecting Scratch
# Increments the index afterwards unless index is defined
sub {
my ($index, $opt, $body) = @_;
my $inc;
unless($index) {
$index = $::Scratch->{control_index} || 0;
$inc = 1;
}
while($body =~ m{\[([-\w]+)\](.*)\[/\1\]}sg) {
my $name = lc $1;
my $val = $2;
$name =~ s/-/_/g;
$::Control->[$index]{$name} = $val;
}
$::Scratch->{control_index}++;
return;
}
EOR
@@ -0,0 +1,6 @@
UserTag counter Order file
UserTag counter addAttr
UserTag counter attrAlias name file
UserTag counter InvalidateCache
UserTag counter PosNumber 1
UserTag counter MapRoutine Vend::Interpolate::tag_counter
@@ -0,0 +1,10 @@
UserTag currency Order convert noformat
UserTag currency hasEndTag
UserTag currency Interpolate
UserTag currency PosNumber 2
UserTag currency Routine <<EOR
sub {
my($convert,$noformat,$amount) = @_;
return Vend::Util::currency($amount, $noformat, $convert);
}
EOR
@@ -0,0 +1,12 @@
UserTag data Order table field key
UserTag data addAttr
UserTag data attrAlias column field
UserTag data attrAlias code key
UserTag data attrAlias base table
UserTag data attrAlias database table
UserTag data attrAlias col field
UserTag data attrAlias row key
UserTag data attrAlias name field
UserTag data Implicit increment increment
UserTag data PosNumber 3
UserTag data MapRoutine Vend::Interpolate::tag_data
@@ -0,0 +1,14 @@
UserTag default Order name default
UserTag default addAttr
UserTag default InvalidateCache
UserTag default PosNumber 2
UserTag default Routine <<EOR
# Returns the text of a user entered field named VAR.
# Same as tag [value name=name default="string"] except
# returns 'default' if not present
sub {
my($var, $default, $opt) = @_;
$opt->{default} = !(length $default) ? 'default' : $default;
return tag_value($var, $opt);
}
EOR
@@ -0,0 +1,3 @@
UserTag description Order code base
UserTag description PosNumber 2
UserTag description MapRoutine Vend::Data::product_description
Oops, something went wrong.

0 comments on commit 8f219b4

Please sign in to comment.