Index: openacs-4/packages/acs-templating/www/scripts/xinha/Makefile =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/scripts/xinha/Makefile,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/www/scripts/xinha/Makefile 18 Aug 2006 19:00:07 -0000 1.1 @@ -0,0 +1,14 @@ +FILES = *.adp *.tcl blank.html + +SOURCE = /usr/local/openacs-4/packages/acs-templating/www/resources/xinha-nightly/plugins/OacsFs/popups/ + +unlink: + rm -f ${FILES} + cp -p ${SOURCE}/*.html . + cp -p ${SOURCE}/*.adp . + cp -p ${SOURCE}/*.tcl . + +link: + ln -sf ${SOURCE}/*.html . + ln -sf ${SOURCE}/*.adp . + ln -sf ${SOURCE}/*.tcl . Index: openacs-4/packages/acs-templating/www/scripts/xinha/attach-file.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/scripts/xinha/attach-file.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/www/scripts/xinha/attach-file.adp 18 Aug 2006 19:00:07 -0000 1.1 @@ -0,0 +1,285 @@ + + + #acs-templating.HTMLArea_InsertImageTitle# + + + + + + + + + + + + +
#acs-templating.HTMLArea_InsertImageTitle# URL click here
+ + +
#acs-templating.HTMLArea_InsertImageTitle# Upload click here
+
+ + + + + + + + +
+ +
+ @HTML_UploadTitle@ + + + + + + + + + +
+ + + + + + +
@formerror.upload_file@
+

+ #acs-templating.This_image_can_be_reused_by#
+ + @formgroup.widget;noquote@ @formgroup.label@ +
+ [i] + #acs-templating.This_image_can_be_reused_help# + +
@formerror.share@
+
+
+   +
+
+
+
+
+
+
+ + + Index: openacs-4/packages/acs-templating/www/scripts/xinha/attach-file.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/scripts/xinha/attach-file.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/www/scripts/xinha/attach-file.tcl 18 Aug 2006 19:00:07 -0000 1.1 @@ -0,0 +1,145 @@ +ad_page_contract { + Simple image upload, attach image to object_id passed in, if no + object_id, use the current package_id + @author Guenter Ernst guenter.ernst@wu-wien.ac.at, + @author Gustaf Neumann neumann@wu-wien.ac.at + @author Dave Bauer (dave@solutiongrove.com) + @creation-date 13.07.2004 + @cvs-id $Id: attach-file.tcl,v 1.1 2006/08/18 19:00:07 daveb Exp $ +} { + {parent_id:integer} + {selector_type "image"} +} + +set f_url "" + +set user_id [ad_conn user_id] +# if user has write permission, create image upload form, +if {[permission::permission_p -party_id $user_id -object_id $parent_id \ + -privilege "write"]} { + + set write_p 1 + + # FIXME DAVEB i18n for share_options + set share_options [list [list "[_ acs-templating.Only_myself]" private] [list "[_ acs-templating.This_Group]" group] [list "[_ acs-templating.Anyone_on_this_system]" site] [list "[_ acs-templating.Anyone_on_the_internet]" public]] + ad_form \ + -name upload_form \ + -mode edit \ + -export {selector_type file_types parent_id} \ + -html { enctype multipart/form-data } \ + -form { + item_id:key + {upload_file:file(file) {html {size 30}} } + {share:text(radio),optional {label "[_ acs-templating.This_image_can_be_reused_by]"} {options $share_options} {help_text "[_ acs-templating.This_image_can_be_reused_help]"}} + {ok_btn:text(submit) {label "[_ acs-templating.HTMLArea_SelectUploadBtn]"} + } + } \ + -on_request { + set share site + } \ + -on_submit { + # check file name + if {$upload_file eq ""} { + template::form::set_error upload_form upload_file \ + [_ acs-templating.HTMLArea_SpecifyUploadFilename] + break + } + + # check quota + # FIXME quota is a good idea, set per-user upload quota?? +# set maximum_folder_size [ad_parameter "MaximumFolderSize"] + +# if { $maximum_folder_size ne "" } { +# set max [ad_parameter "MaximumFolderSize"] +# if { $folder_size+[file size ${upload_file.tmpfile}] > $max } { +# template::form::set_error upload_form upload_file \ + [_ file-storage.out_of_space] + # break + # } + # } + + set file_name [template::util::file::get_property filename $upload_file] + set upload_tmpfile [template::util::file::get_property tmp_filename $upload_file] + set mime_type [template::util::file::get_property mime_type $upload_file] + if {$mime_type eq ""} { + set mime_type [ns_guesstype $file_name] + } + if {$selector_type eq "image" \ + && ![string match "image/*" $mime_type]} { + template::form::set_error upload_form upload_file \ + [_ acs-templating.HTMLArea_SelectImageUploadNoImage] + break + } + if {[string match "image/*" $mime_type]} { + + image::new \ + -item_id $item_id \ + -name ${item_id}_$file_name \ + -parent_id $parent_id \ + -tmp_filename $upload_tmpfile \ + -creation_user $user_id \ + -creation_ip [ad_conn peeraddr] \ + -package_id [ad_conn package_id] + } else { + content::item::new \ + -item_id $item_id \ + -name ${item_id}_$file_name \ + -parent_id $parent_id \ + -tmp_filename $upload_tmpfile \ + -creation_user $user_id \ + -creation_ip [ad_conn peeraddr] \ + -package_id [ad_conn package_id] + } + file delete $upload_tmpfile + permission::grant \ + -object_id $item_id \ + -party_id $user_id \ + -privilege admin + + switch -- $share { + private { + permission::set_not_inherit -object_id $item_id + } + group { + # Find the closest application group + # either dotlrn or acs-subsite + + permission::grant \ + -party_id [acs_magic_object "registered_users"] \ + -object_id $item_id \ + -privilege "read" + } + public { + permission::grant \ + -party_id [acs_magic_object "the_public"] \ + -object_id $item_id \ + -privilege "read" + } + site - + default { + permission::grant \ + -party_id [acs_magic_object "registered_users"] \ + -object_id $item_id \ + -privilege "read" + } + + } + if {$share eq "private"} { + # need a private URL that allows viewers of this + # object to see the image + # this isn't totally secure, because of course + # you need to be able to see the image somehow + # but we only allow read on the image if you can + # see the parent object + set f_url "/image/$item_id/private/$file_name" + } else { + set f_url "/image/$item_id/$file_name" + } + } + +} else { + set write_p 0 +} + +set HTML_Preview "Preview" +set HTML_UploadTitle "" \ No newline at end of file Index: openacs-4/packages/acs-templating/www/scripts/xinha/blank.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/scripts/xinha/blank.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/www/scripts/xinha/blank.html 18 Aug 2006 19:00:07 -0000 1.1 @@ -0,0 +1 @@ \ No newline at end of file Index: openacs-4/packages/acs-templating/www/scripts/xinha/file-selector.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/scripts/xinha/file-selector.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/www/scripts/xinha/file-selector.adp 18 Aug 2006 19:00:07 -0000 1.1 @@ -0,0 +1,170 @@ + + + @HTML_Title@ + + + + + + + + + + +
@HTML_Title@
+
@HTML_Context@
+ +
+ @HTML_Legend@ + +
@up_name@
+
+
@folder_name@
+
+ +
+
+ + + + + + + + + + + +
+
+ @HTML_Preview@ + +
+
+ +
+ @HTML_UploadTitle@ + + + + + + + + + +
+ + + + + + +
@formerror.upload_file@
+
+
+ +
+
+
+
+
+
+ + +
+
+ + + + Index: openacs-4/packages/acs-templating/www/scripts/xinha/file-selector.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/scripts/xinha/file-selector.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/www/scripts/xinha/file-selector.tcl 18 Aug 2006 19:00:07 -0000 1.1 @@ -0,0 +1,304 @@ +ad_page_contract { + @author Guenter Ernst guenter.ernst@wu-wien.ac.at + @author Gustaf Neumann neumann@wu-wien.ac.at + @creation-date 13.10.2005 + @cvs-id $Id: file-selector.tcl,v 1.1 2006/08/18 19:00:07 daveb Exp $ +} { + {fs_package_id:integer,notnull,optional} + {folder_id:integer,optional} + {orderby:optional} + {selector_type "image"} + {file_types "*"} +} + +if {![info exists fs_package_id]} { + # we have not filestore package_id. This must be the first call. + if {[info exists folder_id]} { + # get package_id from folder_id + foreach {fs_package_id root_folder_id} \ + [fs::get_folder_package_and_root $folder_id] break + } else { + # get package_id from package name + set key file-storage + set id [apm_version_id_from_package_key $key] + set mount_url [site_node::get_children -all -package_key $key -node_id $id] + array set site_node [site_node::get -url $mount_url] + set fs_package_id $site_node(package_id) + } +} + +if {![info exists folder_id]} { + set folder_id [fs_get_root_folder -package_id $fs_package_id] + set root_folder_id $folder_id +} + +if {![fs_folder_p $folder_id]} { + ad_complain [_ file-storage.lt_The_specified_folder__1] + return +} + +# now we have at least a valid folder_id and a valid fs_package_id +if {![info exists root_folder_id]} { + set root_folder_id [fs_get_root_folder -package_id $fs_package_id] +} + +set fs_url [site_node::get_url_from_object_id -object_id $fs_package_id] + +# # Don't allow delete if root folder +set root_folder_p [expr {$folder_id == $root_folder_id}] + +set user_id [ad_conn user_id] +permission::require_permission \ + -party_id $user_id -object_id $folder_id \ + -privilege "read" + +set up_url {} + +if { !$root_folder_p} { + set parent_folder_id [fs::get_parent -item_id $folder_id] + set up_name [fs::get_object_name -object_id $parent_folder_id] + set up_url [export_vars -base file-selector \ + {fs_package_id {folder_id $parent_folder_id} + selector_type file_types}] +} + + +# if user has write permission, create image upload form, +if {[permission::permission_p -party_id $user_id -object_id $folder_id \ + -privilege "write"]} { + set write_p 1 + ad_form \ + -name upload_form \ + -mode edit \ + -export {fs_package_id folder_id orderby selector_type file_types} \ + -html { enctype multipart/form-data } \ + -form { + {upload_file:file(file) {html {size 30}} } + {ok_btn:text(submit) {label "[_ acs-templating.HTMLArea_SelectUploadBtn]"} + } + } \ + -on_submit { + # check file name + if {$upload_file eq ""} { + template::form::set_error upload_form upload_file \ + [_ acs-templating.HTMLArea_SpecifyUploadFilename] + break + } + + # check quota + set maximum_folder_size [ad_parameter "MaximumFolderSize"] + + if { $maximum_folder_size ne "" } { + set max [ad_parameter "MaximumFolderSize"] + if { $folder_size+[file size ${upload_file.tmpfile}] > $max } { + template::form::set_error upload_form upload_file \ + [_ file-storage.out_of_space] + break + } + } + + set file_name [template::util::file::get_property filename $upload_file] + set upload_tmpfile [template::util::file::get_property tmp_filename $upload_file] + set mime_type [template::util::file::get_property mime_type $upload_file] + + if {$selector_type eq "image" && ![string match "image/*" $mime_type]} { + template::form::set_error upload_form upload_file \ + [_ acs-templating.HTMLArea_SelectImageUploadNoImage] + break + } + + set existing_file_id [fs::get_item_id -name $file_name -folder_id $folder_id] + + if {$existing_file_id ne ""} { + # write new revision + fs::add_file \ + -name $file_name \ + -item_id $existing_file_id \ + -parent_id $folder_id \ + -tmp_filename $upload_tmpfile \ + -creation_user $user_id \ + -creation_ip [ad_conn peeraddr] \ + -package_id $fs_package_id + } else { + # write file + fs::add_file \ + -name $file_name \ + -parent_id $folder_id \ + -tmp_filename $upload_tmpfile \ + -creation_user $user_id \ + -creation_ip [ad_conn peeraddr] \ + -package_id $fs_package_id + } + + } +} else { + set write_p 0 +} + + +# display the contents + +set folder_name [lang::util::localize [fs::get_object_name -object_id $folder_id]] +set content_size_total 0 + +set folder_path [db_exec_plsql get_folder_path { + select content_item__get_path(:folder_id, :root_folder_id) +}] + + +# -pass_to_urls {c} + +template::list::create \ + -name contents \ + -multirow contents \ + -pass_properties {fs_package_id selector_type folder_id} \ + -key object_id \ + -html {width 100%}\ + -filters {folder_id {} file_types {} selector_type {} fs_package_id {}} \ + -elements { + name { + label "[_ file-storage.Name]" + display_template { + + + + + + + #file-storage.@contents.type@# + onclick="selectImage('@contents.object_id@','@contents.file_url@','@contents.type@');return false;">@contents.name@ + } + orderby_desc {name desc} + orderby_asc {name asc} + html {nowrap ""} + } + content_size_pretty { + label "[_ file-storage.Size]" + orderby_desc {content_size desc} + orderby_asc {content_size asc} + } + type { + label "[_ file-storage.Type]" + orderby_desc {type desc} + orderby_asc {type asc} + } + last_modified_pretty { + label "[_ file-storage.Last_Modified]" + orderby_desc {last_modified_ansi desc} + orderby_asc {last_modified_ansi asc} + html {nowrap ""} + } + } + +set order_by_clause [expr {[exists_and_not_null orderby] ? + [template::list::orderby_clause -orderby -name contents] : + " order by fs_objects.sort_key, fs_objects.name asc"}] + + +if {$selector_type eq "image"} { + set file_types "image/%" +} +set filter_clause [expr {$file_types eq "*" ? "" : + "and (type like '$file_types' or type = 'folder')" }] + +set fs_sql "select object_id, name, live_revision, type, title, + to_char(last_modified, 'YYYY-MM-DD HH24:MI:SS') as last_modified_ansi, + content_size, url, sort_key, file_upload_name, + case + when :folder_path is null + then fs_objects.name + else :folder_path || '/' || name + end as file_url, + case + when last_modified >= (now() - cast('99999' as interval)) + then 1 + else 0 + end as new_p + from fs_objects + where parent_id = :folder_id + and exists (select 1 + from acs_object_party_privilege_map m + where m.object_id = fs_objects.object_id + and m.party_id = :user_id + and m.privilege = 'read') + $filter_clause + $order_by_clause" + +db_multirow -extend { + icon last_modified_pretty content_size_pretty + properties_link properties_url folder_p title +} contents get_fs_contents $fs_sql { + set last_modified_ansi [lc_time_system_to_conn $last_modified_ansi] + set last_modified_pretty [lc_time_fmt $last_modified_ansi "%x %X"] + set content_size_pretty [lc_numeric $content_size] + + if {$type eq "folder"} { + # append content_size_pretty " [_ file-storage.items]" + set content_size_pretty "" + } else { + append content_size_pretty " [_ file-storage.bytes]" + } + if {$title eq ""} {set title $name} + + set file_upload_name [fs::remove_special_file_system_characters \ + -string $file_upload_name] + + if { $content_size ne "" } { + incr content_size_total $content_size + } + + set name [lang::util::localize $name] + + switch -- $type { + folder { + set folder_p 1 + set icon /resources/file-storage/folder.gif + set file_url [export_vars -base file-selector \ + {fs_package_id {folder_id $object_id} + selector_type file_types}] + } + url { + set folder_p 1 + set icon /resources/url-button.gif + set file_url $fs_url/$url + } + default { + set folder_p 0 + set icon /resources/file-storage/file.gif + set file_url ${fs_url}view/$file_url + } + } + + + # We need to encode the hashes in any i18n message keys (.LRN plays + # this trick on some of its folders). If we don't, the hashes will cause + # the path to be chopped off (by ns_conn url) at the leftmost hash. + regsub -all {\#} $file_url {%23} file_url +} + +set HTML_NothingSelected [_ acs-templating.HTMLArea_SelectImageNothingSelected] +switch $selector_type { + "image" { + set HTML_Title [_ acs-templating.HTMLArea_SelectImageTitle] + set HTML_Legend [_ acs-templating.HTMLArea_SelectImage] + set HTML_Preview [_ acs-templating.HTMLArea_SelectImagePreview] + set HTML_UploadTitle [_ acs-templating.HTMLArea_SelectImageUploadTitle] + set HTML_Context "COMMUNITY NAME" + } + "file" { + set HTML_Title [_ acs-templating.HTMLArea_SelectFileTitle] + set HTML_Legend [_ acs-templating.HTMLArea_SelectFile] + set HTML_Preview [_ acs-templating.HTMLArea_SelectImagePreview] + set HTML_UploadTitle [_ acs-templating.HTMLArea_SelectFileUploadTitle] + set HTML_Context "COMMUNITY NAME" + } +} + + +ad_return_template Index: openacs-4/packages/acs-templating/www/scripts/xinha/insert-file-orig.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/scripts/xinha/insert-file-orig.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/www/scripts/xinha/insert-file-orig.adp 18 Aug 2006 19:00:07 -0000 1.1 @@ -0,0 +1,273 @@ + + + #acs-templating.HTMLArea_InsertImageTitle# + + + + + + + + + + + +
#acs-templating.HTMLArea_InsertImageTitle#
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + +
#acs-templating.HTMLArea_ImageURL# + +
#acs-templating.HTMLArea_ImageAlternateText#
+
+ @HTML_Preview@ + +
+
+ +
+ @HTML_UploadTitle@ + + + + + + + + + +
+ + + + + + +
@formerror.upload_file@
+
+
+ +
+
+
+
+
+
+ + +
+
+
+

+ + + + + + +
+
+ Layout + + + + + + + + + + +
#acs-templating.HTMLArea_ImageAlignment# + +
#acs-templating.HTMLArea_ImageBorderSize#
+
+
+
+ #acs-templating.HTMLArea_ImageSpacing# + + + + + + + + + + +
#acs-templating.HTMLArea_ImageSpacingHorizontal#
#acs-templating.HTMLArea_ImageSpacingVertical#
+
+
+ + + + + + + +
+ Image Preview:
+ +
+
+ +
+

+ + + Index: openacs-4/packages/acs-templating/www/scripts/xinha/insert-ilink.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/scripts/xinha/insert-ilink.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/www/scripts/xinha/insert-ilink.adp 18 Aug 2006 19:00:07 -0000 1.1 @@ -0,0 +1,210 @@ + + + #acs-templating.HTMLArea_InsertModifyLink# + + + + + + + + + + + +
#acs-templating.HTMLArea_InsertModifyLink#
+
+
+ + + + + + + + + + + + + + + +
URL:
Title (tooltip):
Target: + + + + + + #acs-templating.HTMLArea_OpenFileStorage# + + +
  + + +
+ + + +
+ + Index: openacs-4/packages/acs-templating/www/scripts/xinha/insert-ilink.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/scripts/xinha/insert-ilink.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/www/scripts/xinha/insert-ilink.tcl 18 Aug 2006 19:00:07 -0000 1.1 @@ -0,0 +1,21 @@ +ad_page_contract { + @author Guenter Ernst guenter.ernst@wu-wien.ac.at, + @author Gustaf Neumann neumann@wu-wien.ac.at + @creation-date 13.07.2004 + @cvs-id $Id: insert-ilink.tcl,v 1.1 2006/08/18 19:00:07 daveb Exp $ +} { + {fs_package_id:integer,optional} + {folder_id:integer,optional} + {file_types *} +} + +set selector_type "file" +set file_selector_link [export_vars -base file-selector \ + {fs_package_id folder_id selector_type file_types}] +set fs_found 1 + +#set user_id [ad_verify_and_get_user_id] +#permission::require_permission -party_id $user_id -object_id $fs_package_id \ +# -privilege "admin" + +ad_return_template Index: openacs-4/packages/acs-templating/www/scripts/xinha/insert-image.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/scripts/xinha/insert-image.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/www/scripts/xinha/insert-image.adp 18 Aug 2006 19:00:07 -0000 1.1 @@ -0,0 +1,235 @@ + + + #acs-templating.HTMLArea_InsertImageTitle# + + + + + + + + + + + +
#acs-templating.HTMLArea_InsertImageTitle#
+ +
+ +
+ + + + + + + + + + + + + + +
#acs-templating.HTMLArea_ImageURL# + +
#acs-templating.HTMLArea_ImageAlternateText#
+ + + + + #acs-templating.HTMLArea_OpenFileStorage# +
+
+

+ + + + + + +
+
+ Layout + + + + + + + + + + +
#acs-templating.HTMLArea_ImageAlignment# + +
#acs-templating.HTMLArea_ImageBorderSize#
+
+
+
+ #acs-templating.HTMLArea_ImageSpacing# + + + + + + + + + + +
#acs-templating.HTMLArea_ImageSpacingHorizontal#
#acs-templating.HTMLArea_ImageSpacingVertical#
+
+
+ + + + + + + +
+ Image Preview:
+ +
+
+ +
+

+ + + Index: openacs-4/packages/acs-templating/www/scripts/xinha/insert-image.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/scripts/xinha/insert-image.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/www/scripts/xinha/insert-image.tcl 18 Aug 2006 19:00:07 -0000 1.1 @@ -0,0 +1,14 @@ +ad_page_contract { + @author Guenter Ernst guenter.ernst@wu-wien.ac.at, + @author Gustaf Neumann neumann@wu-wien.ac.at + @creation-date 13.07.2004 + @cvs-id $Id: insert-image.tcl,v 1.1 2006/08/18 19:00:07 daveb Exp $ +} { + {fs_package_id:integer,optional} + {folder_id:integer,optional} +} + +set selector_type "image" +set file_selector_link [export_vars -base file-selector \ + {fs_package_id folder_id selector_type}] +set fs_found 1 Index: openacs-4/packages/acs-templating/www/scripts/xinha/insert_image.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/scripts/xinha/insert_image.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/www/scripts/xinha/insert_image.html 18 Aug 2006 19:00:07 -0000 1.1 @@ -0,0 +1,172 @@ + + + + Insert Image + + + + + + + + + + +
Insert Image
+ +
+ + + + + + + + + + + + + +
Image URL: + +
Alternate text:
+ +

+ +

+Layout + +
+ +
Alignment:
+ + +

+ +

Border thickness:
+ + +
+ +
+ +
+Spacing + +
+ +
Horizontal:
+ + +

+ +

Vertical:
+ + +
+ +
+
+ + + + + +
+
Image Preview:
+ +
+
+ +
+
+ + \ No newline at end of file