From fed890a26adc5886224f1b463edec169e40a5be6 Mon Sep 17 00:00:00 2001 From: david Date: Wed, 9 Mar 2011 18:42:43 +0000 Subject: [PATCH] MatchForm 2.3 original git-svn-id: https://192.168.0.254/svn/Proyectos.Incam_FormulariosCalidad/trunk@1 e2c41b2c-0c6f-0149-8b81-50b1a9191bb3 --- INSTALL.TXT | 16 + ajax_form_activation.php | 34 + blank.gif | Bin 0 -> 49 bytes captcha.php | 20 + changelog.txt | 146 + columns_preference.php | 283 ++ config-empty.php | 59 + confirm.php | 72 + confirm_embed.php | 68 + css/blank.gif | Bin 0 -> 49 bytes css/email_entry.css | 47 + css/email_entry_ie.css | 18 + css/entry_print.css | 52 + css/iepngfix.htc | 68 + css/jquery-tabs.css | 107 + data/.htaccess | 16 + delete_element.php | 118 + delete_element_option.php | 50 + download.php | 141 + edit_css.php | 82 + edit_entry.css | 837 ++++ edit_entry.php | 203 + edit_form.php | 721 ++++ email_entry.php | 127 + email_settings.css | 539 +++ email_settings.php | 526 +++ embed.php | 94 + embed_code.php | 159 + export_entries.php | 417 ++ hooks/custom_hooks.php | 26 + images/ap_bg.gif | Bin 0 -> 49 bytes images/appnitro_logo.png | Bin 0 -> 3760 bytes images/bottom.png | Bin 0 -> 431 bytes images/button_icon/address_bg.gif | Bin 0 -> 1252 bytes images/button_icon/checkbox_bg.gif | Bin 0 -> 1079 bytes images/button_icon/date_bg.gif | Bin 0 -> 1211 bytes images/button_icon/dropdown_bg.gif | Bin 0 -> 1234 bytes images/button_icon/file_upload_bg.gif | Bin 0 -> 1244 bytes images/button_icon/mail_bg.gif | Bin 0 -> 1162 bytes images/button_icon/multiplechoice_bg.gif | Bin 0 -> 379 bytes images/button_icon/name_bg.gif | Bin 0 -> 1169 bytes images/button_icon/number_bg.gif | Bin 0 -> 1088 bytes images/button_icon/paragraph_text_bg.gif | Bin 0 -> 458 bytes images/button_icon/phone_bg.gif | Bin 0 -> 1064 bytes images/button_icon/price_bg.gif | Bin 0 -> 581 bytes images/button_icon/section_break_bg.gif | Bin 0 -> 637 bytes images/button_icon/single_line_text_bg.gif | Bin 0 -> 372 bytes images/button_icon/time_bg.gif | Bin 0 -> 1277 bytes images/button_icon/website_bg.gif | Bin 0 -> 1322 bytes images/button_text/address.gif | Bin 0 -> 546 bytes images/button_text/checkboxes.gif | Bin 0 -> 638 bytes images/button_text/date.gif | Bin 0 -> 448 bytes images/button_text/drop_down.gif | Bin 0 -> 576 bytes images/button_text/email.gif | Bin 0 -> 456 bytes images/button_text/file_upload.gif | Bin 0 -> 590 bytes images/button_text/multiple_choice.gif | Bin 0 -> 688 bytes images/button_text/name.gif | Bin 0 -> 474 bytes images/button_text/number.gif | Bin 0 -> 509 bytes images/button_text/paragraph_text.gif | Bin 0 -> 691 bytes images/button_text/phone.gif | Bin 0 -> 478 bytes images/button_text/price.gif | Bin 0 -> 462 bytes images/button_text/section_break.gif | Bin 0 -> 671 bytes images/button_text/single_line_text.gif | Bin 0 -> 697 bytes images/button_text/time.gif | Bin 0 -> 437 bytes images/button_text/web_site.gif | Bin 0 -> 579 bytes images/calendar.gif | Bin 0 -> 634 bytes images/click_to_add.gif | Bin 0 -> 1007 bytes images/create_new_form.gif | Bin 0 -> 1395 bytes images/embed_code_tabs.gif | Bin 0 -> 381 bytes images/exec.png | Bin 0 -> 1444 bytes images/icons/add.gif | Bin 0 -> 610 bytes images/icons/agt_family_48.gif | Bin 0 -> 959 bytes images/icons/agt_utilities.gif | Bin 0 -> 308 bytes images/icons/agt_utilities.png | Bin 0 -> 3624 bytes images/icons/application_edit.gif | Bin 0 -> 624 bytes images/icons/arrow.gif | Bin 0 -> 654 bytes images/icons/arrow_left.gif | Bin 0 -> 660 bytes images/icons/arrow_right.gif | Bin 0 -> 201 bytes images/icons/arrow_turn_left.gif | Bin 0 -> 224 bytes images/icons/asterisk_orange.gif | Bin 0 -> 1019 bytes images/icons/attach.gif | Bin 0 -> 560 bytes images/icons/calendar.gif | Bin 0 -> 634 bytes images/icons/checkbox.gif | Bin 0 -> 668 bytes images/icons/checkbox_16.gif | Bin 0 -> 564 bytes images/icons/cog.gif | Bin 0 -> 311 bytes images/icons/colorize_32.gif | Bin 0 -> 1110 bytes images/icons/copy_32.gif | Bin 0 -> 556 bytes images/icons/cross.gif | Bin 0 -> 1130 bytes images/icons/cross_16.gif | Bin 0 -> 644 bytes images/icons/cross_22.gif | Bin 0 -> 405 bytes images/icons/date.gif | Bin 0 -> 291 bytes images/icons/decrypted.gif | Bin 0 -> 751 bytes images/icons/delete.gif | Bin 0 -> 606 bytes images/icons/disabled.gif | Bin 0 -> 816 bytes images/icons/duplicate.gif | Bin 0 -> 636 bytes images/icons/edit_form_32.gif | Bin 0 -> 1094 bytes images/icons/edit_user.gif | Bin 0 -> 744 bytes images/icons/edit_user_48.gif | Bin 0 -> 516 bytes images/icons/embed_code_32.gif | Bin 0 -> 715 bytes images/icons/entries_32.gif | Bin 0 -> 932 bytes images/icons/fileprint.gif | Bin 0 -> 379 bytes images/icons/filesave.gif | Bin 0 -> 633 bytes images/icons/flag_green.gif | Bin 0 -> 268 bytes images/icons/flag_red.gif | Bin 0 -> 265 bytes images/icons/flag_red.png | Bin 0 -> 665 bytes images/icons/form_add.gif | Bin 0 -> 609 bytes images/icons/information.gif | Bin 0 -> 624 bytes images/icons/kate.gif | Bin 0 -> 379 bytes images/icons/key.gif | Bin 0 -> 586 bytes images/icons/lock.gif | Bin 0 -> 1091 bytes images/icons/locksmall.gif | Bin 0 -> 991 bytes images/icons/magnifier.gif | Bin 0 -> 246 bytes images/icons/mail_forward_16.gif | Bin 0 -> 305 bytes images/icons/mail_forward_16.png | Bin 0 -> 1052 bytes images/icons/mail_forward_32.gif | Bin 0 -> 652 bytes images/icons/mail_generic2.gif | Bin 0 -> 390 bytes images/icons/mail_reply_16.gif | Bin 0 -> 302 bytes images/icons/mail_reply_16.png | Bin 0 -> 1061 bytes images/icons/nav_end.gif | Bin 0 -> 597 bytes images/icons/nav_end_grey.gif | Bin 0 -> 642 bytes images/icons/nav_next.gif | Bin 0 -> 587 bytes images/icons/nav_next_grey.gif | Bin 0 -> 607 bytes images/icons/nav_prev.gif | Bin 0 -> 589 bytes images/icons/nav_prev_grey.gif | Bin 0 -> 616 bytes images/icons/nav_start.gif | Bin 0 -> 594 bytes images/icons/nav_start_grey.gif | Bin 0 -> 659 bytes images/icons/package_applications.gif | Bin 0 -> 1198 bytes images/icons/page_excel.gif | Bin 0 -> 650 bytes images/icons/page_white_code.gif | Bin 0 -> 610 bytes images/icons/pencil.gif | Bin 0 -> 536 bytes images/icons/resultset_down.gif | Bin 0 -> 300 bytes images/icons/resultset_next.gif | Bin 0 -> 303 bytes images/icons/resultset_up.gif | Bin 0 -> 300 bytes images/icons/search.gif | Bin 0 -> 331 bytes images/icons/show_table_column.gif | Bin 0 -> 229 bytes images/icons/star.gif | Bin 0 -> 994 bytes images/icons/stardim.gif | Bin 0 -> 994 bytes images/icons/start.png | Bin 0 -> 1629 bytes images/icons/stop.gif | Bin 0 -> 802 bytes images/icons/textfield_add.gif | Bin 0 -> 132 bytes images/icons/view_form_32.gif | Bin 0 -> 994 bytes images/icons/warning.gif | Bin 0 -> 262 bytes images/input_bg.gif | Bin 0 -> 435 bytes images/loader-red.gif | Bin 0 -> 673 bytes images/logout.gif | Bin 0 -> 1139 bytes images/machform.gif | Bin 0 -> 666 bytes images/manage_forms.gif | Bin 0 -> 696 bytes images/manage_forms_active.gif | Bin 0 -> 1273 bytes images/reports.gif | Bin 0 -> 518 bytes images/reports_active.gif | Bin 0 -> 368 bytes images/settings.gif | Bin 0 -> 549 bytes images/settings_active.gif | Bin 0 -> 397 bytes images/shadow.gif | Bin 0 -> 46 bytes images/simple_modal/ajax-loader.gif | Bin 0 -> 1924 bytes images/simple_modal/cancel.png | Bin 0 -> 3224 bytes images/simple_modal/form_bottom.gif | Bin 0 -> 140 bytes images/simple_modal/form_top.gif | Bin 0 -> 140 bytes images/simple_modal/form_top_ie.gif | Bin 0 -> 996 bytes images/simple_modal/send.png | Bin 0 -> 3200 bytes images/top.png | Bin 0 -> 417 bytes includes/JSON.php | 806 ++++ includes/check-session.php | 27 + includes/common-validator.php | 420 ++ includes/db-core.php | 27 + includes/db-functions.php | 237 ++ includes/entry-functions.php | 487 +++ includes/filter-functions.php | 44 + includes/footer.php | 12 + includes/header.php | 37 + includes/helper-functions.php | 514 +++ includes/language.php | 96 + includes/post-functions.php | 2328 +++++++++++ includes/view-functions.php | 2495 ++++++++++++ index.css | 1236 ++++++ index.php | 104 + installer.php | 345 ++ js/base.js | 2993 ++++++++++++++ js/calendar.js | 2058 ++++++++++ js/email_entry.js | 305 ++ js/jquery/jquery-columnhover.js | 200 + js/jquery/jquery-core.js | 32 + js/jquery/jquery-simplemodal.js | 16 + js/jquery/jquery-tabs.js | 515 +++ js/machform.js | 1 + js/rico.js | 402 ++ js/view.js | 1 + lib/class.phpmailer.php | 1896 +++++++++ lib/class.smtp.php | 1062 +++++ .../Compat/Function/file_put_contents.php | 107 + lib/pear/Compat/Function/fputcsv.php | 55 + lib/pear/OLE/OLE.php | 410 ++ lib/pear/OLE/PPS.php | 219 ++ lib/pear/OLE/PPS/File.php | 114 + lib/pear/OLE/PPS/Root.php | 519 +++ lib/pear/PEAR.php | 1108 ++++++ lib/pear/Spreadsheet/Excel/Writer.php | 104 + .../Spreadsheet/Excel/Writer/BIFFwriter.php | 238 ++ lib/pear/Spreadsheet/Excel/Writer/Format.php | 1102 ++++++ lib/pear/Spreadsheet/Excel/Writer/Parser.php | 1689 ++++++++ .../Spreadsheet/Excel/Writer/Validator.php | 230 ++ .../Spreadsheet/Excel/Writer/Workbook.php | 1627 ++++++++ .../Spreadsheet/Excel/Writer/Worksheet.php | 3502 +++++++++++++++++ lib/php-captcha/VeraBd.ttf | Bin 0 -> 58716 bytes lib/php-captcha/VeraSeBd.ttf | Bin 0 -> 58736 bytes lib/php-captcha/php-captcha.inc.php | 407 ++ lib/phpmailer.lang-en.php | 25 + lib/recaptchalib.php | 280 ++ license.txt | 1 + logout.php | 25 + machform.php | 242 ++ manage_entries.php | 628 +++ manage_form.php | 682 ++++ save.php | 474 +++ template_variables.php | 149 + upgrade.php | 416 ++ view.css | 936 +++++ view.php | 92 + view_entry.php | 221 ++ 218 files changed, 39344 insertions(+) create mode 100644 INSTALL.TXT create mode 100644 ajax_form_activation.php create mode 100644 blank.gif create mode 100644 captcha.php create mode 100644 changelog.txt create mode 100644 columns_preference.php create mode 100644 config-empty.php create mode 100644 confirm.php create mode 100644 confirm_embed.php create mode 100644 css/blank.gif create mode 100644 css/email_entry.css create mode 100644 css/email_entry_ie.css create mode 100644 css/entry_print.css create mode 100644 css/iepngfix.htc create mode 100644 css/jquery-tabs.css create mode 100644 data/.htaccess create mode 100644 delete_element.php create mode 100644 delete_element_option.php create mode 100644 download.php create mode 100644 edit_css.php create mode 100644 edit_entry.css create mode 100644 edit_entry.php create mode 100644 edit_form.php create mode 100644 email_entry.php create mode 100644 email_settings.css create mode 100644 email_settings.php create mode 100644 embed.php create mode 100644 embed_code.php create mode 100644 export_entries.php create mode 100644 hooks/custom_hooks.php create mode 100644 images/ap_bg.gif create mode 100644 images/appnitro_logo.png create mode 100644 images/bottom.png create mode 100644 images/button_icon/address_bg.gif create mode 100644 images/button_icon/checkbox_bg.gif create mode 100644 images/button_icon/date_bg.gif create mode 100644 images/button_icon/dropdown_bg.gif create mode 100644 images/button_icon/file_upload_bg.gif create mode 100644 images/button_icon/mail_bg.gif create mode 100644 images/button_icon/multiplechoice_bg.gif create mode 100644 images/button_icon/name_bg.gif create mode 100644 images/button_icon/number_bg.gif create mode 100644 images/button_icon/paragraph_text_bg.gif create mode 100644 images/button_icon/phone_bg.gif create mode 100644 images/button_icon/price_bg.gif create mode 100644 images/button_icon/section_break_bg.gif create mode 100644 images/button_icon/single_line_text_bg.gif create mode 100644 images/button_icon/time_bg.gif create mode 100644 images/button_icon/website_bg.gif create mode 100644 images/button_text/address.gif create mode 100644 images/button_text/checkboxes.gif create mode 100644 images/button_text/date.gif create mode 100644 images/button_text/drop_down.gif create mode 100644 images/button_text/email.gif create mode 100644 images/button_text/file_upload.gif create mode 100644 images/button_text/multiple_choice.gif create mode 100644 images/button_text/name.gif create mode 100644 images/button_text/number.gif create mode 100644 images/button_text/paragraph_text.gif create mode 100644 images/button_text/phone.gif create mode 100644 images/button_text/price.gif create mode 100644 images/button_text/section_break.gif create mode 100644 images/button_text/single_line_text.gif create mode 100644 images/button_text/time.gif create mode 100644 images/button_text/web_site.gif create mode 100644 images/calendar.gif create mode 100644 images/click_to_add.gif create mode 100644 images/create_new_form.gif create mode 100644 images/embed_code_tabs.gif create mode 100644 images/exec.png create mode 100644 images/icons/add.gif create mode 100644 images/icons/agt_family_48.gif create mode 100644 images/icons/agt_utilities.gif create mode 100644 images/icons/agt_utilities.png create mode 100644 images/icons/application_edit.gif create mode 100644 images/icons/arrow.gif create mode 100644 images/icons/arrow_left.gif create mode 100644 images/icons/arrow_right.gif create mode 100644 images/icons/arrow_turn_left.gif create mode 100644 images/icons/asterisk_orange.gif create mode 100644 images/icons/attach.gif create mode 100644 images/icons/calendar.gif create mode 100644 images/icons/checkbox.gif create mode 100644 images/icons/checkbox_16.gif create mode 100644 images/icons/cog.gif create mode 100644 images/icons/colorize_32.gif create mode 100644 images/icons/copy_32.gif create mode 100644 images/icons/cross.gif create mode 100644 images/icons/cross_16.gif create mode 100644 images/icons/cross_22.gif create mode 100644 images/icons/date.gif create mode 100644 images/icons/decrypted.gif create mode 100644 images/icons/delete.gif create mode 100644 images/icons/disabled.gif create mode 100644 images/icons/duplicate.gif create mode 100644 images/icons/edit_form_32.gif create mode 100644 images/icons/edit_user.gif create mode 100644 images/icons/edit_user_48.gif create mode 100644 images/icons/embed_code_32.gif create mode 100644 images/icons/entries_32.gif create mode 100644 images/icons/fileprint.gif create mode 100644 images/icons/filesave.gif create mode 100644 images/icons/flag_green.gif create mode 100644 images/icons/flag_red.gif create mode 100644 images/icons/flag_red.png create mode 100644 images/icons/form_add.gif create mode 100644 images/icons/information.gif create mode 100644 images/icons/kate.gif create mode 100644 images/icons/key.gif create mode 100644 images/icons/lock.gif create mode 100644 images/icons/locksmall.gif create mode 100644 images/icons/magnifier.gif create mode 100644 images/icons/mail_forward_16.gif create mode 100644 images/icons/mail_forward_16.png create mode 100644 images/icons/mail_forward_32.gif create mode 100644 images/icons/mail_generic2.gif create mode 100644 images/icons/mail_reply_16.gif create mode 100644 images/icons/mail_reply_16.png create mode 100644 images/icons/nav_end.gif create mode 100644 images/icons/nav_end_grey.gif create mode 100644 images/icons/nav_next.gif create mode 100644 images/icons/nav_next_grey.gif create mode 100644 images/icons/nav_prev.gif create mode 100644 images/icons/nav_prev_grey.gif create mode 100644 images/icons/nav_start.gif create mode 100644 images/icons/nav_start_grey.gif create mode 100644 images/icons/package_applications.gif create mode 100644 images/icons/page_excel.gif create mode 100644 images/icons/page_white_code.gif create mode 100644 images/icons/pencil.gif create mode 100644 images/icons/resultset_down.gif create mode 100644 images/icons/resultset_next.gif create mode 100644 images/icons/resultset_up.gif create mode 100644 images/icons/search.gif create mode 100644 images/icons/show_table_column.gif create mode 100644 images/icons/star.gif create mode 100644 images/icons/stardim.gif create mode 100644 images/icons/start.png create mode 100644 images/icons/stop.gif create mode 100644 images/icons/textfield_add.gif create mode 100644 images/icons/view_form_32.gif create mode 100644 images/icons/warning.gif create mode 100644 images/input_bg.gif create mode 100644 images/loader-red.gif create mode 100644 images/logout.gif create mode 100644 images/machform.gif create mode 100644 images/manage_forms.gif create mode 100644 images/manage_forms_active.gif create mode 100644 images/reports.gif create mode 100644 images/reports_active.gif create mode 100644 images/settings.gif create mode 100644 images/settings_active.gif create mode 100644 images/shadow.gif create mode 100644 images/simple_modal/ajax-loader.gif create mode 100644 images/simple_modal/cancel.png create mode 100644 images/simple_modal/form_bottom.gif create mode 100644 images/simple_modal/form_top.gif create mode 100644 images/simple_modal/form_top_ie.gif create mode 100644 images/simple_modal/send.png create mode 100644 images/top.png create mode 100644 includes/JSON.php create mode 100644 includes/check-session.php create mode 100644 includes/common-validator.php create mode 100644 includes/db-core.php create mode 100644 includes/db-functions.php create mode 100644 includes/entry-functions.php create mode 100644 includes/filter-functions.php create mode 100644 includes/footer.php create mode 100644 includes/header.php create mode 100644 includes/helper-functions.php create mode 100644 includes/language.php create mode 100644 includes/post-functions.php create mode 100644 includes/view-functions.php create mode 100644 index.css create mode 100644 index.php create mode 100644 installer.php create mode 100644 js/base.js create mode 100644 js/calendar.js create mode 100644 js/email_entry.js create mode 100644 js/jquery/jquery-columnhover.js create mode 100644 js/jquery/jquery-core.js create mode 100644 js/jquery/jquery-simplemodal.js create mode 100644 js/jquery/jquery-tabs.js create mode 100644 js/machform.js create mode 100644 js/rico.js create mode 100644 js/view.js create mode 100644 lib/class.phpmailer.php create mode 100644 lib/class.smtp.php create mode 100644 lib/pear/Compat/Function/file_put_contents.php create mode 100644 lib/pear/Compat/Function/fputcsv.php create mode 100644 lib/pear/OLE/OLE.php create mode 100644 lib/pear/OLE/PPS.php create mode 100644 lib/pear/OLE/PPS/File.php create mode 100644 lib/pear/OLE/PPS/Root.php create mode 100644 lib/pear/PEAR.php create mode 100644 lib/pear/Spreadsheet/Excel/Writer.php create mode 100644 lib/pear/Spreadsheet/Excel/Writer/BIFFwriter.php create mode 100644 lib/pear/Spreadsheet/Excel/Writer/Format.php create mode 100644 lib/pear/Spreadsheet/Excel/Writer/Parser.php create mode 100644 lib/pear/Spreadsheet/Excel/Writer/Validator.php create mode 100644 lib/pear/Spreadsheet/Excel/Writer/Workbook.php create mode 100644 lib/pear/Spreadsheet/Excel/Writer/Worksheet.php create mode 100644 lib/php-captcha/VeraBd.ttf create mode 100644 lib/php-captcha/VeraSeBd.ttf create mode 100644 lib/php-captcha/php-captcha.inc.php create mode 100644 lib/phpmailer.lang-en.php create mode 100644 lib/recaptchalib.php create mode 100644 license.txt create mode 100644 logout.php create mode 100644 machform.php create mode 100644 manage_entries.php create mode 100644 manage_form.php create mode 100644 save.php create mode 100644 template_variables.php create mode 100644 upgrade.php create mode 100644 view.css create mode 100644 view.php create mode 100644 view_entry.php diff --git a/INSTALL.TXT b/INSTALL.TXT new file mode 100644 index 0000000..8e309da --- /dev/null +++ b/INSTALL.TXT @@ -0,0 +1,16 @@ +INSTALLATION +============ + +For the most up to date installation instructions go to: + +http://www.appnitro.com/machform/installation + + + + +UPGRADING +========= + +If you are upgrading from version 1.2 to version 2 go to: + +http://www.appnitro.com/machform/upgrade_instructions \ No newline at end of file diff --git a/ajax_form_activation.php b/ajax_form_activation.php new file mode 100644 index 0000000..cd6fa01 --- /dev/null +++ b/ajax_form_activation.php @@ -0,0 +1,34 @@ + \ No newline at end of file diff --git a/blank.gif b/blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..75b945d2553848b8b6f41fe5e24599c0687b8472 GIT binary patch literal 49 zcmZ?wbhEHbWMp7unE0RJ|Ns9C3=9Vj8~~DvKUo+V7?>DzfNY>Fh|Ltj$Y2csQN9XW literal 0 HcmV?d00001 diff --git a/captcha.php b/captcha.php new file mode 100644 index 0000000..6c05630 --- /dev/null +++ b/captcha.php @@ -0,0 +1,20 @@ +Create(); + +?> \ No newline at end of file diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000..bae8b9c --- /dev/null +++ b/changelog.txt @@ -0,0 +1,146 @@ +MachForm Changelog +================== + +=============================== +VERSION 1.2 - 15 September 2007 +=============================== +* New feature: added CAPTCHA for spam protection +* New feature: added panel to embed form code +* Bugfix on entry manager, column header didn't escape newlines, this break the whole extjs grid javascript +* Bugfix on excel export for UTF-8 encoding +* Bugfix on email name saving +* Bugfix on today's entry counter +* Bugfix on domain guessing for mail +* Bugfix on mkdir umask +* Bugfix on redirect for iframe +* Enhanchement on entry manager, provided a constant to limit the maximum columns to be displayed, large forms tend to be slower +* Expand last used tab on form manager + +=============================== +VERSION 1.2.b - 4 November 2007 +=============================== +* Bugfix on form submission anchor, it does not go to the top of the page where the error message is. +* Bugfix on export to excel. temporary folder wasn't explicitly configured, causing problem to some. +* Bugfix on email field ordering +* Bugfix on export to excel. header ordering. + +=============================== +VERSION 1.2.c - 15 November 2007 +=============================== +* Bugfix on export to excel. unexpected repeated data. + +=============================== +VERSION 1.2.d - 28 November 2007 +=============================== +* Bugfix on export to excel. header ordering fix somehow missed from the previous release. + +=============================== +VERSION 1.2.e - 20 February 2008 +=============================== +* Small bugfix on CSS for IE7. + +=============================== +VERSION 1.2.f - 25 February 2008 +=============================== +* Bugfix on section break. Shouldn't be displayed on email. +* Bugfix on checkbox with only one option. Doesn't displayed on email and exported files. + +=============================== +VERSION 2.0 - 28 April 2008 +=============================== +* New feature: added email autoresponder control panel +* New feature: new html email design +* New feature: fully customizable email template +* New feature: revamped entry manager +* New feature: added email autoresponder control panel +* New feature: entry viewer +* New feature: printer friendly version of an entry +* New feature: forward an entry to email +* New feature: form submission review page +* New feature: full PHP embed code +* New feature: built-in CAPTCHA +* New feature: added language file for easy translation +* New feature: form duplication +* Improved navigation +* SSL Support +* Numerous minor bugfixes + +=============================== +VERSION 2.0.b - 30 April 2008 +=============================== +* Bugfix on quotes not displayed properly in email +* Bugfix on form redirect not being sent properly + +=============================== +VERSION 2.0.c - 1 May 2008 +=============================== +* Bugfix on calendar javascript doesn't loaded properly for DD-MM-YYYY +* Improvement: full UTF-8 encoding in MySQL table + +=============================== +VERSION 2.0.d - 5 May 2008 +=============================== +* Bugfix on website validation. + +=============================== +VERSION 2.0.e - 7 May 2008 +=============================== +* Added charset header to config file, to force UTF-8 encoding. + +=============================== +VERSION 2.0.f - 21 May 2008 +=============================== +* Typo in template variables page for {form_data}. Should be {entry_data}. +* Added translation into language file for review page buttons. +* Bugfix: Checkboxes trimming 'b' and 'r' characters at the end of the label. +* Bugfix: Email validation doesn't allow single character domain. +* Bugfix: Updating checkboxes more than 10 options caused error. +* Bugfix: When deleting fields, column preference for that field should be removed. +* Bugfix: Saving large form on PHP 5.2.x sometimes doesn't work. + +=============================== +VERSION 2.0.g - 16 June 2008 +=============================== +* Bugfix: Using advanced form code, Enter key won't submit password form in IE7. +* Bugfix: Form redirect is not being sent properly when using advanced form code. +* Bugfix: IE7 reject CAPTCHA cookies when using iframe code. +* Bugfix: IE7 reject session cookies for form review. + +=============================== +VERSION 2.1 - 11 November 2008 +=============================== +* PHPMailer library upgrade. Now support secure SMTP (TLS/SSL). +* Added UPLOAD_DIR into config file, to separate upload folder with data folder. +* Added file upload type checking. +* Added random token to file upload, increased security. +* Added default .htaccess file, increased security. +* Bugfix: Zero values are not displayed properly on review page and email. +* Bugfix: Dropdowns and checkboxes are having maximum value of 255. +* Bugfix: '0' values are not being saved for dropdown/multiple choices +* Bugfix: Uploading file with quotes doesn't work properly. +* Bugfix: Download link in exported excel file doesn't work properly. + +=============================== +VERSION 2.1.b - 13 November 2008 +=============================== +* Bugfix: .htaccess file caused error on some server. + +=============================== +VERSION 2.2 - 15 May 2009 +=============================== +* Bugfix: Uploaded files are having broken link in the email when the form is using advanced form code. +* Bugfix: File upload type shouldn't be checked if the field is not required and left empty. +* Bugfix: Apostrophe causing error for field being set as unique. +* Bugfix: Editing empty date/time field within the admin causing error value for those fields. +* Bugfix: Checkboxes doesn't completely exported after some options being deleted. +* Bugfix: Linebreak doesn't displayed properly on field labels or section break. + +=============================== +VERSION 2.3 - 24 March 2010 +=============================== +* Bugfix: Double linebreak within form description. +* Bugfix: Linebreak within excel causing weird ascii characters. +* Bugfix: Excess head tag at review page when using the advanced form code. +* Bugfix: Uploading file with quotes doesn't work properly when form review being enabled. +* Bugfix: Required file upload field doesn't validate properly when form review enabled and back button pressed. +* Bugfix: Removed any deprecated messages within form view, form editor and excel export due to PHP 5.3 new rules. \ No newline at end of file diff --git a/columns_preference.php b/columns_preference.php new file mode 100644 index 0000000..a475bfb --- /dev/null +++ b/columns_preference.php @@ -0,0 +1,283 @@ +$element_name){ + do_query("insert into `ap_column_preferences`(form_id,element_name,position) values('{$form_id}','{$element_name}','{$position}')"); + } + + $_SESSION['AP_SUCCESS']['title'] = 'Success'; + $_SESSION['AP_SUCCESS']['desc'] = 'Columns preference successfully saved.'; + + header("Location: manage_entries.php?id={$form_id}"); + exit; + }else{ + $_SESSION['AP_ERROR']['title'] = 'An error occured while saving'; + $_SESSION['AP_ERROR']['desc'] = 'Please select at least one column.'; + } + } + + //get form name + $query = "select form_name from `ap_forms` where form_id='$form_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + $form_name = $row['form_name']; + + //get form element options + $query = "select element_id,option_id,`option` from ap_element_options where form_id='$form_id' and live=1 order by element_id,option_id asc"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $option_id = $row['option_id']; + + //limit the data length + if(strlen($row['option']) > MAX_TITLE_LENGTH){ + $element_option_lookup[$element_id][$option_id] = htmlspecialchars(substr($row['option'],0,MAX_TITLE_LENGTH),ENT_QUOTES); + }else{ + $element_option_lookup[$element_id][$option_id] = htmlspecialchars($row['option'],ENT_QUOTES); + } + } + + /******************************************************************************************/ + //prepare column header names lookup + $query = "select element_id,element_title,element_type,element_constraint from `ap_form_elements` where form_id='$form_id' and element_type != 'section' order by element_position asc"; + $result = do_query($query); + + $column_name_lookup['date_created'] = 'Date Created'; + $column_name_lookup['date_updated'] = 'Date Updated'; + $column_name_lookup['ip_address'] = 'IP Address'; + + while($row = do_fetch_result($result)){ + $element_type = $row['element_type']; + $element_constraint = $row['element_constraint']; + + //limit the title length + if(strlen($row['element_title']) > MAX_TITLE_LENGTH){ + $row['element_title'] = substr($row['element_title'],0,MAX_TITLE_LENGTH); + } + + $row['element_title'] = htmlspecialchars($row['element_title']); + + if('address' == $element_type){ //address has 6 fields + $column_name_lookup['element_'.$row['element_id'].'_1'] = $row['element_title'].' - Street Address'; + $column_name_lookup['element_'.$row['element_id'].'_2'] = 'Address Line 2'; + $column_name_lookup['element_'.$row['element_id'].'_3'] = 'City'; + $column_name_lookup['element_'.$row['element_id'].'_4'] = 'State/Province/Region'; + $column_name_lookup['element_'.$row['element_id'].'_5'] = 'Zip/Postal Code'; + $column_name_lookup['element_'.$row['element_id'].'_6'] = 'Country'; + + $column_type_lookup['element_'.$row['element_id'].'_1'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_2'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_3'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_4'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_5'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_6'] = $row['element_type']; + + }elseif ('simple_name' == $element_type){ //simple name has 2 fields + $column_name_lookup['element_'.$row['element_id'].'_1'] = $row['element_title'].' - First'; + $column_name_lookup['element_'.$row['element_id'].'_2'] = $row['element_title'].' - Last'; + + $column_type_lookup['element_'.$row['element_id'].'_1'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_2'] = $row['element_type']; + + }elseif ('name' == $element_type){ //name has 4 fields + $column_name_lookup['element_'.$row['element_id'].'_1'] = $row['element_title'].' - Title'; + $column_name_lookup['element_'.$row['element_id'].'_2'] = $row['element_title'].' - First'; + $column_name_lookup['element_'.$row['element_id'].'_3'] = $row['element_title'].' - Last'; + $column_name_lookup['element_'.$row['element_id'].'_4'] = $row['element_title'].' - Suffix'; + + $column_type_lookup['element_'.$row['element_id'].'_1'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_2'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_3'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_4'] = $row['element_type']; + + }elseif('money' == $element_type){//money format + $column_name_lookup['element_'.$row['element_id']] = $row['element_title']; + if(!empty($element_constraint)){ + $column_type_lookup['element_'.$row['element_id']] = $element_constraint; //euro, pound, yen + }else{ + $column_type_lookup['element_'.$row['element_id']] = 'dollar'; //default is dollar + } + }elseif('checkbox' == $element_type){ //checkboxes, get childs elements + + $this_checkbox_options = $element_option_lookup[$row['element_id']]; + foreach ($this_checkbox_options as $option_id=>$option){ + $column_name_lookup['element_'.$row['element_id'].'_'.$option_id] = $option; + $column_type_lookup['element_'.$row['element_id'].'_'.$option_id] = $row['element_type']; + } + }else{ //for other elements with only 1 field + $column_name_lookup['element_'.$row['element_id']] = $row['element_title']; + $column_type_lookup['element_'.$row['element_id']] = $row['element_type']; + } + } + /******************************************************************************************/ + + //get values from ap_column_preferences table + $query = "select element_name from ap_column_preferences where form_id='{$form_id}'"; + $result = do_query($query); + + $column_prefs = array(); + while($row = do_fetch_result($result)){ + $column_prefs[] = $row['element_name']; + } + + $header_data =<< + + + +EOT; + +?> + + + + +
+ +
+

Entries Choose Columns

+

Specify which columns are displayed in Entries table

+
+ + +
+
+
+ + + + + + + + + +$element_label){ + if($toggle){ + $toggle = false; + $row_style = 'class="alt"'; + }else{ + $toggle = true; + $row_style = ''; + } + + if(in_array($element_name,$column_prefs)){ + $checked = 'checked="checked"'; + $img_name = 'checkbox_16.gif'; + }else{ + $checked = ''; + $img_name = 'cross_16.gif'; + } + +$table_row =<< + + + + +EOT; + echo $table_row; + $i++; + } +?> + + +
Choose columns to be displayed: 
{$element_label}

+ + + +
+
+ + + +
+ \ No newline at end of file diff --git a/config-empty.php b/config-empty.php new file mode 100644 index 0000000..791c6bc --- /dev/null +++ b/config-empty.php @@ -0,0 +1,59 @@ + \ No newline at end of file diff --git a/confirm.php b/confirm.php new file mode 100644 index 0000000..694ec0c --- /dev/null +++ b/confirm.php @@ -0,0 +1,72 @@ +top.location.replace('{$commit_result['form_redirect']}')"; + exit; + } + + }elseif (!empty($_POST['review_back'])){ + //go back to form + $ssl_suffix = get_ssl_suffix(); + header("Location: http{$ssl_suffix}://".$_SERVER['HTTP_HOST'].get_dirname($_SERVER['PHP_SELF'])."/view.php?id={$form_id}"); + exit; + }else{ + + if(empty($form_id)){ + die('ID required.'); + } + + if(!empty($_GET['done'])){ + $markup = display_success($form_id); + }else{ + if(empty($_SESSION['review_id'])){ + die("Your session has been expired. Please click here to start again."); + }else{ + $record_id = $_SESSION['review_id']; + } + $markup = display_form_review($form_id,$record_id); + } + } + + header("Content-Type: text/html; charset=UTF-8"); + echo $markup; + +?> diff --git a/confirm_embed.php b/confirm_embed.php new file mode 100644 index 0000000..79bafac --- /dev/null +++ b/confirm_embed.php @@ -0,0 +1,68 @@ +top.location.replace('{$commit_result['form_redirect']}')"; + exit; + } + }elseif (!empty($_POST['review_back'])){ + //go back to form + $ssl_suffix = get_ssl_suffix(); + header("Location: http{$ssl_suffix}://".$_SERVER['HTTP_HOST'].get_dirname($_SERVER['PHP_SELF'])."/embed.php?id={$form_id}"); + exit; + }else{ + + if(empty($form_id)){ + die('ID required.'); + } + + if(!empty($_GET['done'])){ + $markup = display_success($form_id,true); + }else{ + if(empty($_SESSION['review_id'])){ + die("Your session has been expired. Please click here to start again."); + }else{ + $record_id = $_SESSION['review_id']; + } + $markup = display_form_review($form_id,$record_id,true); + } + } + + header("Content-Type: text/html; charset=UTF-8"); + echo $markup; + +?> diff --git a/css/blank.gif b/css/blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..75b945d2553848b8b6f41fe5e24599c0687b8472 GIT binary patch literal 49 zcmZ?wbhEHbWMp7unE0RJ|Ns9C3=9Vj8~~DvKUo+V7?>DzfNY>Fh|Ltj$Y2csQN9XW literal 0 HcmV?d00001 diff --git a/css/email_entry.css b/css/email_entry.css new file mode 100644 index 0000000..04592a2 --- /dev/null +++ b/css/email_entry.css @@ -0,0 +1,47 @@ +/* + * SimpleModal Contact Form + * http://www.ericmmartin.com/projects/simplemodal/ + * http://code.google.com/p/simplemodal/ + * + * Copyright (c) 2007 Eric Martin - http://ericmmartin.com + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * Revision: $Id: contact.css 114 2008-03-20 00:53:05Z emartin24 $ + * + */ + +body {padding:0; margin:0; height:100%; width:100%;} + +/* Overlay */ +#contact-overlay {background-color:#000; } + +/* Container */ +#contact-container {width:420px; left:50%; top:25%; margin-left:-210px; font-family:'Trebuchet MS', Verdana, Arial; font-size:16px; text-align:center;} +#contact-container .contact-content {background-color:#144282; color:#ddd; height:40px;} +#contact-container h1 {color:#fff; margin:0; padding:20px 0 20px 0px; font-size:1.2em; text-align:center;text-indent: 0px} +#contact-container .contact-loading {position:absolute; background:url(../images/simple_modal/ajax-loader.gif) no-repeat; z-index:8000; height:55px; width:54px; margin:-14px 0 0 170px; padding:0;} + +#contact-container .contact-message {text-align:center;} +#contact-container .contact-error {width:92%; font-size:.8em; background:#000; border:2px solid #ccc; font-size:0.8em; font-weight:bold; margin:0 auto; padding:2px;} +#contact-container br {clear:both;} +#contact-container form {padding:0; margin:0;} +#contact-container label {clear:left; display:block; width:100px; float:left; text-align:right; padding-right:4px; font-weight:bold;} +#contact-container .contact-input {font-family:'Trebuchet MS', Verdana, Arial; padding:2px; margin:2px; background:#eee; border:1px solid #fff; width:350px;text-align: center} +#contact-container textarea {height:84px;} +#contact-container .contact-top {height:13px; background:url(../images/simple_modal/form_top.gif) no-repeat; padding:0; margin:0;} +#contact-container .contact-bottom {height:13px; background:url(../images/simple_modal/form_bottom.gif) no-repeat; font-size:.7em; text-align:center;} +#contact-container .contact-bottom a, +#contact-container .contact-bottom a:link, +#contact-container .contact-bottom a:active, +#contact-container .contact-bottom a:visited {position:relative; top:-4px; text-decoration:none; color:#666;} +#contact-container .contact-bottom a:hover {color:#888;} +#contact-container .contact-button {margin:4px 0 0 4px; cursor:pointer; height:24px; border:0; font-size:1em; font-weight:bold; color:#fff; text-align:center; vertical-align:middle;display: inline !important; float: inherit !important} +#contact-container .contact-send {width:50px; background:url(../images/simple_modal/send.png) no-repeat;padding: 0px;} +#contact-container .contact-cancel {width:65px; background:url(../images/simple_modal/cancel.png) no-repeat;padding: 0px;} +#contact-container a.modalCloseX, +#contact-container a.modalCloseX:link, +#contact-container a.modalCloseX:active, +#contact-container a.modalCloseX:visited {text-decoration:none; font-weight:bold; font-size:1.2em; position:absolute; top:-2px; left:400px; color:#fff;} +#contact-container a.modalCloseX:hover {color:#fff;} \ No newline at end of file diff --git a/css/email_entry_ie.css b/css/email_entry_ie.css new file mode 100644 index 0000000..92f6b5d --- /dev/null +++ b/css/email_entry_ie.css @@ -0,0 +1,18 @@ +/* + * SimpleModal Contact Form + * http://www.ericmmartin.com/projects/simplemodal/ + * http://code.google.com/p/simplemodal/ + * + * Copyright (c) 2007 Eric Martin - http://ericmmartin.com + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * Revision: $Id: contact_ie.css 113 2008-03-15 15:36:21Z emartin24 $ + * + */ + +/* IE 6 hacks*/ +#contact-container {top:expression((document.documentElement.scrollTop || document.body.scrollTop) + Math.round(15 * (document.documentElement.offsetHeight || document.body.clientHeight) / 100) + 'px');} +#contact-container .contact-top {background:url(../img/contact/form_top_ie.gif) no-repeat;} +#contact-container form {padding:0; margin:0;} \ No newline at end of file diff --git a/css/entry_print.css b/css/entry_print.css new file mode 100644 index 0000000..77dbac3 --- /dev/null +++ b/css/entry_print.css @@ -0,0 +1,52 @@ +body { + background: none !important; + margin: 0px !important; + padding: 0px !important; + font-size : 11pt !important; + overflow-y : visible !important; +} +#form_manager{ + margin: 0px !important; + padding: 0px !important; +} +#header, #footer{ + display: none !important; +} +#top, #bottom{ + display: none !important; + height: 0px !important; +} + +#ve_action_container{ + display: none !important; +} +#ve_detail{ + width: 100% !important; + float: none !important; +} +.alt{ + background-color: #fff !important; +} +.info{ + border-bottom: none !important; + padding-bottom: 10px !important; +} +.info p{ + display: none !important; +} +.breadcrumb{ + border-bottom: none !important; + color: #000 !important; +} +#ve_a_entries, #ve_a_next{ + display: none !important; +} +.global_message{ + display: none !important; +} +#view_entry{ + overflow: inherit !important; +} +#panel{ + overflow: inherit !important; +} \ No newline at end of file diff --git a/css/iepngfix.htc b/css/iepngfix.htc new file mode 100644 index 0000000..6d15f32 --- /dev/null +++ b/css/iepngfix.htc @@ -0,0 +1,68 @@ + + + + + \ No newline at end of file diff --git a/css/jquery-tabs.css b/css/jquery-tabs.css new file mode 100644 index 0000000..657c30d --- /dev/null +++ b/css/jquery-tabs.css @@ -0,0 +1,107 @@ +.ui-wrapper { border: 1px solid #50A029; } +.ui-wrapper input, .ui-wrapper textarea { border: 0; } + + +/* Caution! Ensure accessibility in print and other media types... */ +@media projection, screen { /* Use class for showing/hiding tab content, so that visibility can be better controlled in different media types... */ + .ui-tabs-hide { + display: none; + } +} + +/* Hide useless elements in print layouts... */ +@media print { + .ui-tabs-nav { + display: none; + } +} + +/* Skin */ +.ui-tabs-nav, .ui-tabs-panel { + + font-size: 12px; +} +.ui-tabs-nav { + list-style: none; + margin: 0; + padding: 0 0 0 3px; +} +.ui-tabs-nav:after { /* clearing without presentational markup, IE gets extra treatment */ + display: block; + clear: both; + content: " "; +} +.ui-tabs-nav li { + float: left; + margin: 0 0 0 2px; + font-weight: bold; +} +.ui-tabs-nav a, .ui-tabs-nav a span { + float: left; /* fixes dir=ltr problem and other quirks IE */ + padding: 0 12px; + background: url(../images/embed_code_tabs.gif) no-repeat; +} +.ui-tabs-nav a { + margin: 5px 0 0; /* position: relative makes opacity fail for disabled tab in IE */ + padding-left: 0; + background-position: 100% 0; + text-decoration: none; + white-space: nowrap; /* @ IE 6 */ + outline: 0; /* @ Firefox, prevent dotted border after click */ +} +.ui-tabs-nav a:link, .ui-tabs-nav a:visited { + color: #fff; +} +.ui-tabs-nav .ui-tabs-selected a { + position: relative; + top: 1px; + z-index: 2; + margin-top: 0; + background-position: 100% -23px; +} +.ui-tabs-nav a span { + padding-top: 1px; + padding-right: 0; + height: 20px; + background-position: 0 0; + line-height: 20px; +} +.ui-tabs-nav .ui-tabs-selected a span { + padding-top: 0; + height: 27px; + background-position: 0 -23px; + line-height: 27px; +} +.ui-tabs-nav .ui-tabs-selected a:link, .ui-tabs-nav .ui-tabs-selected a:visited, +.ui-tabs-nav .ui-tabs-disabled a:link, .ui-tabs-nav .ui-tabs-disabled a:visited { /* @ Opera, use pseudo classes otherwise it confuses cursor... */ + cursor: text; +} +.ui-tabs-nav a:hover, .ui-tabs-nav a:focus, .ui-tabs-nav a:active, +.ui-tabs-nav .ui-tabs-unselect a:hover, .ui-tabs-nav .ui-tabs-unselect a:focus, .ui-tabs-nav .ui-tabs-unselect a:active { /* @ Opera, we need to be explicit again here now... */ + cursor: pointer; +} +.ui-tabs-disabled { + opacity: .4; + filter: alpha(opacity=40); +} +.ui-tabs-nav .ui-tabs-disabled a:link, .ui-tabs-nav .ui-tabs-disabled a:visited { + color: #000; +} +.ui-tabs-panel { + padding: 10px; + padding-left: 5px; + background: #fff; /* declare background color for container to avoid distorted fonts in IE while fading */ +} +/*.ui-tabs-loading em { + padding: 0 0 0 20px; + background: url(loading.gif) no-repeat 0 50%; +}*/ + +/* Additional IE specific bug fixes... */ +* html .ui-tabs-nav { /* auto clear @ IE 6 & IE 7 Quirks Mode */ + display: inline-block; +} +*:first-child+html .ui-tabs-nav { /* auto clear @ IE 7 Standards Mode - do not group selectors, otherwise IE 6 will ignore complete rule (because of the unknown + combinator)... */ + display: inline-block; +} + diff --git a/data/.htaccess b/data/.htaccess new file mode 100644 index 0000000..9b3d22c --- /dev/null +++ b/data/.htaccess @@ -0,0 +1,16 @@ +# no access to .htaccess + +order allow,deny +deny from all + + +# view.css is required by public visitors + +allow from all + + +# limit public access + +order deny,allow +deny from all + \ No newline at end of file diff --git a/delete_element.php b/delete_element.php new file mode 100644 index 0000000..a769bd0 --- /dev/null +++ b/delete_element.php @@ -0,0 +1,118 @@ + \ No newline at end of file diff --git a/delete_element_option.php b/delete_element_option.php new file mode 100644 index 0000000..2911e42 --- /dev/null +++ b/delete_element_option.php @@ -0,0 +1,50 @@ + \ No newline at end of file diff --git a/download.php b/download.php new file mode 100644 index 0000000..8e4b4d2 --- /dev/null +++ b/download.php @@ -0,0 +1,141 @@ + \ No newline at end of file diff --git a/edit_css.php b/edit_css.php new file mode 100644 index 0000000..2d87d38 --- /dev/null +++ b/edit_css.php @@ -0,0 +1,82 @@ + + + + +
+ +
+

CSS File

+

Editing

+
+ +
+
+
    +
  • + +
    + +
    +
  • +
  • + + +
  • +
+
+

+ +
+ \ No newline at end of file diff --git a/edit_entry.css b/edit_entry.css new file mode 100644 index 0000000..8d15a63 --- /dev/null +++ b/edit_entry.css @@ -0,0 +1,837 @@ +#main_body +{ + background:#fffff; + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + font-size:small; + margin:8px 0 16px; + text-align:center; +} + +#form_container +{ + background:#fff; + border:1px solid #ccc; + margin:0 auto; + text-align:left; + width:640px; +} + + + + + +form.appnitro +{ + margin:20px 20px 0; + padding:0 0 20px; +} + +/**** Logo Section *****/ +#main_body h1 +{ + background-color:#dedede; + margin:0; + min-height:0; + padding:0; + text-decoration:none; + text-indent:-8000px; + background-image: url('../../../images/machform.gif'); + background-repeat: no-repeat; +} + +#main_body h1 a +{ + + display:block; + height:100%; + min-height:40px; + overflow:hidden; +} + + +#main_body img +{ + behavior:url(css/iepngfix.htc); + border:none; +} + + +/**** Form Section ****/ +.appnitro +{ + font-family:Lucida Grande, Tahoma, Arial, Verdana, sans-serif; + font-size:small; +} + +.appnitro li +{ + width:61%; +} + +#main_body form ul +{ + font-size:100%; + list-style-type:none; + margin:0; + padding:0; + width:100%; +} + +#main_body form li +{ + display:block; + margin:0; + padding:4px 5px 2px 9px; + position:relative; +} + +#main_body form li:after +{ + clear:both; + content:"."; + display:block; + height:0; + visibility:hidden; +} + +#main_body .buttons:after +{ + clear:both; + content:"."; + display:block; + height:0; + visibility:hidden; +} + +#main_body .buttons +{ + clear:both; + display:block; + margin-top:10px; +} + +#main_body html form li div +{ + display:inline-block; +} + +#main_body form li div +{ + color:#444; + margin:0 4px 0 0; + padding:0 0 8px; +} + +#main_body form li span +{ + color:#444; + float:left; + margin:0 4px 0 0; + padding:0 0 8px; +} + +#main_body form li div.left +{ + display:inline; + float:left; + width:48%; +} + +#main_body form li div.right +{ + display:inline; + float:right; + width:48%; +} + +#main_body form li div.left .medium +{ + width:100%; +} + +#main_body form li div.right .medium +{ + width:100%; +} + +#main_body .clear +{ + clear:both; +} + +#main_body form li div label +{ + clear:both; + color:#444; + display:block; + font-size:9px; + line-height:9px; + margin:0; + padding-top:3px; +} + +#main_body form li span label +{ + clear:both; + color:#444; + display:block; + font-size:9px; + line-height:9px; + margin:0; + padding-top:3px; +} + +#main_body form li .datepicker +{ + cursor:pointer !important; + float:left; + height:16px; + margin:.1em 5px 0 0; + padding:0; + width:16px; +} + +#main_body .form_description +{ + + display: none; + +} + + + +#main_body form hr +{ + display:none; +} + +#main_body form li.section_break +{ + border-top:1px dotted #ccc; + margin-top:9px; + padding-bottom:0; + padding-left:9px; + padding-top:13px; + width:97% !important; +} + +#main_body form ul li.first +{ + border-top:none !important; + margin-top:0 !important; + padding-top:0 !important; +} + +#main_body form .section_break h3 +{ + font-size:110%; + font-weight:400; + line-height:130%; + margin:0 0 2px; +} + +#main_body form .section_break p +{ + font-size:85%; + + margin:0 0 10px; +} + +/**** Buttons ****/ +#main_body input.button_text +{ + overflow:visible; + padding:0 7px; + width:auto; +} + +#main_body .buttons input +{ + font-size:110%; + margin-right:5px; + font-family: "Lucida Grande",Tahoma,Arial,Verdana,sans-serif; +} + +/**** Inputs and Labels ****/ +#main_body label.description +{ + border:none; + color:#222; + display:block; + font-size:95%; + font-weight:700; + line-height:150%; + padding:0 0 1px; +} + +#main_body span.symbol +{ + font-size:115%; + line-height:130%; +} + +#main_body input.text +{ + background:#fff url(images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; + color:#333; + font-size:100%; + margin:0; + padding:2px 0; +} + +#main_body input.file +{ + color:#333; + font-size:100%; + margin:0; + padding:2px 0; +} + +#main_body textarea.textarea +{ + background:#fff url(../../../images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; + color:#333; + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + font-size:100%; + margin:0; + width:99%; +} + +#main_body select.select +{ + color:#333; + font-size:100%; + margin:1px 0; + padding:1px 0 0; + background:#fff url(../../../images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; +} + + +#main_body input.currency +{ + text-align:right; +} + +#main_body input.checkbox +{ + display:block; + height:13px; + line-height:1.4em; + margin:6px 0 0 3px; + width:13px; +} + +#main_body input.radio +{ + display:block; + height:13px; + line-height:1.4em; + margin:6px 0 0 3px; + width:13px; +} + +#main_body label.choice +{ + color:#444; + display:block; + font-size:100%; + line-height:1.4em; + margin:-1.55em 0 0 25px; + padding:4px 0 5px; + width:90%; +} + +#main_body select.select[class] +{ + margin:0; + padding:1px 0; +} + +*:first-child+html select.select[class] +{ + margin:1px 0; +} + +#main_body .safari select.select +{ + font-size:120% !important; + margin-bottom:1px; +} + +#main_body input.small +{ + width:25%; +} + +#main_body select.small +{ + width:25%; +} + +#main_body input.medium +{ + width:50%; +} + +#main_body select.medium +{ + width:50%; +} + +#main_body input.large +{ + width:99%; +} + +#main_body select.large +{ + width:100%; +} + +#main_body textarea.small +{ + height:5.5em; +} + +#main_body textarea.medium +{ + height:10em; +} + +#main_body textarea.large +{ + height:20em; +} + +/**** Errors ****/ +#error_message +{ + background:#fff; + border:1px dotted red; + margin-bottom:1em; + padding-left:0; + padding-right:0; + padding-top:4px; + text-align:center; + width:97%; +} + +#error_message_title +{ + color:#DF0000; + font-size:125%; + margin:7px 0 5px !important; + padding:0 !important; +} + +#error_message_desc +{ + color:#000; + font-size:100%; + margin:0 0 .8em !important; +} + +#error_message_desc strong +{ + background-color:#FFDFDF; + color:red; + padding:2px 3px; +} + +#main_body form li.error +{ + background-color:#FFDFDF !important; + border-bottom:1px solid #EACBCC; + border-right:1px solid #EACBCC; + margin:3px 0; +} + +#main_body form li.error label +{ + color:#DF0000 !important; +} + +#main_body form p.error +{ + clear:both; + color:red; + font-size:10px; + font-weight:700; + margin:0 0 5px !important; +} + +#main_body form .required +{ + color:red !important; + float:none !important; + font-weight:700; +} + +/**** Guidelines and Error Highlight ****/ +#main_body form li.highlighted +{ + background-color:#fff7c0; +} + +#main_body form .guidelines +{ + background:#f5f5f5; + border:1px solid #e6e6e6; + color:#444; + font-size:80%; + left:100%; + line-height:130%; + margin:0 0 0 8px !important; + padding:8px 10px 9px; + position:absolute; + top:0; + visibility:hidden; + width:42%; + z-index:1000; +} + +#main_body form .guidelines small +{ + font-size:105%; +} + +#main_body form li.highlighted .guidelines +{ + visibility:visible; +} + +#main_body form li:hover .guidelines +{ + visibility:visible; +} + +.no_guidelines .guidelines +{ + display:none !important; +} + +.no_guidelines form li +{ + width:97%; +} + +.no_guidelines li.section +{ + padding-left:9px; +} + +/*** Success Message ****/ +.form_success +{ + clear: both; + margin: 0; + padding: 90px 0pt 100px; + text-align: center +} + +.form_success h2 { + clear:left; + font-size:160%; + font-weight:normal; + margin:0pt 0pt 3px; +} + +/*** Password ****/ +#main_body ul.password{ + margin-top:60px; + margin-bottom: 60px; + text-align: center; +} +.password h2{ + color:#DF0000; + font-weight:bold; + margin:0pt auto 10px; +} + +.password input.text { + font-size:170% !important; + width:380px; + text-align: center; +} +.password label{ + display:block; + font-size:120% !important; + padding-top:10px; + font-weight:bold; +} + +#li_captcha{ + padding-left: 5px; +} + + +#li_captcha span{ + float:none; + padding: 0px !important; +} + +#li_captcha div{ + padding: 0px !important; +} + + + +/** Integrated Form **/ +.integrated *{ + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + color: #000; +} + +.integrated #top, .integrated #bottom, .integrated h1{ + display: none; +} + +.integrated #form_container{ + border: none; + width: 99%; + background: none; +} + +.integrated #footer{ + display: none; +} + +.integrated #footer.success{ + text-align: center; +} + +.integrated form.appnitro +{ + margin:0px 0px 0; + +} + +.integrated form .section_break h3 +{ + border: none !important; +} + +.integrated #error_message h3 +{ + border: none !important; + +} + + + +/*** Calendar **********************/ +div.calendar { position: relative; } + + +.calendar table { +cursor:pointer; +border:1px solid #ccc; +font-size: 11px; +color: #000; +background: #fff; +font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; +} + +.calendar table .title,.calendar table .button{ +font-size: 11px; +} + +.calendar * { +font-size: 11px; +font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; +} + +.calendar .button { +text-align: center; +padding: 2px; +} + +.calendar .nav { +background:#f5f5f5; +} + +.calendar thead .title { +font-weight: bold; +text-align: center; +background: #dedede; +color: #000; +padding: 2px 0 3px 0; +} + +.calendar thead .headrow { +background: #f5f5f5; +color: #444; +font-weight:bold; +} + +.calendar thead .daynames { +background: #fff; +color:#333; +font-weight:bold; +} + +.calendar thead .name { +border-bottom: 1px dotted #ccc; +padding: 2px; +text-align: center; +color: #000; +} + +.calendar thead .weekend { +color: #666; +} + +.calendar thead .hilite { +background-color: #444; +color: #fff; +padding: 1px; +} + +.calendar thead .active { +background-color: #d12f19; +color:#fff; +padding: 2px 0px 0px 2px; +} + + +.calendar tbody .day { +width:1.8em; +color: #222; +text-align: right; +padding: 2px 2px 2px 2px; +} +.calendar tbody .day.othermonth { +font-size: 80%; +color: #bbb; +} +.calendar tbody .day.othermonth.oweekend { +color: #fbb; +} + +.calendar table .wn { +padding: 2px 2px 2px 2px; +border-right: 1px solid #000; +background: #666; +} + +.calendar tbody .rowhilite td { +background: #FFF1AF; +} + +.calendar tbody .rowhilite td.wn { +background: #FFF1AF; +} + +.calendar tbody td.hilite { +padding: 1px 1px 1px 1px; +background:#444 !important; +color:#fff !important; +} + +.calendar tbody td.active { +color:#fff; +background: #529214 !important; +padding: 2px 2px 0px 2px; +} + +.calendar tbody td.selected { +font-weight: bold; +border: 1px solid #888; +padding: 1px 1px 1px 1px; +background: #f5f5f5 !important; +color: #222 !important; +} + +.calendar tbody td.weekend { +color: #666; +} + +.calendar tbody td.today { +font-weight: bold; +color: #529214; +background:#D9EFC2; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { +visibility: hidden; +} + +.calendar tbody .emptyrow { +display: none; +} + +.calendar tfoot .footrow { +text-align: center; +background: #556; +color: #fff; +} + +.calendar tfoot .ttip { +background: #222; +color: #fff; +font-size:10px; +border-top: 1px solid #dedede; +padding: 3px; +} + +.calendar tfoot .hilite { +background: #aaf; +border: 1px solid #04f; +color: #000; +padding: 1px; +} + +.calendar tfoot .active { +background: #77c; +padding: 2px 0px 0px 2px; +} + +.calendar .combo { +position: absolute; +display: none; +top: 0px; +left: 0px; +width: 4em; +border: 1px solid #ccc; +background: #f5f5f5; +color: #222; +font-size: 90%; +z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { +text-align: center; +padding: 1px; +} + +.calendar .combo .label-IEfix { +width: 4em; +} + +.calendar .combo .hilite { +background: #444; +color:#fff; +} + +.calendar .combo .active { +border-top: 1px solid #999; +border-bottom: 1px solid #999; +background: #dedede; +font-weight: bold; +} + diff --git a/edit_entry.php b/edit_entry.php new file mode 100644 index 0000000..7e8edd3 --- /dev/null +++ b/edit_entry.php @@ -0,0 +1,203 @@ + $entry_id order by id asc limit 1"); + $row = do_fetch_result($result); + $newer_entry_id = $row['id']; + + //newest entry id + $result = do_query("select id from ap_form_{$form_id} order by id desc limit 1"); + $row = do_fetch_result($result); + $newest_entry_id = $row['id']; + + if(($entry_id == $newest_entry_id) && ($entry_id == $oldest_entry_id)){ + $nav_position = 'disabled'; + }elseif($entry_id == $newest_entry_id){ + $nav_position = 'newest'; + }elseif ($entry_id == $oldest_entry_id){ + $nav_position = 'oldest'; + }else{ + $nav_position = 'middle'; + } + +?> + + + + +
+ +
+

Entries #

+

Editing entry #

+
+ + +
+
+ +
+ +
+
+ + " alt="Newest">  + " alt="Newer">  + + + +   +   + + + +" alt="Older">  + " alt="Oldest"> + + +   + + +
+
Entry Options
+
+ +
+
+ + +
+ \ No newline at end of file diff --git a/edit_form.php b/edit_form.php new file mode 100644 index 0000000..2fcf786 --- /dev/null +++ b/edit_form.php @@ -0,0 +1,721 @@ +id = $form_id; + $form->name = $row['form_name']; + $form->description = $row['form_description']; + $form->redirect = $row['form_redirect']; + $form->success_message = $row['form_success_message']; + $form->password = $row['form_password']; + $form->frame_height = $row['form_frame_height']; + $form->unique_ip = $row['form_unique_ip']; + $form->captcha = $row['form_captcha']; + $form->review = $row['form_review']; + }else{ + $form->id = 0; + $form->name = 'Untitled Form'; + $form->description = 'This is your form description. Click here to edit.'; + $form->redirect = ''; + $form->success_message = 'Success! Your submission has been saved!'; + $form->password = ''; + $form->frame_height = 0; + $form->unique_ip = 0; + $form->captcha = 0; + $form->review = 0; + } + + //get element options first and store it into array + $query = "select + element_id, + option_id, + `position`, + `option`, + option_is_default + from + ap_element_options + where + form_id='$form_id' and live=1 + order by + element_id asc,`position` asc"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $option_id = $row['option_id']; + $options_lookup[$element_id][$option_id]['position'] = $row['position']; + $options_lookup[$element_id][$option_id]['option'] = $row['option']; + $options_lookup[$element_id][$option_id]['option_is_default'] = $row['option_is_default']; + } + + + //get elements data + $element = array(); + $query = "select + element_id, + element_title, + element_guidelines, + element_size, + element_is_required, + element_is_unique, + element_is_private, + element_type, + element_position, + element_default_value, + element_constraint + from + ap_form_elements + where + form_id='$form_id' + order by + element_position asc"; + $result = do_query($query); + $j=0; + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + + //lookup element options first + if(!empty($options_lookup[$element_id])){ + $element_options = array(); + $i=0; + foreach ($options_lookup[$element_id] as $option_id=>$data){ + $element_options[$i] = new stdClass(); + $element_options[$i]->id = $option_id; + $element_options[$i]->option = $data['option']; + $element_options[$i]->is_default = $data['option_is_default']; + $element_options[$i]->is_db_live = 1; + $i++; + } + } + + + //populate elements + $element[$j] = new stdClass(); + $element[$j]->title = $row['element_title']; + $element[$j]->guidelines = $row['element_guidelines']; + $element[$j]->size = $row['element_size']; + $element[$j]->is_required = $row['element_is_required']; + $element[$j]->is_unique = $row['element_is_unique']; + $element[$j]->is_private = $row['element_is_private']; + $element[$j]->type = $row['element_type']; + $element[$j]->position = $row['element_position']; + $element[$j]->id = $row['element_id']; + $element[$j]->is_db_live = 1; + $element[$j]->default_value = $row['element_default_value']; + $element[$j]->constraint = $row['element_constraint']; + if(!empty($element_options)){ + $element[$j]->options = $element_options; + }else{ + $element[$j]->options = ''; + } + $j++; + } + + + $json = new Services_JSON(); + $json_form = $json->encode($form); + + + $all_element = array('elements' => $element); + + $json_element = $json->encode($all_element); + + + $header_data =<< + +EOT; + + $show_status_bar = true; //for header.php + + require('includes/header.php'); +?> + +
+
+
    + +
    +

    You have no fields yet!

    +

    Click the buttons on the right to add fields to your form.

    +
    + + +
    +
    +
    + + + + + +var json_form = {$json_form}; +var json_elements = {$json_element}; + +EOT; + require('includes/footer.php'); +?> diff --git a/email_entry.php b/email_entry.php new file mode 100644 index 0000000..3a274ec --- /dev/null +++ b/email_entry.php @@ -0,0 +1,127 @@ + + x +
    +
    +

    Email Entry #{$entry_id} to:

    + + +
    +
    + Use commas to separate email addresses

    + + +
    + + +
    +
    +
    +
    "; + }elseif ($action == 'send') { + + $to_emails = trim($_REQUEST['email']); + + //get form properties data + $query = "select + esl_from_name, + esl_from_email_address, + esl_subject, + esl_content, + esl_plain_text + from + `ap_forms` + where + form_id='$form_id'"; + + $result = do_query($query); + $row = do_fetch_result($result); + + $esl_from_name = $row['esl_from_name']; + $esl_from_email_address = $row['esl_from_email_address']; + $esl_subject = $row['esl_subject']; + $esl_content = $row['esl_content']; + $esl_plain_text = $row['esl_plain_text']; + + //get parameters for the email + + //from name + if(!empty($esl_from_name)){ + $admin_email_param['from_name'] = $esl_from_name; + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $admin_email_param['from_name'] = NOTIFICATION_MAIL_FROM_NAME; + }else{ + $admin_email_param['from_name'] = 'MachForm'; + } + + //from email address + if(!empty($esl_from_email_address)){ + if(is_numeric($esl_from_email_address)){ + $admin_email_param['from_email'] = '{element_'.$esl_from_email_address.'}'; + }else{ + $admin_email_param['from_email'] = $esl_from_email_address; + } + }elseif(NOTIFICATION_MAIL_FROM != ''){ + $admin_email_param['from_email'] = NOTIFICATION_MAIL_FROM; + }else{ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $admin_email_param['from_email'] = "no-reply@{$domain}"; + } + + //subject + if(!empty($esl_subject)){ + $admin_email_param['subject'] = $esl_subject; + }elseif (NOTIFICATION_MAIL_SUBJECT != ''){ + $admin_email_param['subject'] = NOTIFICATION_MAIL_SUBJECT; + }else{ + $admin_email_param['subject'] = '{form_name} [#{entry_no}]'; + } + + //content + if(!empty($esl_content)){ + $admin_email_param['content'] = $esl_content; + }else{ + $admin_email_param['content'] = '{entry_data}'; + } + + $admin_email_param['as_plain_text'] = $esl_plain_text; + $admin_email_param['target_is_admin'] = true; + + send_notification($form_id,$entry_id,$to_emails,$admin_email_param); + + echo "Entry #{$entry_id} successfully sent."; + } + + + + +?> \ No newline at end of file diff --git a/email_settings.css b/email_settings.css new file mode 100644 index 0000000..c2cfc04 --- /dev/null +++ b/email_settings.css @@ -0,0 +1,539 @@ +#esl_main_body, #esr_main_body +{ + background:#fffff; + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + font-size:small; + margin:8px 0 16px; + text-align:center; +} + +#esl_form_container, #esr_form_container +{ + background:#fff; + border:1px solid #ccc; + margin:0 auto; + text-align:left; + width:640px; +} + + +form.appnitro +{ + margin:20px 20px 0; + padding:0px; +} + +.esl_options{ + display: none; +} +.esr_options{ + display: none; +} +/**** Form Section ****/ +.appnitro +{ + font-family:Lucida Grande, Tahoma, Arial, Verdana, sans-serif; + font-size:small; +} + +.appnitro li +{ + width:98%; + padding-right: 0px !important; + +} + +#esl_main_body form ul,#esr_main_body form ul +{ + font-size:100%; + list-style-type:none; + margin:0; + padding:0; + width:100%; +} + +#esl_main_body form li,#esr_main_body form li +{ + /*display:block;*/ + margin:0; + padding:4px 5px 2px 9px; + position:relative; +} + +#esl_main_body form li:after,#esr_main_body form li:after +{ + clear:both; + content:"."; + display:block; + height:0; + visibility:hidden; +} + +#esl_main_body .buttons:after,#esr_main_body .buttons:after +{ + clear:both; + content:"."; + display:block; + height:0; + visibility:hidden; +} + +#esl_main_body .buttons,#esr_main_body .buttons +{ + clear:both; + display:block; + width: 100%; + +} + +#esl_main_body html form li div,#esr_main_body html form li div +{ + display:inline-block; +} + +#esl_main_body form li div,#esr_main_body form li div +{ + color:#444; + margin:0 4px 0 0; + padding:0 0 8px; +} + +#esl_main_body form li span,#esr_main_body form li span +{ + color:#444; + float:left; + margin:0 4px 0 0; + padding:0px !important; +} + +#esl_main_body form li div.left,#esr_main_body form li div.left +{ + display:inline; + float:left; + width:48%; +} + +#esl_main_body form li div.right,#esr_main_body form li div.right +{ + display:inline; + float:right; + width:48%; +} + +#esl_main_body form li div.left .medium,#esr_main_body form li div.left .medium +{ + width:100%; +} + +#esl_main_body form li div.right .medium,#esr_main_body form li div.right .medium +{ + width:100%; +} + +#esl_main_body .clear,#esr_main_body .clear +{ + clear:both; +} + +#esl_main_body form li div label,#esr_main_body form li div label +{ + clear:both; + color:#444; + display:block; + font-size:9px; + line-height:9px; + margin:0; + padding-top:3px; +} + +#esl_main_body form li span label,#esr_main_body form li span label +{ + clear:both; + color:#444; + display:block; + font-size:9px; + line-height:9px; + margin:0; + padding-top:3px; +} + + + +#esl_main_body form hr,#esr_main_body form hr +{ + display:none; +} + +#esl_main_body form li.section_break,#esr_main_body form li.section_break +{ + border-top:1px dotted #ccc; + margin-top:9px; + padding-bottom:0; + padding-left:9px; + padding-top:13px; + width:97% !important; +} + +#esl_main_body form ul li.first,#esr_main_body form ul li.first +{ + border-top:none !important; + margin-top:0 !important; + padding-top:0 !important; +} + +#esl_main_body form .section_break h3,#esr_main_body form .section_break h3 +{ + font-size:110%; + font-weight:400; + line-height:130%; + margin:0 0 2px; + color: #444; + padding: 0px; +} + +#esl_main_body form .section_break p,#esr_main_body form .section_break p +{ + font-size:85%; + + margin:0 0 10px; +} + +/**** Buttons ****/ +#esl_main_body input.button_text,#esr_main_body input.button_text +{ + overflow:visible; + padding:0 7px; + width:auto; +} + +#esl_main_body .buttons input,#esr_main_body .buttons input +{ + font-size:120%; + margin-right:5px; +} + +/**** Inputs and Labels ****/ +#esl_main_body label.description,#esr_main_body label.description +{ + border:none; + color:#222; + display:block; + font-size:95%; + font-weight:700; + line-height:150%; + padding:0 0 1px; +} + +#esl_main_body span.symbol,#esr_main_body span.symbol +{ + font-size:115%; + line-height:130%; +} + +#esl_main_body input.text,#esr_main_body input.text +{ + background:#fff url(images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; + color:#333; + font-size:100%; + margin:0; + padding:2px 0; +} + +#esl_main_body input.file,#esr_main_body input.file +{ + color:#333; + font-size:100%; + margin:0; + padding:2px 0; +} + +#esl_main_body textarea.textarea,#esr_main_body textarea.textarea +{ + background:#fff url(images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; + color:#333; + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + font-size:100%; + margin:0; + width:98%; +} + +#esl_main_body select.select,#esr_main_body select.select +{ + color:#333; + font-size:100%; + margin:1px 0; + padding:1px 0 0; + background:#fff url(images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; +} + + +#esl_main_body input.currency,#esr_main_body input.currency +{ + text-align:right; +} + +#esl_main_body input.checkbox,#esr_main_body input.checkbox +{ + display:block; + height:13px; + line-height:1.4em; + margin:6px 0 0 3px; + width:13px; +} + +#esl_main_body input.radio,#esr_main_body input.radio +{ + display:block; + height:13px; + line-height:1.4em; + margin:6px 0 0 3px; + width:13px; +} + +#esl_main_body label.choice,#esr_main_body label.choice +{ + color:#444; + display:block; + font-size:100%; + line-height:1.4em; + margin:-1.55em 0 0 25px; + padding:4px 0 5px; + width:90%; +} + +#esl_main_body select.select[class],#esr_main_body select.select[class] +{ + margin:0; + padding:1px 0; +} + +*:first-child+html select.select[class] +{ + margin:1px 0; +} + +#esl_main_body .safari select.select,#esr_main_body .safari select.select +{ + font-size:120% !important; + margin-bottom:1px; +} + +#esl_main_body input.small,#esr_main_body input.small +{ + width:25%; +} + +#esl_main_body select.small,#esr_main_body select.small +{ + width:25%; +} + +#esl_main_body input.medium,#esr_main_body input.medium +{ + width:50%; +} + +#esl_main_body select.medium,#esr_main_body select.medium +{ + width:50%; +} + +#esl_main_body input.large,#esr_main_body input.large +{ + width:98%; +} + +#esl_main_body select.large,#esr_main_body select.large +{ + width:100%; +} + +#esl_main_body textarea.small,#esr_main_body textarea.small +{ + height:5.5em; +} + +#esl_main_body textarea.medium,#esr_main_body textarea.medium +{ + height:10em; +} + +#esl_main_body textarea.large,#esr_main_body textarea.large +{ + height:20em; +} + +/**** Errors ****/ +#error_message +{ + background:#fff; + border:1px dotted red; + margin-bottom:1em; + padding-left:0; + padding-right:0; + padding-top:4px; + text-align:center; + width:97%; +} + +#error_message_title +{ + color:#DF0000; + font-size:125%; + margin:7px 0 5px !important; + padding:0 !important; +} + +#error_message_desc +{ + color:#000; + font-size:100%; + margin:0 0 .8em !important; +} + +#error_message_desc strong +{ + background-color:#FFDFDF; + color:red; + padding:2px 3px; +} + +#esl_main_body form li.error,#esr_main_body form li.error +{ + background-color:#FFDFDF !important; + border-bottom:1px solid #EACBCC; + border-right:1px solid #EACBCC; + margin:3px 0; +} + +#esl_main_body form li.error label,#esr_main_body form li.error label +{ + color:#DF0000 !important; +} + +#esl_main_body form p.error,#esr_main_body form p.error +{ + clear:both; + color:red; + font-size:10px; + font-weight:700; + margin:0 0 5px !important; +} + +#esl_main_body form .required,#esr_main_body form .required +{ + color:red !important; + float:none !important; + font-weight:700; +} + +/**** Guidelines and Error Highlight ****/ +#esl_main_body form li.highlighted,#esr_main_body form li.highlighted +{ + background-color:#fff7c0; +} + +#esl_main_body form .guidelines,#esr_main_body form .guidelines +{ + background:#f5f5f5; + border:1px solid #e6e6e6; + color:#444; + font-size:80%; + left:100%; + line-height:130%; + margin:0 0 0 8px !important; + padding:8px 10px 9px; + position:absolute; + top:0; + visibility:hidden; + width:42%; + z-index:1000; +} + +#esl_main_body form .guidelines small,#esr_main_body form .guidelines small +{ + font-size:105%; +} + +#esl_main_body form li.highlighted .guidelines,#esr_main_body form li.highlighted .guidelines +{ + visibility:visible; +} + +#esl_main_body form li:hover .guidelines,#esr_main_body form li:hover .guidelines +{ + visibility:visible; +} + +.no_guidelines .guidelines +{ + display:none !important; +} + +.no_guidelines form li +{ + width:97%; +} + +.no_guidelines li.section +{ + padding-left:9px; +} + + +/** Integrated Form **/ +.integrated *{ + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + color: #000; +} + +.integrated #top, .integrated #bottom, .integrated h1{ + display: none; +} + +.integrated #esl_form_container,.integrated #esr_form_container{ + border: none; + width: 100%; + background: none; + +} + +.integrated #footer{ + text-align: left; + padding-left: 10px; + width: 99%; +} + +.integrated #footer.success{ + text-align: center; +} + +.integrated form.appnitro +{ + margin:0px 0px 0; + +} + +.integrated form .section_break h3 +{ + border: none !important; +} + +.integrated #error_message h3 +{ + border: none !important; + +} + diff --git a/email_settings.php b/email_settings.php new file mode 100644 index 0000000..e4d4103 --- /dev/null +++ b/email_settings.php @@ -0,0 +1,526 @@ +$value){ + $value = mysql_real_escape_string($value); + $update_values .= "`$key`='$value',"; + } + $update_values = substr($update_values,0,-1); + + $query = "UPDATE `ap_forms` set + $update_values + where + form_id='{$form_id}';"; + + do_query($query); + + $_SESSION['AP_SUCCESS']['title'] = 'Success'; + $_SESSION['AP_SUCCESS']['desc'] = 'Notification settings have been saved.'; + + header("Location: email_settings.php?id={$form_id}"); + exit; + }else{ + $_SESSION['AP_ERROR']['title'] = $lang['error_title']; + $_SESSION['AP_ERROR']['desc'] = $lang['error_desc']; + } + + }else{ + //populate current values or default values + $_POST['esl_email_address'] = $form_email; + + if(!empty($esl_from_name)){ + $_POST['esl_from_name'] = $esl_from_name; + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $_POST['esl_from_name'] = NOTIFICATION_MAIL_FROM_NAME; + }else{ + $_POST['esl_from_name'] = 'MachForm'; + } + + $_POST['esl_from_email_address'] = $esl_from_email_address; + + if(!empty($esl_subject)){ + $_POST['esl_subject'] = $esl_subject; + }elseif (NOTIFICATION_MAIL_SUBJECT != ''){ + $_POST['esl_subject'] = NOTIFICATION_MAIL_SUBJECT; + }else{ + $_POST['esl_subject'] = '{form_name} [#{entry_no}]'; + } + + if(!empty($esl_content)){ + $_POST['esl_content'] = $esl_content; + }else{ + $_POST['esl_content'] = '{entry_data}'; + } + + $_POST['esl_plain_text'] = $esl_plain_text; + $_POST['esl_options_expand'] = 0; + } + //end left form handler -------- + + //start right form handler -------- + $esr_email_fields = $email_fields; + $esr_valid_email = true; + + if(!empty($_POST['esr_submit'])){ + unset($_POST['esr_submit']); + $input_array = ap_sanitize_input($_POST); + + //validate for valid email address + if(!empty($input_array['esr_from_email_address'])){ + $regex = '/^[A-z0-9][\w.-]*@[A-z0-9][\w\-\.]+\.[A-z0-9]{2,6}$/'; + $email = trim($input_array['esr_from_email_address']); + $result = preg_match($regex, $email); + + if(empty($result)){ + $esr_valid_email = false; + } + + } + + //if passed, store into database + if($esr_valid_email){ + $esr_input['esr_email_address'] = $input_array['esr_email_address']; + $esr_input['esr_from_name'] = $input_array['esr_from_name']; + $esr_input['esr_from_email_address'] = $input_array['esr_from_email_address']; + $esr_input['esr_subject'] = $input_array['esr_subject']; + $esr_input['esr_content'] = $input_array['esr_content']; + $esr_input['esr_plain_text'] = $input_array['esr_plain_text']; + + if(empty($esr_input['esr_plain_text'])){ + $esr_input['esr_plain_text'] = 0; + } + + //create the sql update string + foreach ($esr_input as $key=>$value){ + $value = mysql_real_escape_string($value); + $update_values .= "`$key`='$value',"; + } + $update_values = substr($update_values,0,-1); + + $query = "UPDATE `ap_forms` set + $update_values + where + form_id='{$form_id}';"; + + do_query($query); + + $_SESSION['AP_SUCCESS']['title'] = 'Success'; + $_SESSION['AP_SUCCESS']['desc'] = 'Notification settings have been saved.'; + + header("Location: email_settings.php?id={$form_id}"); + exit; + }else{ + $_SESSION['AP_ERROR']['title'] = $lang['error_title']; + $_SESSION['AP_ERROR']['desc'] = $lang['error_desc']; + $_POST['esr_options_expand'] = 1; + } + }else{ + //populate current values or default values + $_POST['esr_email_address'] = $esr_email_address; + + if(!empty($esr_from_name)){ + $_POST['esr_from_name'] = $esr_from_name; + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $_POST['esr_from_name'] = NOTIFICATION_MAIL_FROM_NAME; + }else{ + $_POST['esr_from_name'] = 'MachForm'; + } + + if(!empty($esr_from_email_address)){ + $_POST['esr_from_email_address'] = $esr_from_email_address; + }elseif(NOTIFICATION_MAIL_FROM != ''){ + $_POST['esr_from_email_address'] = NOTIFICATION_MAIL_FROM; + }else{ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $_POST['esr_from_email_address'] = "no-reply@{$domain}"; + } + + if(!empty($esr_subject)){ + $_POST['esr_subject'] = $esr_subject; + }else{ + $_POST['esr_subject'] = '{form_name} - Receipt'; + } + + if(!empty($esr_content)){ + $_POST['esr_content'] = $esr_content; + }else{ + $_POST['esr_content'] = '{entry_data}'; + } + + $_POST['esr_plain_text'] = $esr_plain_text; + $_POST['esr_options_expand'] = 0; + + } + //end right form handler --------- + + if(!empty($_POST['esl_options_expand'])){ + $esl_style = ''; + } + + if(!empty($_POST['esr_options_expand'])){ + $esr_style = ''; + } + + $header_data =<< + + + + {$esl_style} + {$esr_style} +EOT; +?> + + + +
    + +
    +

    Emails

    +

    Configure your email notification settings

    +
    +

    Send notification emails to

    +
    +

    You

    +
    + + +
    + +
    +
    +
      +
    • > + +
      + +
      + {$lang['val_email']}

      "; }; ?> +
    • +
    • +

       Email Header

      +
    • +
    • + +
      + +
      +
    • +
    • + +
      + +
      +
    • +
    • +

       Email Content

      +
    • +
    • + +
      + +
      + +
    • +
    • + +
      + +
      +
    • +
    • + + + /> + + +
      + Info
      You can insert template variables into the above fields. +
      +
    • +
    • + +
      + +
      +
    • +
    • + + + + +
    • +
    +
    +
    + +
    + + +
    + +
    +
    +

    Your Users

    +
    + + +
    + +
    +
    +
      + +
    • + +
      + +
      +
    • + +
    • + +
      + To enable sending email to your users, an Email field is required on the form. +
      +
    • + +
    • +

       Email Header

      +
    • +
    • + +
      + +
      +
    • +
    • + +
      + +
      + {$lang['val_email']}

      "; }; ?> +
    • +
    • +

       Email Content

      +
    • +
    • + +
      + +
      +
    • +
    • + +
      + +
      +
    • +
    • + + + /> + + +
      + Info
      You can insert template variables into the above fields. +
      +
    • +
    • +
      + + + +
      +
    • +
    • + + + /> +
    • +
    +
    +
    + +
    + + +
    +
    +
    +
    + \ No newline at end of file diff --git a/embed.php b/embed.php new file mode 100644 index 0000000..a93fe8b --- /dev/null +++ b/embed.php @@ -0,0 +1,94 @@ +top.location = '{$submit_result['form_redirect']}'"; + exit; + } + }else{ //redirect to review page + $ssl_suffix = get_ssl_suffix(); + $_SESSION['review_id'] = $submit_result['review_id']; + + header("Location: http{$ssl_suffix}://".$_SERVER['HTTP_HOST'].get_dirname($_SERVER['PHP_SELF'])."/confirm_embed.php?id={$input_array['form_id']}"); + exit; + } + + }else{ + $old_values = $submit_result['old_values']; + $custom_error = $submit_result['custom_error']; + $error_elements = $submit_result['error_elements']; + + $markup = display_form($input_array['form_id'],$old_values,$error_elements,$custom_error,0,true); + } + }else{ //if password form submitted + if($submit_result['status'] === true){ //on success, display the form + $markup = display_form($input_array['form_id'],null,null,'',0,true); + }else{ + $custom_error = $submit_result['custom_error']; //error, display the pasword form again + $markup = display_form($input_array['form_id'],null,null,$custom_error,0,true); + } + } + }else{ + $form_id = (int) trim($_GET['id']); + if(empty($form_id)){ + die('ID required.'); + } + + //check for delete file option + //this is available for form with review enabled + if(!empty($_GET['delete_file']) && !empty($_SESSION['review_id'])){ + $element_id = (int) trim($_GET['delete_file']); + delete_review_file_entry($form_id,$_SESSION['review_id'],$element_id); + } + + if(!empty($_GET['done'])){ + $markup = display_success($form_id,true); + }else{ + $markup = display_form($form_id,null,null,'',0,true); + } + } + + header("Content-Type: text/html; charset=UTF-8"); + echo $markup; + +?> diff --git a/embed_code.php b/embed_code.php new file mode 100644 index 0000000..f59db1e --- /dev/null +++ b/embed_code.php @@ -0,0 +1,159 @@ +'.$form_name.''; + + $form_link_code = ''.$form_name.''; + + + $current_dir = rtrim(dirname($_SERVER['PHP_SELF'])); + if($current_dir == "/" || $current_dir == "\\"){ + $current_dir = ''; + } + + $absolute_dir_path = rtrim(dirname($_SERVER['SCRIPT_FILENAME'])); + + $advanced_form_code =<< +EOT; + + $header_data =<< + + + +EOT; +?> + + + +
    +
    +

    Embed Code

    +

    Copy and paste one of the code below into your website

    +
    +
    + +
    + +
    +
      +
    • + +
      + +
      + Use this code to embed your form to any page of your website or blog.

      + Instructions
      + +

      1. Copy and paste the code into your web page.

      +

      2. Publish the file on your server.

      +

      3. Adjust the "height" variable of the iframe as needed.

      +

      4. Adjust your form CSS file to match your website style as needed.

      +
      +
      +
      +
    • +
    +
    + +
    +
    + +
    +
      +
    • + +
      + +
      + This is for advanced user only. Use this code to integrate your form into your *.php pages without using iframe. Some PHP and CSS knowledge might be required.

      + Instructions
      + +

      1. Copy and paste the code into your PHP page.

      +

      2. Publish the file on your server.

      +

      3. Adjust the CSS of your form to match your current page.

      +

      4. This code might not work on certain PHP page, thus it's not guaranteed to work on all pages. In case of failure, use Standard Form Code instead.

      +
      +
      +
    • +
    +
    +
    +
    + +
    +
      +
    • + +
      + +
      + Use this code to provide a link to your complete form.

      + Instructions
      + +

      1. Copy and paste the code into your PHP page.

      +

      2. Publish the file on your server.

      +
      +
      +
    • +
    +


    +
    +
    + + +
    + + \ No newline at end of file diff --git a/export_entries.php b/export_entries.php new file mode 100644 index 0000000..6b28ed8 --- /dev/null +++ b/export_entries.php @@ -0,0 +1,417 @@ +$option){ + $column_name_lookup['element_'.$row['element_id'].'_'.$option_id] = $option; + $column_type_lookup['element_'.$row['element_id'].'_'.$option_id] = $row['element_type']; + } + }elseif ('time' == $element_type){ + if($element_constraint == 'show_seconds'){ + $column_type_lookup['element_'.$row['element_id']] = $row['element_type']; + }else{ + $column_type_lookup['element_'.$row['element_id']] = 'time_noseconds'; + } + + $column_name_lookup['element_'.$row['element_id']] = $row['element_title']; + }else{ //for other elements with only 1 field + $column_name_lookup['element_'.$row['element_id']] = $row['element_title']; + $column_type_lookup['element_'.$row['element_id']] = $row['element_type']; + } + } + /******************************************************************************************/ + + + + + //set column properties for basic fields + $column_name_lookup['id'] = $lang['export_num']; + $column_name_lookup['date_created'] = $lang['date_created']; + $column_name_lookup['date_updated'] = $lang['date_updated']; + $column_name_lookup['ip_address'] = $lang['ip_address']; + + $column_type_lookup['id'] = 'number'; + $column_type_lookup['date_created'] = 'text'; + $column_type_lookup['date_updated'] = 'text'; + $column_type_lookup['ip_address'] = 'text'; + + + /******************************************************************************************/ + //prepare headers + if($type == 'xls'){ + require('Spreadsheet/Excel/Writer.php'); + + // Creating a workbook + $workbook = new Spreadsheet_Excel_Writer(); + + $workbook->setTempDir(DATA_DIR); + + // sending HTTP headers + $clean_form_name = preg_replace("/[^A-Za-z0-9_-]/","",$form_name); + $workbook->send("{$clean_form_name}.xls"); + + if(function_exists('iconv')){ + $workbook->setVersion(8); + } + + // Creating a worksheet + $clean_form_name = substr($clean_form_name,0,30); //must be less than 31 characters + $worksheet =& $workbook->addWorksheet($clean_form_name); + + $format_bold =& $workbook->addFormat(); + $format_bold->setBold(); + $format_bold->setFgColor(22); + $format_bold->setPattern(1); + $format_bold->setBorder(1); + + if(function_exists('iconv')){ + $worksheet->setInputEncoding('UTF-8'); + } + + $format_wrap = $workbook->addFormat(); + $format_wrap->setTextWrap(); + + }elseif ($type == 'csv'){ + require('Compat/Function/fputcsv.php'); + + $clean_form_name = preg_replace("/[^A-Za-z0-9_-]/","",$form_name); + + //Prepare headers + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); + header("Cache-Control: public", false); + header("Content-Description: File Transfer"); + header("Content-Type: application/vnd.ms-excel"); + header("Content-Disposition: attachment; filename=\"{$clean_form_name}.csv\""); + + $out = fopen('php://output', 'w'); + } + + /******************************************************************************************/ + + //get column labels, order in the correct position + $query = "select * from `ap_form_{$form_id}` limit 1"; //limit 1 being used so that we could get the headers + $result = do_query($query); + + //get actual field name from selected table + $i = 0; + $fields_num = mysql_num_fields($result); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + $columns[$i] = $meta->name; + $i++; + } + + + $temp_columns = array_slice($columns,0,4); + + //first, reorder columns into the correct position + $query = "select + element_id, + element_total_child, + element_type + from + `ap_form_elements` + where + form_id='$form_id' and element_type != 'section' + order by + element_position asc"; + $result = do_query($query); + + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $total_child = $row['element_total_child']; + $element_type = $row['element_type']; + + if($total_child > 0){ + if($element_type != 'checkbox'){ + $max = $total_child + 1; + for($i=0;$i<=$max;$i++){ + if($i == 0){ + if(in_array('element_'.$element_id,$columns)){ + $temp_columns[] = 'element_'.$element_id; + } + }else{ + + if(in_array('element_'.$element_id.'_'.$i,$columns)){ + $temp_columns[] = 'element_'.$element_id.'_'.$i; + } + } + } + }elseif ($element_type == 'checkbox'){ + $checkbox_child_query = "select + `option_id` + from + `ap_element_options` + where + form_id='{$form_id}' and element_id='{$element_id}' and live=1 + order by + position asc"; + $checkbox_child_result = do_query($checkbox_child_query); + while($check_child_row = do_fetch_result($checkbox_child_result)){ + $option_id = $check_child_row['option_id']; + if(in_array('element_'.$element_id.'_'.$option_id,$columns)){ + $temp_columns[] = 'element_'.$element_id.'_'.$option_id; + } + } + + } + }else{ + + if($element_type != 'checkbox'){ + $temp_columns[] = 'element_'.$element_id; + }else{ + $temp_columns[] = 'element_'.$element_id.'_1'; + } + } + } + + + + + $columns = array(); + $columns = $temp_columns; + + + /******************************************************************************************/ + //get form entries + $query = "select * from `ap_form_{$form_id}` order by id asc"; + $result = do_query($query); + + $i=0; + $i_file=0; + $c=0; + $row_num = 1; + $column_label = array(); + $column_label_has_printed = false; + + while($row = do_fetch_result($result)){ + + for($j=0;$j<$fields_num;$j++){ + + $column_name = $columns[$j]; + + if(count($column_label) < $fields_num){ + $column_label[$c] = $column_name_lookup[$column_name]; + $c++; + } + + //initialize with empty value, so it won't break our grid + $form_data[$i][$j] = ''; + + if($column_type_lookup[$column_name] == 'time'){ + $form_data[$i][$j] = date("h:i:s A",strtotime($row[$column_name])); + }elseif($column_type_lookup[$column_name] == 'time_noseconds'){ + if(!empty($row[$column_name])){ + $form_data[$i][$j] = date("h:i A",strtotime($row[$column_name])); + } + }elseif(in_array($column_type_lookup[$column_name],array('dollar','euro','pound','yen'))){ //set column formatting for money fields + $form_data[$i][$j] = $row[$column_name]; + }elseif($column_type_lookup[$column_name] == 'date'){ //date with format MM/DD/YYYY + if(!empty($row[$column_name]) && ($row[$column_name] != '0000-00-00')){ + $form_data[$i][$j] = date("Y/m/d",strtotime($row[$column_name])); + } + }elseif($column_type_lookup[$column_name] == 'europe_date'){ //date with format MM/DD/YYYY + if(!empty($row[$column_name]) && ($row[$column_name] != '0000-00-00')){ + $form_data[$i][$j] = date("Y/m/d",strtotime($row[$column_name])); + } + }elseif($column_type_lookup[$column_name] == 'number'){ + $form_data[$i][$j] = $row[$column_name]; + }elseif (in_array($column_type_lookup[$column_name],array('radio','select'))){ //multiple choice or dropdown + $exploded = array(); + $exploded = explode('_',$column_name); + $this_element_id = $exploded[1]; + $this_option_id = $row[$column_name]; + + $form_data[$i][$j] = $element_option_lookup[$this_element_id][$this_option_id]; + }elseif($column_type_lookup[$column_name] == 'checkbox'){ + if(!empty($row[$column_name])){ + $form_data[$i][$j] = $column_label[$j]; + } + }elseif(in_array($column_type_lookup[$column_name],array('phone','simple_phone'))){ + $form_data[$i][$j] = $row[$column_name]; + }elseif($column_type_lookup[$column_name] == 'file'){ + if(!empty($row[$column_name])){ + $filename_only = $row[$column_name]; + + //remove the element_x-xx- suffix we added to all uploaded files + $file_1 = substr($filename_only,strpos($filename_only,'-')+1); + $filename_only = substr($file_1,strpos($file_1,'-')+1); + + $form_data[$i][$j] = $filename_only; + + $q_string = base64_encode("form_id={$form_id}&id={$row['id']}&el={$column_name}"); + $file_url[$i_file][$j] = "http://".$_SERVER['HTTP_HOST'].rtrim(dirname($_SERVER['PHP_SELF']), '/\\')."/download.php?q={$q_string}"; + } + + }else{ + $form_data[$i][$j] = $row[$column_name]; + } + + if($j == 0){ + $form_data[$i][$j] = $row_num; + } + + + } + $i_file++; + //print_r($file_url); + + if($type == 'xls'){ + //print column header + if(!$column_label_has_printed){ + $i=0; + foreach ($column_label as $label){ + $worksheet->write(0, $i, $label,$format_bold); + $i++; + } + $column_label_has_printed = true; + } + + //print column data + + foreach ($form_data as $row_data){ + $col_num = 0; + foreach ($row_data as $data){ + //echo "rownum -1: ".($row_num - 1)."\n"; + //echo "colnum: ".$col_num."\n"; + if(empty($file_url[$row_num-1][$col_num])){ + $data = str_replace("\r","",$data); + if($col_num > 4){ + $worksheet->write($row_num, $col_num, $data,$format_wrap); + }else{ + $worksheet->write($row_num, $col_num, $data); + } + }else{ + $worksheet->writeUrl($row_num,$col_num,$file_url[$row_num-1][$col_num],$data); + } + $col_num++; + } + + } + }elseif ($type == 'csv'){ + if(!$column_label_has_printed){ + fputcsv($out, $column_label); + $column_label_has_printed = true; + } + + foreach ($form_data as $row_data){ + fputcsv($out, $row_data); + } + } + + $row_num++; + unset($form_data); + unset($file_url); + } + + + /******************************************************************************************/ + + //start exporting data + if($type == 'xls'){ + // Let's send the file + $workbook->close(); + + }elseif ($type == 'csv'){ + fclose($out); + } + +?> \ No newline at end of file diff --git a/hooks/custom_hooks.php b/hooks/custom_hooks.php new file mode 100644 index 0000000..da30ef7 --- /dev/null +++ b/hooks/custom_hooks.php @@ -0,0 +1,26 @@ + +var RecaptchaOptions = { + theme : 'blackglass' +}; + +EOT; + return $capthca_theme; + } + +**/ +?> \ No newline at end of file diff --git a/images/ap_bg.gif b/images/ap_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..e19cdd549995759f9cf81b22f84d685fdd6d9160 GIT binary patch literal 49 ycmZ?wbhEHbWMg1sXkcJCaNxk%J8u+!vM_*v4u}BBFfehr^kwe2{xOb`!5RQW!3@6u literal 0 HcmV?d00001 diff --git a/images/appnitro_logo.png b/images/appnitro_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9d52aed0990e101c2543f8b659dfdf8319f2a40d GIT binary patch literal 3760 zcmcIn`#+T1_kU)_+?Zj^bx)7srf}OGymn8R{G* zAw#;MOhw1^dDJ8k6%mS3eG0jJr|&=T{ptI|+H39o!(RLKUTeMA+F7iy0J6HFIsgFV zpg?B0O4qAo6#=JO16+@-Q7Pj7z%9uDph5dBC_qxGuR2sqV1zONpe`r<*M_sIJs2Mt z9tr?QEdhWh1b~@El^z3tl$8K59t!}TMF60;?@Y`?e*n<53Su%grS-Ds78iZmZ1k~h zC_s(!oJ+|Tyh8(MF5M|t5Qq8yG{n7G#YW-~Ue9sLOqYT9B~a&ZrU<9JP+k!fI}PxF z@>I4PFt``oYsx&XX34e(b(vHbwLuP8xHJ^qhF86|ftF0Av}9OO=NW^KA41ni^7Hxf zxz=nozz$!*n?$*4L*$~P*@T1|cx>J$W!ttnMQTsIzd z;xOpHy=mU`3V;|Td!7-TMy7n` z-O%Ar+f(`~t~lWb*Do%Eb;J>Tcl?tYDEvH8=NMML0lJ2gC-bIPQTm`41YpVsTp-FV zS*wTm)A#}{mw&0^7EGO5ftGWXfn6awr2^P=ot*eN4r~zD!M4R7`^ok3oS zQw7S^#h5>BLMdY={^JM?5@c>p?aen4E0lATX7!H2uwW%tyb zKjJB-OqY+O!Vz-ghz_kV)g7E4*ZMF7n%@v?<0E$^HFU84M@uFy+ zk9MQvok(i6{TWYxZ~-GPL%z2#pJ{FUX(EZrzrVAx2~BUCbIc!?#hmS6A=A~XQ%Fk?pDzMAAmQLo;3Aw1Nc#9u8ianj&taF&) z6C#P9))$R&y)cJ^yIF@93_^o3TB?W|S|%IQ5AcIy6Gp!n6Z+5xv?yEsM7Q+eETc`) zMis?UQuWgs&=S<)>g13h&OyHtRKX6Wzr{}qdLQhXh1c~k$F*PTRCHaUe*r+AO=xF2 z!Xz19KZ=&WfwdQj64rK1QWL}j1l|%M|$f3jeRF^<+T8HCWu2H&y&fGkH zSGt7KgfZ#07v@}U18lT615?r9aaTzJZmBBaFDpo_D;kmqPurHAFzuD9i&9~Trc)!e zob={C)>1x7MGu0PIJn9qQ>f^1VemveDeu)<*2qU@(#4hWyKbzE+aUDXb&%StjdeYB z9WzDZR<~wU%!Cu_}a zgC+=v*iKr7YiFuq!n24a1=B#pO-pTdnV*JCI(vAlJ-SH4Mvq{`Pe`f4h$^vBY@&Rf#!(x}`7T@^~^vhPON3LdE9 zib8%n6eYp+D8bD$a899#%tSLWJ|?5_IT4l2#m#EGIIJoDsTG^{jnOw>iqzsmhxaj( z(Aww@sIv{4GqXjC=Ik6?dulNNO7090XN)i-QI4L|_y{~^5_+8}KcN}=`Y?fM#wBMO zoay<53hOLKtn$F{dXACyJ3c9z7bRdGTal9?SC!oNfn5i&(a!u}i+#BE_jorTv4msp z>V!N#U}*qqlzib+WEq_hn;59^#E1@3l0SUjy$m*y0pRxk09zV#vn=bp z%^&2jM+qGX4hP|mbFZ~2Cl=ufzZU)d>&>QIph7h1m@1`}VV&?87b&XqqQeZ!{aS@~ zn)C->sL@9Sg?vY=Hb(>QSUHq`%5 z(GQ*#zUQd{VgJkS3tx4#G;s!k3X^L4b4cy z>B!NP|_ZUNu`UfzOy7j#GL!?Tkt8iJuY%^-zsWywIr*c#E! zqb%Jch>_p_Mx{eoFp~-DsW@@e8+$O;%`GN z8)NEvh+nIgP-=vZmj1YX($qTIS0f16VDGeg(VCQ9H~KH{iQ;e2>CM_FHV)8T?cC_^ z^3sJe_x;3OC?97{k>l6L_yJ$N@9`m>)2&Hhq;+1=o474!PiuXHUS`nHRRSM6Q^{6e4P z#fvN(rFq^a6+Q0;ebzIQssvZ(Z*ooESOzZ0v5>;>`|x!*v9Unxv;+BcWrfT`l=yk!|`h0!fwZo>$fyJm1s=jpETDCx@k z)5-|v$J+Vvin`I~e@&uq`La9a)S?IPw;mbYn~UX+@0GfG)VjLRr9WPx>ue5{EFrwC zC{98Ddwt3G@n<^XVU=6)XVlaZ`kJ2L5lhypO23<#%Y+GP!5rVW+R+=oI7`y458Wwt zlbsB}B@+rdYv54NBco5@6z-iPNQnVhYnZ6Vz4M2b?$2h_;7V@&Q<}J}yyL^W5bOW# zB@TG9`yX$OWheb!CXn_dZO@Dhm0OK;KzDVk)k|`9yFN&_UL{y^aK?QXnaC_^bC<+W zudDZD7EP>Pei6d?-T&>si-aIs%@1Xg|GfJRbLjn`MvfCJveMX=Mu3-H$wD?z zqjU;+e{<|)>Xwgk;juUbZFZn?^@8uiG{nk1c5lH>Xw4=ZeRjWo$bUl#UKu&*t*u5} zt${oo&3=wMR}qyN^4Yf}k%ZK~7374+V(@{oMW;hdjEAPF^zmCU>OQjtqcT>@-QO`OQ zB7Sn0ZTx}y<`+OYh@s?ueN8MqOfI zKf{Tkm!sZ?3DycGHcZy%XpcHBu-1YHzEL7@n6?^jzdDEu0 z;`1n!Dxjy&7|1Sjtuf>Ib<+She$;MMxxA8gv)K37VZX;4+oVI)-^9wFWvx-SRv(fW z=(%UgaTA+A{Uy0iH2F1-NlE4{c?(GD_@%Hwc?WQLOpR&b~4@?9Mc>SPKl zK=Y7(h#qE#rEw#KWVkJNhD~ZtlP=XrTd}G6(hpWLnIPr;4cLIHY|~{!r58jRox&Wr zHTW>A&qU_-&Qms{77Pv`Io*Q{%1d~|nR_HLW;tULcj5VFQi}a-*fg2s_o-l$3TL{L zQ1>z~vN<$?*U1bOrB*unhVXL{wHgKB5rb(I<7G&5R$T0Pt7d^)(ARuNVXTam=Y^t@lSCTmE&Z<;dV#HvommWJp288LH1jzn1G}N*=NG3eH?q(g08`%KSV$F2#^}!Q~5f=AGXBov**^k@CK_<>knhir< zIbk}UW!ef&->scJLD_8yNE&))E#R<#I&Hh6H9VfZx=Ez8a-eBCvFD#a?PL{-6Xa^} zF|SbP2~?Hn#7!78mnnW^tV=!zU;gF8r475~8~Ex*f1MNgd)f?bdqjodZQVzaR4;QG z@rK^Go^9oEmguuP=Eu~Iph|-$ffEPvPB4;u@~qcFXDMzZ@y>i$o`S2M-%BF5w6N~v zz$wgac@m!%c<<~we^EcF*XzCi)hiIEKepBTVp7I?M=S1hdRsgmudFF${da}5!QkNY zhd}S$8I6ZRKUW!4NZRDHmSsK+O*|*L0S0`}y&GgxDJ4ytl+vEdmY15m<+bLz z<*jb7;at1+Qt#gb002BksadxyHS?C+mXDhEx}C$hcI|#&+2z6DwJzwF!Qy_cgK}2_ zF7>=30002bEdp&_9?QV3X09dR779SSw!}fX8#pQhv3V?^0K^h7DFOfha9R;4gE9~c z!KehpqE4epPZK>_e<0001-Uk27Yg6!4dWl#G004mV%RuTD z`(;o7%4o>Zqe0U_bMWmy008{mV(`fRun44kt>NHvg#Z8mezySp`24j0p%?%F@V|Tt ZFaVS#nT1#k1`GfI002ovPDHLkV1l%@vLyfj literal 0 HcmV?d00001 diff --git a/images/button_icon/address_bg.gif b/images/button_icon/address_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..f6359e03c0dbe74d25d4ab8f40e67ff4164b6711 GIT binary patch literal 1252 zcmV#3=z!Md*R@93(nuI%gMqoSgsqN4Ni z?eg;N@bK{K>+Agd`}X$o`1tke>EZYH^P-}m`}_I0xVQ51@|sB#{QUf!N)y%A)>>Cp zxVX6O?d|91+oh$XlSUH8#>RU#2ExL^?e6Z5jg6|Qso&q<=;+>8MLFy0;qUM7^YiXr zRZI2s^LBG?xwf^cs;c()^JQaVrK6(C%F4aDuBD@(;^Ef0xw)*Ytoi!)zPG9S`}@1Q zx<5HGU{_67Q&RQ!@#Esy@bT;9}{lM@`uDO~AJ43PyJv6_*zU1ZGU|m~PMLL;F8J$fTt*x%9sj2Pk<-fS8UtL@J`}wL<8lFrS z!oRnop`W6np5^7*Ksz(d!n*kQ^kZRO(Z;*DS{#poc<}M@!^Fhr=G;_5HQ(Ui(ZaOj zn#dI+RbTkS4{rmRz_RPb)+S=N(R~pmB zxZvN@;NRcPzp}_>BEw-HW@curtE%no?$61HYlm>FVjk!ojGPgw4XYQbRbb ztgE_SAm--g|Ns71R#wZ)%k%T?Lpd`S$bl^O;N;kw+Fgwv8o0`JFzFb*Ysi&r|tgP(o!k4rx`z`V8Y?(XX8;A3K6`uX?H!@62WIr{qg;o;%4 zv$TPId;kCcA^8LW00930EC2ui02Tli000R80RIUbNbm$Hf&mf|TsRQGy$uZp!jngZ z;X(j#ejpkb@n1VIg)9zSG2_Pv6Tgx~yuply$bS}+K%?O!hlx5t7>pTaNF;zv^V~tI z;cON;b$E;fTW7HzpjzeTERkiWf>dN_Fx_Ct09YPQ8crYx(=7oi4KQeBGqP~Yj1=Oq ztO!77M2KE&08A>DB8aPj9TrKVN6dwTSnp!+DS^*{3t@!xZCLhC6f17gkno~F;hQxQ zB(69(M?o63CvuuS(o#tYmnPL9?9epoRk}7vc0hm-;m!wsJp?AhLn{LHzr=jb`LgGA^|I~L%MO~A9hKkmtf>B^ z<+QUY4F`f{R;b!}&wNi!K&E{V$dieN3 zRZo8NMaj8K=VdN;Yo1t_F~@hx`N*WXPU~;<^M~@)pU_>lWhkN(M|ZUGl(p;f1^b(*MUAFoQ7dgDo>gD3Z%eRZ(= zoX5*gPgXvPKL7M!%_&*OiNeztOtGILy7pS{<-Mw#T)jkjV$$V!n zo+>;n+I=Eo(dDZ8v$FsH|7RGQK=CIFBLl-B1|5*|L3x6K<3B?yr;Nvj1qYisgtbg& zq#tl<5#D1^l~KSTW)RcFut4L&6nVc5=R!Uuv^+T0ymwwor{K$J>Xz$Ru3ZRloO;k# ze@jDG^J$m427)acyOP?Ev2wBqznL_pk!fO>ZB$6%rj%1`0_)vw1SuG}vJ3L9Fwoe_ zF?oXdA(6X^jL8$Y6D;ydG@Fi{k&5!N`w$iA^gt^}W`e}8ql*vr`9;eun9!uru)>Fx zt?Os8=e6mIT1mPAi%)tn#Ix5p6a{Z!VB)a+@L?uPM?<60X1|RG9G*Rx<7V6-z#*y= zy3TAG(^tU>0(`TD?PtC541N*JVXH38wIbE=f`q$Oio-*X&XW_}&G>pn9$6R!3R$f< TA-rdix2>bo#k<8k91PX~#?{2; literal 0 HcmV?d00001 diff --git a/images/button_icon/date_bg.gif b/images/button_icon/date_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..e9624aae5f585e5f8b3c59a301f730b26cec7cef GIT binary patch literal 1211 zcmb``{WF^f0KoAl9@VI~OjXr%mzdjh!-G1f+d7PP?Al&Y@sirOMyRn$JLG7(Rzy!L ztuke8sY*&EXc`qof@q}iGU6>tDo4fp`;!+U61)Bn`~Cr+-@ZQwpY}NsXA9T@TMEEn zFu*Vz6B8329J07sIRYYXlP)uSUR1qudlDFs;Z`@ zMl2RLH#ZLt4_~@;X?}h_GBUEdx|-Uz%x1G`G@6Blg?dW^k+_qSlRO>|q6*^T;NJnPFE_Ge5oumD|2yiacOBOK0aQpR+o&dl}Oh!-pKKIJnq@h`uh6n>T2%2f|ZRm zO3xCL$-J15vy}j-2?V-O~a&vPD1OkOZArSI{i@Vd))7#tI^X}i3 zNF*`8r}Xyr9w%{ly#r9@Yv*Im!7s*PwNfsZ-~0Qaa9Em@l$0ZwSyON1=jXQ#43Wv? z)}gU?qwlYa7V5 zm6a8g#)d9ehK7c6x!jKm#m>$Sl=p6aX_?Mo6!kA-o2D6WTB}(#THTIPt%80nBHv)? z4f?P$giiTr=hSLz7P8uoW_ZXiAPT! z<1$zo*U7RElfH@Nuo70OR7FKa9sPqprqN>x$ z5K;5qhsvYmW<$JlJtV;o5 zshjX-Nvj;XR)3>&c4lT~WpyPgD(cFWD+L7wkGtpDJ#%||d%*u4Mr(`!00rRk3I6m1 zfZPMRO&x;R6#~jZw2fCTS|-S5t882jo$Y`7-C53yN1>EoTmzj6v;Ia*iLIN7NoK3U z6!$cQ%WWpY({DYa&LH_7@d>exj#4ZUrkW!kLw6F79`raPa`R)Dl;?#9e{N^@G*I#? zFyFcyd)^E2Z6$sR@*NSy9893fXouar5*Mx}gdK-Y5Rf)s{#$HuG@=3#TgA$6@Eav< zE+EjSoNxJO>Q5Y^4txKetfDbrS6j8bnVxIly zK1-+Yf9O+D+lm9$jNroE98XtF3(fr+UYrFS&Ow=2d~?17v45@@4Ir((U^!@PoO;*j zK3Wo-4mhBN)=75$2+(p0?Qil~Y3xtNmR_j+PUb!we>X7sW)}u@a`&T|y4*yVn7O3R v+y}3N?;IaQqChiSWQC&ejAwTblJTG*+6-~w@@#Qr<<*XWi?%i>;QRjox6WEF literal 0 HcmV?d00001 diff --git a/images/button_icon/dropdown_bg.gif b/images/button_icon/dropdown_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..e6c5dff072561b7ebc7379c250909554fdddc35a GIT binary patch literal 1234 zcmd6m>rYw-0L3q$n^Wg&&bH33NLn{mx7emxoKu5MYhUYP6X)i#INNE{W&2RGuIcun zMV+=bv{TbI*2F}O5d~i;^MQy^K;@-~aOGBn%gZZp;qsD)_?XT9iT%EvFDK`mGUa)NG=j76bjJm@mQ_4%}s|&rEY5*L=d#Ue+qNCM~3-2or%q! zj%;ruh(jh@@%j8KE3chS_sonm6bjGHElH&sCX=Pn=y*KY__#=|h8PSk44WZn9fIJg zDc*rEjn<>p!WOf6Z0r>X8ft2O^ZU1)s1wo}OeSPtV8-L|LXg4XaKW&3VnV#KvbMMg z+U=;pVCwE>^Z5#aKqeMTG0ffGKD4w5DwSHlKNyMZh{f{l?QNIKGe5s9k*GmX*Vi{O zIVl#4l?w|iT&|QxqlLrULqlwdWQoI>fAFAABvNuXb9OssG+I3#pI(1Z@RdNI0KwN> zu4I78U0X9QDnPy7yc3CZclT9QRrU6cyIk1x^n%;%13|4)sWF*0&1OWWGY=2*B9Vwt zC{ZZX!C*)#RdYCEi)C|UWVW+&j812$RM7tZKJfo0GaQ8j04b3DCgz(@05SVOG@0@Z zIsQpuUhb!)o4?9hvVVW9y!RYY#ZlLw|A;4__?d>!%+fc%LnKmVPmd)h z0oQvPKRNzgzRkwR3I9sJQ&L5wJOg6!`ALUi>dDl>@=JM>={KT8QTQWC8N_Q8LVfhH zT=Y+z^a=TcrwIkdpP0!>l!8Duk%Y?WG4Fr9P?JI~J9#9DIKs~)6gMSj#x$KCi!DBs zKXIQ;?fL3u>}QnJfk~33ltF20El8<L1!4WF%YGPJ2xeR)oNGR<2b{J}@uU$QnR;X@G zp=s)+=kMNAuqtb#<5F)>Tb>hf30dENTvAkBQQ|JT|7@p~55y-NY)3c;*AhPDmXt^D zo(jQ@8Ti|EaWh)VCE#$tm;VB@Q=kX{ literal 0 HcmV?d00001 diff --git a/images/button_icon/file_upload_bg.gif b/images/button_icon/file_upload_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..358834ba36d0e1197f4ea6853b0ec45faebd2d5a GIT binary patch literal 1244 zcmd7R{ZrF*00;2z#xwI_P)C-KgY%Sv?f~Ma^VFq; z#ACrwbg-a9*m$Uk>;dFqJdAxeHeh4GU_9;7Jpdc~?)xG6FM9pwZc-VNF-WcUpE?!R*PkAZEbaR zRj<=+Zf+V31{j9t=jV0n>pGpzZnrNlFTboeHa1pPRt$PQhr@9=98#&&jqU&dR+g6q z0)bYm-QM1wo10T86vM;ATU%SRv$NCF(-MiKzrTNMY)qs=MrUm6dSljOz~k{I7ZDUi z3z?Qt<;M87T)hf+^;4v$ zr>6~eow@@q*Q3&@dAVHP+1YvQ7SQONUze|4VWRKRfl{fI$(8RGf-V^nQ4Dh14Ear{ zR3=kQO=U8+iW;4N525jQ!Sz;W!ub$H0}3HG@}l! z?9jR0?p_{GtyW)UA@LPJq;$bk8lB$E=tUM57I;$E$s4Fnuh00yoKXuzBO?=Yh(IW$ z)bbGoDP)2C7RQF&9!UrFT;tEBy(*>hVjY@QI?>(TJt|cV%%B0;ZjDCMJibjV0Uyzj zYfW3QLj6sJt$^iV@Q^-{d~tD+(fm(V#Zpk7oBoi0pCvwDZf3LDjs3`lI&iK53=Iw4 z>OlE?{{1KOWsUqQF1W{1bPM6{+CgBJn>~u!Z8k=)>sOZSuR+viwa%(knRV95$;olC zcxPt^`de9oxBCgmcL%z`4ya1RReb&vSN)c(_0jV?;zCAXdFDM<0+%L^ z^WbPJKh3-9>l$b&Z%uFa{fzee*}%@%()nD%rX^`#oL`V9K8j4FVm)czgHY2VJ-Icv z>J&5Uvg9F&`aT&ZC2_vJG!HLze*sAzka3CZD6BLrnjdD3W)AJ&+m78QiYEw(ez@Pt z_MFIR8F}&srTGAk$hDmFJQ&%~(KJxT41FLBzj^8CtCX=CukdUF6@w2smg-j#NG}Z_ z7yCmLC<6mwUq6!Apo$s~k2tq!!aiKKv|U?L*c9ebN$ppGv1Qa; z?_fxX^~)tvAy>Sdf(wWx1Q%h5WkhHNQ`U#WABU53mlXwvybh+3PJ6yR0B6K#L+}vI z|F(we(?t)IgLrBDYf2Np~0-!+6HS=am`Xg)_D1Z zh+17~&_=5kE8wc4vBIP(3Szm9DojNKhalqQQW24(Q0|enzhmzoc#jVYBU8tsaxf9g7_-FFT{rxWfS-93(b3eJ~sriw*Jkfx+NhU3G=SF|*kd z2*k8no89i)-3_j+IHgjE$rOh|Q5X)kv`j57IwO&|NVL4aAGv*-GcfQ5g4|nM`xeV~ zBoY$}mvlP&=;%^!uWEhWYcy_kb;HWo_-K&E{dTW(Ehf zK3}k+qPM^QjYzcQ@dO->U7_%wzCMlB>K+}{vska3PT1vw=jUw;3+oW{Rwy*+bT+x% zLZ`oMYn$%tQ;m-s0)c2lgRrUT)$`}-p&{L)M-wF_?IhA;4o5|$@^0LCGCaJX*E>|I zHHE^gR6>)JD>~g~f4@epUJC@mGc!iJ-FyE&Ppw|pXlyk#BN~l07K=Z9ItRm%*;x~T z&>)war>9rN;uSi5Od$BXx_bEDJwAof<#O#S6c!@!@zj)&&(|oGYsJOvo*t!EYmrEd z&z{Na>I5>Gd3N?abk*(N>+F;^H;*$IV;voH@7_gNEJQr{EwF%K_&sf2=Lhl2OmBGpcBBg6x_usd@|VhOI9fv^CSDq zAM%gYDyqtwP)Dy2@mz$8(|V{{waj&*03DQ?*F8z5b znQFiloi0RWlr~{-1*wJgTtejubotL<2Otop6_(W(6!X$f#Up$wgZ}l+WQG94uTMu1 zuKvZ{*a89c+3R<(U1w4+pFESt`hr4wP0vX|rcsGZgE56rv_ZbgPip*z^sBZ?Scc6x zfpBA@`Q=HUel@hSrOi|_nI9J-?@m$L??T9~{D;T!%ElKL{$O*Cqt%GZ$YgTXG0IU! zD}ol_K$+ByjP&!LVD}kbt2@9wrm#vF&v7 Y(%Czu?1$Os^29|S^{i%;gTVLy0gML^tN;K2 literal 0 HcmV?d00001 diff --git a/images/button_icon/multiplechoice_bg.gif b/images/button_icon/multiplechoice_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..d9c5108b06e0847cdb4f8c6a73a65830ee686856 GIT binary patch literal 379 zcmZ?wbhEHb6k`x$xT?V5Cd0PKYslF`t|3pUw=M-{*jm7^!oMZ zj~~Ckef#C#zkk`;ladqLzkL3>cklU+A3k5aaO?g1uVqCOPo22>{Mp+>hc0j3dTQI& zW9QG^%F5_|@#0-&+2pMBE}+Q_v;>MjSr{1@6c}_smVo@kz&68SLV<^lRR0MT4aN+s z`2h}190C#RZ{)B$i1O@vuwjPv8m)894OM5uCbV8X#e7(xTQWc3>*EsvHyRk3D?`N? z#ktE8xm%bx`Z*eNIC|Npv2`V|^|H=ooxWf?YcKm!_IWGjvG)o~39(GdX6cpT6Xa#t uxobCXuN=QL)5a{O-iX~NSdPX<9A-S78hI%~pwcJshHtRfox67(8LR>Fnv9nK literal 0 HcmV?d00001 diff --git a/images/button_icon/name_bg.gif b/images/button_icon/name_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..c0c1efcc0b4c0551749c1797a992a7b000e64339 GIT binary patch literal 1169 zcmV;C1aA9BNk%w1VHN-u0Qdg@`}_U;{Qdg+{QuLLy1miK%i7t?yy@xkou9+2uf^Ef z<^RWp`T6_({r=tF>i^D?|Hz5FyxP*BW|Eb;`S+Rd!=koIQx}9l@jk%hoU@T& z3AVY;ouRmEZ=RiM4$;%%uCU0}*5aXY8-RqXx0z@3^!9E-0>+z2tAstqsCUAhSO4tE z)5f=TNCV%+plEBQ+uZ1(eod@^F#q1Mxw+SZgs_WP0GMbL<>&0Qw#(bx=9HPTijk_; zv4Wmx0mR1G_~XFL&E5aywcq0A&8&lwma*L3>41l#prpNUbEI^2tk>D%?ds=te4wqc z$F{l5x4O>F&)oR*?Dq5T@4}AP*yN#$i-J`O!o}6l(csnA;m*+AzLGw|#MaKx+_}5Y zidze$ewJ-s)*s!!{^+|>)yx4p?1lmcje{qieoRr zqGq&!9n7g?tF6iW*Qegp%GlZCjbIq3h*sR)=i1xogNUhximAuS+J}y)e^(*%+O_w~ zme{wA`TG2jXC|_NAf#~-|JbLNX&$D3JmluM#Q=fTa--;``B|Kz;4kW0OlN|2SXeu1sv z;q8)^v6Gjw-rwlZ(%;k6+Jl3(^udJKwS51|i@Uqn*vhtjPz=efga6#Co1VdXd#%sV z->k63g^91OvB!Z}9Jjj7o}#?WxuKw>y3EephFl=c&)sQkotkJ3XltRFow%Eyxzg0( zWoexH`ul}e48p|K!J%lw#np$3vDDS$w3KL$k-3qSxa{rm?CkQGowu2uw~dmnjgzjp zyU*3v3#SCC12+7j9UmXZ-v0_Zd$bs<0+_L5^in~@!Y}k4E4~dp&E2L0T zQf-*4a6DmgiWTfhDSD*HrJBJrN0m(1t`IXs=0zt>JpUCkHJ}A69cCm!3Hy&09$nHN zJlJr80$WFn1}s>BLQ$g(Z2uXM009CtG;jj{qoF5Eq*JxR;_&q>TN@D}oF(B=;)01! z?Hc++7bn-Od^-sA6BSR;n==UN-6M!E(Hbzy(#h&J2N$0LQ!clzdQ=OY}$2ERZ7{H7GxX{2q0RaFzXYabb literal 0 HcmV?d00001 diff --git a/images/button_icon/number_bg.gif b/images/button_icon/number_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..7c349badb948266484478210257da9fb4ce9a69f GIT binary patch literal 1088 zcmZ?wbhEHb6k`x$_`ZPQ>({S8e*Cz4^{Rq`!k<5X_V3^S`}c2ERn;?R&OCqq{MM~o zmo8npe*OCP?c49&ySIDy?tlOOm6w;t#Kc^~*~R{?6y$ zpVzNnUsY9QZEd}6+qUoDzpsC`UVnks*|TR24GpinyF6{$wAHIu|N8ao&G$D44jg#& z;h~F*%lALulg`C!XlP_)WZb`h|NYPRW?PMqK0C5}`EuSpoB;s=OCK-k>+9RJY17uN zTeY>dj~_qY-Q8WWzvS+_J6&B}OO`BIwrp8^eEi9`CyyRI`t;M2hYuefI(#TUKR-P^ z{m!m;e0__q4RMe*XEn<;CWek5+7Yu+i1k z_1v?weaE`rzklz$*0b<(LE)u>rAwDSd-hCrv*fp5UnM0aYiny?y?XWI&yTxrZ;Q_0 zzwrJ-<-W3Y>(=eswQJSQ<>LEAC!Fi^^z=+hN(v1P4c{2ta=7u~=LcK1Y}x;2Us+k1 zxw-k{H;*5Dd2s5~sh>Z8{{R1oxi?7g)S2f8KrmefP=7JC8rSdjIprgLi-a|G#qQ^}qlBpT7R~;Q8l|U;qC6^Z(7qUl(q^ zeEs3)x1awXKL337+Vf{`zJ2-e|N8y6KYsr|d-3kAhwtw_{rL9N@0ag?eEaqP`>+3( zZohi<;pe4m53b#Nd*afQ4`2R#`u6YSxmzbMKRt8x*{w(KkDRy)bRNi+IDq0$7DfgJ zGX@=yJjhQBY|kBTXE^AHC2wshTDgUj`9g+6(}4n!o~aKVW^l}5&YY5UG;3$v1_`f~ zMGouFlqvnbb%?Q{?)>xWn6io_kq`wnc@{w_IpfBF+6mR&eSx8x8VUyLe1f{dT2fL| zCQh8+C(;t4sm?CT!pF}qsHm7(-oK=F^AtuAE&*0nQEqm2F;#vOLBYj4YgAOG2=S`% z9$@1ZJu0?-~tay^foxP@qTfvkSI)Ywbo(jkn!B4;wkOOz+epkxmD<< literal 0 HcmV?d00001 diff --git a/images/button_icon/phone_bg.gif b/images/button_icon/phone_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..54d1dd2f481e7d993d4da91ba3d95f0cee268291 GIT binary patch literal 1064 zcmds$i&N7D0DymTVCqqaXGgn^%ST;ZmgRYwWq1L%BjP+10TUEq(_bw!YMRIxf4sXgO&eA-+%Dkecu;f=6>=iA{|Hv zp4xy!A~CTP_b)!W@Pk@vozr-idwfw8+j@;PRLe2di(Izwz4_>tV{*kBiSmt8Qs@D> zCs0Gz79e>5sXg=o=b5?D?(f6p^trVI+K_pZ=~&o^|7?W?6N zpyl>Dx*cL@-1yG^`VK2JyU`bTh^T4f8@z=mK`CJn#kAayZ%KxygytExK7?rC)iL!K z@dkVNS4;&(1*Tj16wtLdZ}OMUap{-E@8!AbL}NqIcRi96n5k_DgM@Y zUNQc31&5$;RdJl|nb>u{5ycsmjLfzVOi{W$MaWjNW}*PW#jE@*onK*{DJKsoMrXJK zlf@Wi1$B_z8+6b84lg1p?059R4J66X+-b2-J^YqqWU$qa$XZQ@o2;8vL3hK;@tfKp zRpmv~^g?5#ypDa9Y0*FnXo6bjTdAOpY;SM>vz5?#79T&`uI4$FW9vx9C_(9>$elOD zmj1x%IRyQN*j8D~k8Q+Fp$EA|%}hgxBG6sM_vDw7RF2s?p$CDJwaB10m8Gn)kEa`# zyVkILtI8X7FaBAG(|y&{S4uR=hQd#tK5tQaev~>I1U7ScjV>L^FKJ}zf)_CYk?Cjm zoz42rF@u%R;Tf zd*iJhb~5oKWw2p4&-GDCQgYgXN=n8XxD5XUJo?HJ(wWz37f8?~^<#K$CM+#BP08PR z;>b~WRW1wmLHj(Ym?*fpzbds>31$BxJ9#Qq(U?q#DBmPoV8vZmruF+&V_DgU5U(9N zF3GRVojntv!|PCwk_bnL6os&%*Pw7o3~fbF_Wt*=dU|%)j{T!qij! z^Uu#-dTIWm^RvtMl$Gr%S#xFil#{*dFR#1w{Nl{hlaD?)GV}DrX{RSlJ2mm;=a;Lm zES-6J()z0_i+AO(yu7USaMOh2-Szvcj^00V2~IeEi&#bGP1HZ#&d@>Bae3 zXQ%DDxnt>txr@)wo_lV_-n%O~ zn0aQ}tkaVwp6r`&vhUTGm)%F&HeFk@?(&*-*H)~*w(9u9qbn{insIvK?6cEnotZZA zL~s56x~WH}%sV%${Ydkiv(tKxb<8+Dwf}f$>F$EcJ*73h05@_iNqNC1@Pw>F~|il^kgtOvv8>HpOGc)lc~qW zmg+KtLC}~viQB_p^hB0$O01nJ6z$)_W9R(xqs~AxZ1-x#hdxq{QCd5 z7ESTuonpsuWt!iQ$0t6$k=PmG@bcxG{s2*-&^7N~K3h{0wxvDo$7kvL_g_9XWtip5 zaC?T-$LIH7#pwPxR{r?B*c2DGAD?CZzc}`E9sAB)hEvm9s{%~_8!@cPci;@$d92HG zc4y&FLx$CP)|bBUGD~}#Lc+wZHvBQdCV|Bof&r-7k1^*slKibGKJDly; z!+pz>H6ESczcGd3hcUzd*Tp}k1-`m1eq~+fqF|x_7kg%h$^7^%xp!md|Nhk94}4eV z*-uRK`2T3;{|`4meE6~`ne%s&#qF80|F0PU1B!vFK=CIFBLhP!gAT}4P@FKZ-)cy0 zYHn#}v1DcCZ|!MiVG9jnGUVv(?PpVGiqezqp4P^utjc7TWTC~npsAl*fhj@B-Zo&> zg0&G$(UF?Yimq&{Ik?@KgxF1NoYWYZ7jPtM9AoFw@p3tP-rI^lG#*&x$gkj_;jr+~X{T7OI}AmWC-Mm~G;zs# UnY>uA$fH}%_moJ(0tW_b0BhR)D*ylh literal 0 HcmV?d00001 diff --git a/images/button_icon/single_line_text_bg.gif b/images/button_icon/single_line_text_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..879391f435632a823c7a2a8f95702f55b835ae3b GIT binary patch literal 372 zcmZ?wbhEHb6k`x$xT?bN|NsAnhK60ccK!VMlYxQZ+qZ9j|NZ^*=lAE&pMU@U^Znbm zUq63-`TY6I=P%#BfB*XzDD?-(`S2uw`juhJlorOG{y@0+UnY;(!kcH~RV)Ee_Ztnr-5_K|+Uv zk-4d^Nts!uxr&KhguS7cQ&E7OlT$!SdRmtPzhr}`kdhD^+gvtL{v}-uYZ}(9->_lz wTE>mr)@){2w|(Qz-Fw#W+j`(&=8-)+k8g5jJbUi^g>$}_uUx%$#gV}p06V;>1^@s6 literal 0 HcmV?d00001 diff --git a/images/button_icon/time_bg.gif b/images/button_icon/time_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..4dcdb764f5b73e7ce6d0ed1d206ec77e50beae85 GIT binary patch literal 1277 zcmVr|tg#|K9Ka>G}Vw();=O`D%it-1Gm+;rZb4|Nq;{ zg0|*!eU4j{-1Ynap{1;>xx|~H*4pm>?EL@G<@ovi|3GcBFL1T`t17u-r?o+ z|NpYm_wo1srqT4;=lb5>-thbX^ZWms#`49>($?z!u&}ZC|Nr~{|8|3!-u&L}`sVikl$_Okg_eenpZU$h zwA1pXr_GL@#nRyFd4rRCgpoZ*6_>O<;CLu%jEp8ck|)4=)D&n9HGb-DUqrReA`||L)|+$jL*8)63uX#oGAQ;_kDvwX@av zwbl63)6%A37N@ zO;JKA%(rkPCZy7%ffF}RU;Z(ugY3+?5d2WslNE#n2@wgdgy^x!*Q_paA~@4P1VuUu zM6x_-!DdkoE0-{gYp|-o7;nOYELb3~MGIN@yogw^f&_&nOF%Vqav?&734v@#5Hf%n zgiix>w9sLL-UI|_c3h}cLdV_z}h(5DoIc1HZ(;B7Z}G1BU{5bl?y~kF){<40Omr4LYNs(uo4y nxUuF(3^WmqAyBB0L;!`rl1MureRKd0l2k#3Keq&vXg~lv2Y(!U literal 0 HcmV?d00001 diff --git a/images/button_icon/website_bg.gif b/images/button_icon/website_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..c6601da7afcdc99f27a5a65dbf90a38fddc0bfdb GIT binary patch literal 1322 zcmV+_1=adTNk%w1VHN-u0Qdg@B0q>qVxTTckHE&^r>CdU)#-teyiaAJVs@*duFZ*; z!JDYc>gwv<;_Y;Ty8HY4DMpOQ&E=)6)V;mFpQq7=lfl^C>x_+(J64)ycdq5-<hLtoWc$-eGe~w<>&Iv z(&u`AjhUy&MqQoL+319ny!!k61}AvojGDr*u&`=7&n49OoWu6#=5}W zySu#G;OwWc(|U@w_V@aGjJQx}rq>RWywyHfmqT2em!Qo> zU7Jf_p-f_-iHeP2ZH=g})oE>d5ix(t(B;(B)Vjjo@bdRMRF!{$hCEf5vbxz?Z>Kg> zn_+XNSY(A-aH*!U&tGz^(b3UwfU?b}j-b1{yCgk*QfZ@U zd#_h(r+baJa)h(3x7gj^@WjN#frz84wAEvIwPbm;xx(3mlf93e!?(cN!^6YY+v!$s zs*|C`+}zw&XsIhmj@sSsZGE-d-tOGq?v+pkOKKo;0;I2-5_AeOuf?}i8w9>MAVD6HYbUyFLop`7I14?9 zFd0Sxfj}X@@{p=#&j5=Z`x5zbapO#uFau&)Vt7JEC|6Vrpdf(&0f`+O)F{D2tcine z9R7)r@dUsWD(tSPsDv!n0(b?&L|Ega-id!IWB`!DsZRlM32>09c8iCNK~2^;z+&bf zk1yp`kgG5tf|52LY9L5*uYx8`bI@G>`R4(U7c46TP#NIp8i{;65BCJ%&jSKw z(hdYrNMXnlXN15*DFNVs4**}RU`jFnl)ykQ$6x@#D7O63fdT1caDWPv2q1tq=$H`2 z16vrw2mp%M;D!PooTI=8i6mnO3%Jm7feBh1!N4;FZ1Tu7Y$yPOHG-f(hcyaF6G$T| zurk6w^k{$$0ivMNiaMXflf^pC=yM7jnA9+#35@aU> z>wg7>zLd;)8LQUiyxv!!bG{_^e#N@?HShl)SWw`hBh`OmNzut1tN9mJlz6S3C&9tZ zHPN7Oturgrrnl4fB|Km`IITy8)8)zT0tG4lFE{um1{~oORuU@X;A?8hY0p%tEap+J zX<&%p<>am6;NlV#O6KR~QYz%<=j3KsvTQ|<(n5yW%3QqM^I{8|M60%}sLZPrVVJc> z>F`<=5e|Na%BDkU@rBA&X)8HIMI$B@cdfY7b|kY{fK#C8=!NYZmtQIu=HyJ^=HYuL z$ng2=^B(RGA9$70u6DI4h;Q}ah}bymz$?nkY&0- zrLD1LBB$5Zs+?gF4A0MBf>^;wC=ccE}n2oaUo!Pnh`S}IT-EzLW cOrA5W2woj`cGuR|*Eb}ep66R#%E4d_0E%SljsO4v literal 0 HcmV?d00001 diff --git a/images/button_text/checkboxes.gif b/images/button_text/checkboxes.gif new file mode 100644 index 0000000000000000000000000000000000000000..5ce4882a0e317187c8fe33ff98d420439075457e GIT binary patch literal 638 zcmV-^0)hQUNk%w1VQv5;0K@UQ^iWLRbUq!tAN0=U_;S0|1LWC2A87{Ex`flH?n zjgm9Ml$#>^H40|3RERVxfGT}pXH1r}h?0bv&|0U!WC zfrBgnvJ{1yWsAXqhy1Zgi%8Lz0BX8I^204}rL-1uc`E>@l@?K0&L|K#r?TbCm@{kM z%()1J&!9t#9!C>oFt6nX-g6r3?W6PdRySDAyxO3}{EupvX-@t9_&b_<$@8H9WA5Xr#`Sac*s9(>%z5Dm@+#35@aU> z>;DC+eJPpqGFGk2dA+Yd=X^=-{fc$(Yu^7qu%N(0N2>qClA@D2R`V~cDDhf5jbZ8< zg$+tFYg~003|6Rwh%(IR5S7(p6=bwdkZ^f<(P_fJb)~sVtfEEC99*I?5s_lN1su#w z^$jgbjbia^m7Jo{VjQBp^F_HQTTGwM#==r5wl-olW9KsS>CH-WBG<0p6&bU|v@t(R zY-0KDBOT>prw^DUrKB~9wy$Mkj^Qp~BiH(bo_bWIj zl{jo#a&odpuFo^IgpH^X!Dva_=-ieKG1xq12d`DTh7vR+$OTwLriSu6I` emX((m2`%!P>$P>&)zuN3v+kbSs(n>}!5RP=NW-T9 literal 0 HcmV?d00001 diff --git a/images/button_text/drop_down.gif b/images/button_text/drop_down.gif new file mode 100644 index 0000000000000000000000000000000000000000..d5e2293f719b280790abce6bd9cee1d5d266ea33 GIT binary patch literal 576 zcmZ?wbhEHb%wteyIKsei{?_Zy-+tYG{NefAuk*KFOK#sAUbkcQ{yT>+KAXJeV*bQK z?TgP;&pN*S#6#PR<(|bG%@P+n<*YV|pKq12#I<1E|NsBJOE)v%28usfz>+#35@aU> z>;DC+eJPpqGFGk2dA+Yd=X^=-{fc$(Yu^7qu%N(0N2>qClA@D2R`V~cDDhf5jbZAW zh6AV5SYuvub2G4Lb;ha&*eyS*yT&6>uwz5}0f)qs?0m|l5gcr)q722Q%9YV#Oroq} zEE6V)##FRV^eR&7FVALTVw=p&JWVNnSz=?yTv4SZ%edJ^x%-xLOo?Fb=kT5*HYZ|Y zD-$Cd8)KPRBpYjc+uDQc`xwQ}bMT0=pBLR%HGkr={Z}r}SGn-)%-WZ0l;^y>aEh~C z^cL^)SDpvv{d)cL+5{?HOYE!dozVSrF6O_IE-YnSk^z;nl?0aW+Zhn4#fphXa zhh1A+#35@aU> z>;DC+eJPpqGFGk2dA+Yd=X^=-{fc$(Yu^7qu%N(0N2>qClA@D2R`V~cDDhf5jbUm| zS-{~gEr!*++#1XxrmWYQ#LBhR-Z%t!N(g*yYArY+_eG3{Ej}^NI4)e2k%2LisU(Jl zk(*PLU8y6t%_t(OKrDi%T9iqQbry>f2jh(Svt}Elq^(t+HH($4eE!VV4f-7_2eu{h z_C{^V*}G5ofbyZ%+=!}4q+`GkA({lw+kqH&GFc{=xDcuu~W~1jf;=>D>!$_ zcy3y9a+#35@aU> z>;DC+eJPpqGFGk2dA+Yd=X^=-{fc$(Yu^7qu%N(0N2>qClA@D2R`V~cDDhf5O=@aR zS;E0Ct=?(nEPlP2PnEYF%+t`}TBo|#>il7i-92$vqPZC3E5w)?M44E^MO9KG*xEW` zyOo&PMcIoOBN#Y3S(ro_*lJwrk~6sy7B?%E^)BRXi%I6((8ejoxM)EP^R^|<*|}>c zXD;aE5am%>ml)B=vtDTdYkj-YRhIQv84ox`L`_~^!NASPc(PIX?4*=)k0zHZu{^)j zyHM`w zr@9_?g6s^Zzc3jua8wt%d!S+UHq9_ry#+i5D_9Sxtz#ACY2bRidbwiQQn7!hQ$3C> z=Hf1x%E9nzf|dIOA<+#YD=w*8MjxE=QzUDusC3;qJI~eIIB#z&czi1L(}Hz(cUOFV zb@%l4_4oHTFh5@Euw%o+!yUrfac6dHe0+QYzxxcIotvJXo?)DQ@6684&(BYj?U3`` zwdLjI6~U|H&hFa!`jT+c>3P1px4pf+qxki`v%Af6ISw>)%lqxw@$vDA$=dPfYId|d Yzp&VQzTe(mUtizYoPA%+#35@aU> z>;DC+eJPpqGFGk2dA+Yd=X^=-{fc$(Yu^7qu%N(0N2>qClA@D2R`V~cDDhf5O+)l> zhro&z8Kc1A{ay ztb%D?Tjdg_Rm^Hfq9d5IIhD$pPfSZ=ZHlPpNnM_%dudVZy!{g^Sx-bAsbE=>ma#l) zIhX1M<%n4?#F!X43IrFNJ;anKwk5(N!11zUtM(qwRSXWXyKD>Y^-f;A&Y{sd&*R1J zhz;QzE2~}pvj{x+_&`D|!G?89M$jd>Ue>D*4+>8@vm;}|CjsZfhN&CpR>Zk|VbZ&~ zxX$tW-8(k|=6SZw(n(QmObyYT#lX5w=Y`S2j^yY($)(|p()w-eTMm@Ef0a1eD*8w( zfjObEVeN)pqN`>;kJ>g_YzObE56}5pySN#cAI)lKaOTQ(QTSkzW_+le$sqHS4O_!< zMqAG#SiF~f_Wu6<;k@|_|NZ;^{{Hd#_5Jhv z_y7O@%~Rn)1B+P3gGLUu6%TZqc+6fTH1fM>JZupO%Xru-k+$Mtn@pKUB8x(s#-k3E UX&H|?HI}V-)TPrW!Ngz<08z6t6#xJL literal 0 HcmV?d00001 diff --git a/images/button_text/name.gif b/images/button_text/name.gif new file mode 100644 index 0000000000000000000000000000000000000000..41546ad8368e893699c2a380eaa33af1096d89b6 GIT binary patch literal 474 zcmZ?wbhEHb%wteyIKsei{?_aHTdzHT`!%_JZ+P8~&)0M3s_zUM1t&OVEvz< z+Lw|!FJslZoY(sbbk3LL-mh5qzUKY^0}Bc~bfo%EEGasfV>SQ6iW0B2(->M0b}(&l zViY;D?R9CBCZphXqlf^F))o#KfdC%%BXbpkZZPts8mEgiW;3(0F;-->Yf?nncV;IfXDt=k$(XTGe-C?p zHW%xO-6DHM&z{LVqPs`*(AlU9`_E_R)rda0qH|5ODmJex@6NurT#1Zq9FHDrKJAEQ zPM`bc_S@@aEIzBg($h4tL3VZ_~NXk#Tud?CEW5Z*MPnd}^+Dc`gToH2^aL B%+vq? literal 0 HcmV?d00001 diff --git a/images/button_text/number.gif b/images/button_text/number.gif new file mode 100644 index 0000000000000000000000000000000000000000..1d777dd158f1d0282d1f89d7bfd3535d7e85b956 GIT binary patch literal 509 zcmZ?wbhEHb%wteyIKsei{?_Z~Z@-4u?YRB;!{=|mlH2zlzW8kWiHGyIUaOvUeD(f2 z?TgP$UUM;j;vw6N<(|bG%@P+n<*YV|pKq12#I<1E|NsBJOE)v%28usfz>+#35@aU> z>;DC+eJPpqGFGk2dA+Yd=X^=-{fc$(Yu^7qu%N(0N2>qClA@D2R`V~cDDhf5jiKex z3Z@N=T48s}H@v;J@8Rw3O#+2?)3z)%GAIy_Z*cfxTd-A$gGH3By12BYAv0T)w>T|d ztVmRpk#WkjmYS)|v&48}xF*hEWY1KtoyxShFrk>Gdiq9|*{n<~j7nwIby1=l+Llie zWtzTd!rFq_rw^ZDVdmtlT5@3X^7Hc@nz>}Xwye0g*rVPp z;?$OvmzM`D_L}Rpb=B3?ezF;NPiS6!@ literal 0 HcmV?d00001 diff --git a/images/button_text/paragraph_text.gif b/images/button_text/paragraph_text.gif new file mode 100644 index 0000000000000000000000000000000000000000..8bec1ea7e21d23910effeaf087b87d8985ff655c GIT binary patch literal 691 zcmZ?wbhEHb%wteyIKsg2`P;AXx*gBoeqFu)&it*{s%IU){rJP-i_enV_fB4OF@NHr z?I#|#FFter)@$30<(|bG%@P+n<*YV|pKq12#I<1E|NsBJOE)v%28usfz>+#35@aU> z>;DC+eJPpqGFGk2dA+Yd=X^=-{fc$(Yu^7qu%N(0N2>qClA@D2R`V~cDDhf5O=_x6 zL%`8R95)MEe`{&P-Eea@SXSlFX}VyM-+>n|x-=97A_UkY*%_50m>HP3SR)v?TNoP| zm@C>kxEh*T#M(+YT16-GrmN*E@#HKLOW+mb6lGJY&|AvHP(O)Vlzlz}8yh3*q{f&8 z2HxT|J^L6rcI=wZ#CCqR=*7$7RZ1M|+v~(GvF4;lL~bt0UT{l^ZQGT3v(g!-h|XjE z{QlMbw-FqS9rIgm%+WACd0B-`?9Ew8g+o&rjC4+fPFTVj!I(MUD`Jj$lQL(w#L83= zPodi!I;>p(8x)N>8`QWrMNN@9nBX^KBJWX^(`xzZowJhM_DRk<`$XL^MQLx3#!X{JvT|9_^NmbP^28VyrS4lc*IBiZMZfg3oZp^`N$e*kYsa74v-9)w3yZzy z`_)>uzP_eAWvBB@i6fx#L83;Qdr literal 0 HcmV?d00001 diff --git a/images/button_text/phone.gif b/images/button_text/phone.gif new file mode 100644 index 0000000000000000000000000000000000000000..aadd42ee708675b5222260f5dfe2da991dff7230 GIT binary patch literal 478 zcmZ?wbhEHb%wteyIKsei{?_Z~Z@RHFPpLl4SvD~wGqgmoYr<~O$@$;=xmbezI`~UyHcj;yZyg>0M3s_zUM1t&OVEvz< z+Lw|!FJslZoY(sbbk3LL-mh5qzUKY^0}Bc~bfo%EEGasfV>SQ6iW0B2(-@|_aWGiK zu*O%1L100FcASB*wiXMM5?7OhqKHdV(Ssh_3Q=XYR0hs0gB&GB=E9=X7&Z}R24)d9 z(FjJ4QYEe;cIJXMy`&To_QC?z%#v2l*%1w?N_7o&(-!GOM6s7=#P6Ff5*y!fRD_$G zDQ(BjLu#1^Ixe0&78#j-M)Q)&h1DW!*IzkTvUl&zTjx~o#!r|uW!f>N2^>s39M7Js z-9B8nzfz>y<;da1?9uz0IfS)hPHb4{EXt?kHOFJ)qNCjs##whxY*aqVso>lt+#35@aU> z>;DC+eJPpqGFGk2dA+Yd=X^=-{fc$(Yu^7qu%N(0N2>qClA@D2R`V~cDDhf5jbW-z z;)Fv{{Sgcb0T1ViJk!6JEy%*O$V*W%U4d^gqh;d;of8bTS!Ow6j4Xws`MhE|TwSaz z>^wzmECtP`iOHgDg)B@=N;wgW7O{!)h^^qBX%Z2|wn$8rK_zGFc2RbA=G1k@ttvZ} zcWgTvc{1~W{vqWfi$yOk6D!%g`HaE2!s8c}`WYv(a~Co5vfj9-b+eVqBUZl z7*D_Y`Rn(ezyJO-B-%)LY*=uxnL}7B=ER1DhuhgSJ?409Ty(Ts!Z_>BiH(bocL_Rm z$#`yBa&odpu=lE%lbcjM*$t9U&GFp4?Cfld;#YT07C&p5@6gO8>$PRY#l;?zwPLkI snl3L7SnM^|YwN13t0OjN^=d6#eSLkx;VxP4ZEJ3B&bZvf%gA620PiZrUjP6A literal 0 HcmV?d00001 diff --git a/images/button_text/section_break.gif b/images/button_text/section_break.gif new file mode 100644 index 0000000000000000000000000000000000000000..6d348120cee4ff9a4195678dcd2a6640935e20a6 GIT binary patch literal 671 zcmV;Q0$}||Nk%w1VQv5;0K@nSG+vD(in#XUE!iS^GtH0dC(dJ`^ zy_2lbx5(ko+Uq@Nr%7|MHesPcY^yY1pE_iuMR2bF|Nl#Mvj6}9000000000000000 z000000000000000A^8LV00000EC2ui0B!&y000I5pe2rEX`X1Ru59bRa4gSsZQppV z?|kq7z@TtQEEgL z$JIBy6#)%*oLvkRo?=~HzuzL9o&f|R4FPY= zq_J0^z&b;{GSMOR3=p7Rpu)`AQz1@BF%{eY+!;_&p{5F~b{L4%uOG&Z8b#{lh;L&^ zo+1*`IaxEBubM;q-ML|akWdQ*v;`IUuIEmA7VKFCIs(+Sq$JW!%{s_}%L9C3(ip&p zWSlnV8o)XVOqc}#0pwXY1|ZqipLs~?6%kGV191c@Am9X6*S#AD$`CMU!IUP-jUE-^ z!_^X|zt6hXM6>fy7Sab*xfHq7itE>~W6PdRyS9=CxO3~?&AYen-@t*t2Wj&b_<$@8H9W&+eeS`Sa-0t6$H)z5Dm@pf_vNprC_VWC27t2AGqI%K3paIXLV|4VhV000000000000000 z000000000000000A^8LV00000EC2ui0B!&y000I5;3bY^X`X1Ru59bRa4gSsZQppV z?|kq7z@TtQEEAEA00I^UjU$O80SS_n zmLs8~r6ixAqNHhK3X>wIC;|ePBz&pV?=e z0a>bPYL6(-7KM4j0$o`mz5@ellGK%52o}J*(j$B6?mFGOkZ+&AZ37DiNN3@Ih;SAF z7(4-hj+!>YsAc3=4_<))0rHuPW`^3HJ_0`fhO{uUqeqY;FFb2!svnC4XEu`bM2(Zn zHETxl;^|TtP?jbA9febgCdU;C8qFJ{vk#{PIG6P#Fe28@X+=9F>w4nTSP@+o)~dN; zfT%&D>{RW9ZjA^60@~cFh#=ONL57G5?z7iH-=rc6BWRE%0JvifCzfFFWs;qpC#3-} zAgEISQ6dhADsZ_b&^G@xN)v6l>^7OB8KgnrNK2Oljeo$wS-^@Ea_L(7ZX#Ra@Z-pn zD^CHTx%21Hqf4Joy}I@5*t0{gz`eWo@8H9WA5Xr#`Sa+%OIXjoz5Dm@)uk7-p#9h8%Y2;fElG fDB_4DZaBe-D5j|5iY&J1;)^iGDC3MOh5!INTX{F& literal 0 HcmV?d00001 diff --git a/images/button_text/time.gif b/images/button_text/time.gif new file mode 100644 index 0000000000000000000000000000000000000000..1beba7c23e4ce337efa6dd6ee836c46f51612927 GIT binary patch literal 437 zcmZ?wbhEHb%wteyIKsei{?_a8x*gBoe*OII*Zi&54qtp$J?r@G#~&uIxw!qr!`1um z+#35@aU> z>;DC+eJPpqGFGk2dA+Yd=X^=-{fc$(Yu^7qu%N(0N2>qClA@D2R`V~cDDhf5iDT-T zX$dPC*7&k81W5J>iZMyO`7()zJMd}13K1Um>I4^w7dNf)l$#=%m|ELel{n(Kni|ae zW8-6)85u>Hl$e;6N~<|Vc_vJpQZ%JyN{SLQI~&_Vwk2khRxVds9UB$7X|u`J6$f{S zDzVQ}s@}JM+2rkK#dbz8urP3*JY{&`T+>c5t~z$!8;_qnefIpt%U7oSZ{NND@bS~< zFJHfX|MByK$e+Le{xdLh$#`s7aIl%+#35@aU> z>;DC+eJPpqGFGk2dA+Yd=X^=-{fc$(Yu^7qu%N(0N2>qClA@D2R`V~cDDhf5iEV1L zMxbKHh7REci=q-(dDkyx5|BM~Eo6a^0H+o=_d+Fy-e9g8hKNcr#@3udP4>WPZwgsCXK2@d{IpOZU_t+(cDC4;UB$}}8S7otDF|HL7He9oByb?{ z#RQR+y-F4bj%FHoADN>!F^x6D;J|5#+?{R$2aFgTRAZM&UE?%KNb_|S+i+L-+ND(0 zg6&43H(VY$G+Dd4Pp~RDp2@nx<8YU(_qH`RH)kxji8#G&?d|Oak5A3@-oEbc?mW#G zcTaC$e}8`iGq;@2jtvj@2?}Y)o!PPR@$m`D-t&BR8YQ#OFwVYrX6NST=NCA4%lTG) zZn?Z7cy-*_U0YvY-;jKI-dd@qx3_l`zrJ^N_xAVq4>WV1*Il^dG1UW@$~xd^ZEayWSF|?uF2`r;rIWrVgH0e z|F~^jipI&;>Yl&su*m4H$moKq-`L{teWB2hwdQ!E*qhXpeWl#B&FSXt_W!3;|By|L zvEziS;FGl9|DIjI)9ZD!aQ~uW|C(C5&+7k_QrqS6^7ZhSkymeE>@ z$-mR8Qrv~#S;@#5D8+3U^O?5V`)bh2-gx94As#)q!qREES=hQ?Nh$L{m_pTOb_^^~8vuPw zf&rjNUR@kV8dWQ*JAxOW7Bd52Uo>0{Hhl+zRDD8zXMPfXI({I2c?yDC1QK)$br?Wn z34198K7uVlIetlgSbhdg34S+if@>2?MGX&85i)27Av~}VB%(qDKMhVi@Kb{T9x_?P z2vSl30fGh?!=#u{#sP&6f}Xtj;fG`lKXuGFfDlKGAT3sSsF+f~!3YmmC_uoWN6-r= UJq{@F;f9aVqa+L|B@_q%JBq7kivR!s literal 0 HcmV?d00001 diff --git a/images/click_to_add.gif b/images/click_to_add.gif new file mode 100644 index 0000000000000000000000000000000000000000..8c2224fe559f088c57dc0edfd3434098a7f23303 GIT binary patch literal 1007 zcmZ?wbhEHb>|hXJc*ejWC@9#`(eduxJ0&Hh-Me>(hK8Owb7s}5Rd?^+ojG%6d3kwS zTAFc@Ui{jyrB~*39&743-fG)q<}=lG#<>Yo&-5j4iVU6Qm$Npt=}>LW{<7A?b&<;g zf?ER;C&VqhJY(^dSrbonc~5X&ePdC;B=6{{VX>=%bN3~+A8qvQ_wed*^_t|=cd|Wo zOZ3X?3+7*%R&XdavOhFnmPfXwH5^{CejLp8@P2Rqpn>$(9`WbyWJGQkQ>fh#j+;`)Vj-9Qi zo80B)R6E#x8N3-zHl5|%cxKCke&+QDx1W37x6S*F_knv|XIswu>FBvyJ=?=^{mw%+ z7B*Ie@P=?>CKdsKN#+|)HsrVPC^PB>AYX zV4T2dctlX>W={lDyAK1)nWxzYZBqQ!Bwj9CFri6}dmHB`(*sv6m-%rEGAwwI)HpFB zU(Zr%o#d6|Ri1V;JCmR zVerst&o3s2>v}R9yOkzuxn$2+I$1>_jKgsEg^!k%ci0#h1j47KUv62WSx{tRxbb?X zuC-vphQ|uY4s!*V53nR&n!CI-dK$w+N0xJ&Z?m!A6^p#M`QTJxuTw3`K?iQMrpuQI z&rGelHM^R9-rt+N-0CKOEhm6c0Wpf|MsvP*e@%y%rup0@}-l_`O zJ`g;7B>r=t+XDrYmI6jLqn-l}>}?!VdxI8f7N3i;oOnH0QI@UrY}%;qquet)5VbOI+p_+F9}Lq zPzca-<%`{JTDY_`JaWq!rHgW-ojA^8LV00000EC2ui z0H6RP000O7fPaF6goTEOh>41ejE#Y=j_DWANWWeQ7>Ptb;)zMPJhyHeGdptRzKNUbKW#fzpLXNKC>x#WLMXcz@$Q7XCAcnwDBM{^+76cc5CWJRWFW&TBG6Ie(R0aqDm!4MGx zsIf!_DhR>?0CX$>!4O0ilG|;^(S%ZiHT?ypn39`dt01KXdWBMm{rX2~ zh_*>=u#<5*q8}xm=0> z_1B9ivFn7p%-;IPV~E*{?;jmj@dp=2VruSpN>z8JzMf9jW+b8t!jKjZk+6W!3Uq|~ z!VwP?LXt_K7HpY=f@Gl>fK@0Z$jF%4Hb`BAung*pfHm5zAu`__sJ@yO*$5eeyw`;V zT6{#q02u)A1p$H-;Pe0`KtR#dKTBNdLjriP0|5&t{YBG86yU=HOi*ohB4jl5kq2w6 zfdK|%kPyNGuNGiL*gg=Dgb-)^o{5G{@VNx3<`z5q49`Jii*mn z^Z8^#r_?G=YRzi5BP{m|4nMr&vUy8BtJlpm`wjoONkNC~0{{nW?$S+3EQS8Y((UT55WVnyR|W+UoiW8!J0YTWeb?kgL1P z+w1!a94tIcTx@)doUFXe-0Ym3`7Aw6U2T1hovkelvhDp19xgsEZa{vHp02(QZqEJ= zA1^=eK5u`IpFdr%-|znqkRQN-1Pi7UXfUC|h13u-d z2oj#hkR(f%17I?x%5fuCx_r5;CCr&LC!(y0Gv_dwI(xq4=`*NFphAm&Bx*FNMWjlb bK4j`NszInytN!a|HEYCZTDv9$Q2+ot%b>F* literal 0 HcmV?d00001 diff --git a/images/exec.png b/images/exec.png new file mode 100644 index 0000000000000000000000000000000000000000..67174cb1ed42637555217f07645abde34fc7ce66 GIT binary patch literal 1444 zcmV;V1zY-wP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ>8c9S!RCwB~m3>UqbsWdvKkj$;yGP&-xZ`-{5QH;8 z2MQ{pO?)V*pedy3=*bzaS!<=swrV~6QB7@Gsax5DPF(qrZfQtCO+_>?0`7qW4>-6d z?tr`F9)EZD`}Idl%?fer_1|~j?e+caz4vEd4(_0#;c*xYdN2$_Xtnyi)6>)5zP`S( zre}9xV!{r$+l9G6-hPnD5~Q`YwXd-;u^NF;RGE{L`$T2sDsc=irD}Oasc776YBiZg zS_y&x%d)eIIRFqF8;eDYN>EbvVDs)>FFd7It5*a=(ehx3AyheeC0s6N$&-y6SDkCQ z7_nN$&g9O^hs|!eyI84AN#4Et&CNEuql6$O*~U?uAR{A{AW0H|APreUA~zI@!fLVj z7nhbrScZ{kw7sUgMzNr1SySc8s@F5J7hqs;1ld_>;BiR^g?xlUH2nS`hDWWaZ`i!t z>!X+J4aRQ)T$*)af*@cR=)EiuCqKvGiiAmtQbfWG#>Q>vywWip3`V&WC5RzO5+f!X z+S=Qg<|7~1hr_gUR!I^_C3D=X6$ z47yKWOM{)&wRaqK~b4NukC7Q7zWu{Dx{@n!e+bG z6ppU{SN)88^7@*!wa>`qa*0^PheRxdGC3tNBO|XqEj6%5j!Wmh8#HK*shNdU>FEl{6XQWq z90&wFL>UI1T^fA2_ub|p{iU}bs$Q$$@hJDUZA}+P#vIE0yc}MFB5O;}Z=G!fK>z@V z+h0kNr&ev;{Bo;7*QHmfRPuavvCQLfN85ior%lOF7hY~ZwKG32t?$rh&F3vvJHw~A zF|iUct5hn8g9rA1bG-RjgHGQMpU-*2OimODqm6i3jj(imToz6 z^rYs(kJro>JG89J6=G?cWxd`AJ8pKd8ttg(#L0F|K|$fln^F7)%d);;z}p4D3&3d} z8#GzQ2hT^N;USt1_Nr9#D~lH{TdK-bVqkC#KeV*@rd@tgC=wBL7*uz658Zt1&^rM9 zoY}S~5)SF2(eMZW)YfgPt6Ww6v`{3Dk46c6e)#Z}x8B&XRHM-`rHk*cuv#ZThZ&ws zmJ|;7y$%v{#Oa(Yop$-sczic}zA#Elipk+Mt3yRa<&4kk$K;d;9*>v0F*K0vaN6Su z+yh%1Up%$GdQ;uhqyx(2M5wY-B92Knr?1~YPyzvrLj&f0AG}lquv475N=cF%H@~3d z)j+@(o13fRn9X(!7)E0(wh1CBNeZ`XGThtS1E<4sHQ=8anzNW;n6Rer+Ht$pJR?m^ zU#(K5LZOf$Rw97Q+|Wn)w$W}(eL)`=<(*<@z~Vs&t#xhNsmIk4i$Q+>W?iN1J~ z&4`A{e2T((h`4uas#rshIE>4IZ?#yY&XhfdHMQTYc&=#0-MQoK;mqL1%HG9Ol}xMD zon@<4#puA!>B)w-akAT}v)!qD!)vtNs^Ie6x8SdV%ymMIHn`QVj?#m=*0F!NZJE)F zdd6#h$8VCwfL@$dm&b*;-LKc~(sH?5v)QF_zF&&Dd3dyBiO7G7&wYl;dWFq-SDr;-%Z0P?UccIYeQZ7n zf^$S&N!!1DD?S*4FeesJ89(QJR{%)h}0W4-H w*cr5A!j?1v>WB$|C5DX#h4f6o6Xs1D7D_&VG^ByUlmusb5YPdsW}!d;I~uPyUH||9 literal 0 HcmV?d00001 diff --git a/images/icons/agt_family_48.gif b/images/icons/agt_family_48.gif new file mode 100644 index 0000000000000000000000000000000000000000..316f74503075ae508096647bc9f1b299bed9bed3 GIT binary patch literal 959 zcmV;w13>&oNk%w1VK4wN0K^{vnU$fYYYq1G_58_)k<|Xo&e&i%r~dN@@{p3=v2f$0 z98tLacggjNtt-ICM+y2#?e_XV(fhYJ_Sv8{cwd4Q6y}h(#A^8LW0018VEC2ui05AYB000I5;3tk`X`X1Ru59bRa4d^LW@m*k z?_W^`z)I!e(eYjqh!PkODjuDq3!tn9AK0i=mHAbdP3&Wv68r)W&KDA{NMHg_;*jvX zQ3a+(^Y}K007wl7goO=SB^gQ;4vl?ZLSrow4V8t4MkEDF4~>l;UmO)2nPmx;mV<=} zCLL-Xdm4=$k4mI01quqNl^UuCcOwEE0kN^39u*J(r6?Y{&%>n=#1Kizv6973Z0_4yMvgiYY1x!SMH=v-rcoD>%=un}-gaHW# z>_Io7(zQg~3TiYM!G(_o@Z?Q&P_cm+EIB&=@O!v%f`@=DGMLji&%po%XM|LEk|Dwa zmIf0rb3raZJem{sGzh?kNhAdT07NVp5sE@#0%)B{0QBfhFHQfD0{}6BS(jHwNO*7t z$OD2K2k3mjv}q)(9l~XekRg}}0TGxm;o6dJlZVRevdxfnK)Ade3Pgx-uS6cfK&BRK zpulZXK465{Lx7-ffdUdFM^bbe#e7#%*dK z806+agNH}}yoeGJk^69D2F(3MvJ;22;{y;yDb#5}3aQ#}F&_Dzk~UJnO^xDFz?TPPO3)K(E(&Qu0jr&sWmFMp2j-3( zU;*X^3}B$=o){3o01gPKX(5b8BDjGBS>2%Mq7iJc00RW@DQTYzY=GdUn8JrB4b*h% zX;v3NO2DY3mP#rH3^0?`s*kNojSCTk%7Cb*jyfv?p)P=k6arkZz@xX`>SwSQ_{u#xOzdO=z+#Of;lVPfZYz({wl1g+HQLROj2|Jzy|EL>+ZYm hwzfr91!idPy#?w;hJv5=>o2wY1}yNv1g8)J06UT7pXLAn literal 0 HcmV?d00001 diff --git a/images/icons/agt_utilities.gif b/images/icons/agt_utilities.gif new file mode 100644 index 0000000000000000000000000000000000000000..76128e285c319d2dff90dae07e5a6ff7194b109b GIT binary patch literal 308 zcmV-40n7eJNk%w1VGsZi0K^{vu;-R%!ca7@2vCF3<@&}POD;qu;J$T@VKaZkk>cg1Zq!2nCMJb>O$P@PPXnTqlJ>V%$p zWR6Uq=yU)7|NsC0A^8LW0018VEC2ui01yBW000HC;3s|!B1xEpG-In^K_OEVrnHO{ zI0aoC5Q;_O5h*N`A0ofer=_9K$UQ8@dnE0~;(YBM1r^843v4 GApkq=d2(<7 literal 0 HcmV?d00001 diff --git a/images/icons/agt_utilities.png b/images/icons/agt_utilities.png new file mode 100644 index 0000000000000000000000000000000000000000..e312063305d23c213b3c21ce4f8a8e4ded084ef1 GIT binary patch literal 3624 zcmV+@4%hLCP)KLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde00d`2O+f$vv5tKEQIh}w03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(` z>RI+y?e7jKeZ#YO-C14T(hK~#9!Y?E1NTy-2q&;M>SnM|`clcbY6jY(4y=ONWe z7f3{G^+AwWs1!u7QqpQcyJ$5a22m^GLoq%?R9vYPqo}yyf?EuY>4sH8Xp@qynYNjv zNoF#0@65gP^C{4Z=lPuP?NcJcji`VM85^{1WsN19io?b0q=1rz(S`GK!`J&|grCHg z#7+K<1Nv5Vpk-I|@aAZ1I8;=LjzQk@aIi^bG7Ov>96xpZ+^cd*-dt%60Hu@}?C>9Z zsC(!B=Qh7U--Qp!<}$cIz$~P*>1phoL(u<5q^53lZ}2|-+v8iS&l?7GwjlNI0zlhiG>ZNUO>?tFr9tY4=P}MZ-2p_5m zR+5o<`scso)3FbDGTKdA&EhEsfQOqp>1;lP<7TNUDyMEo^%3P$<%U_$w%Yp8YA2rr zEr(SAf7?G}UbX3p_FySLSDh(xp2u7^$IE9AVwomuH&oS*MP}L!Ur5!vz9bp(V;KrD z^5nE6qC2b&G@zmL)>Ie2T=^P3SAY@lkb%{oQ3_ZTIkB04~2pJJvvgDQENSf`9 zt$aNCJflC@V^_YH7e&NHL=X{tWwf;%Vd&BRBI!C4m2rDW7QMKnyo8KpPRg@qZj;@= zmr3*q{;-OOt#mh?Nhwvkrk&399o!$;NS(jXCCbOaA=Oh{r1FE zb*%dQ{HlpV`Qx&AquKHH`}WhW_~Kn`l*wy(nTcX6QE{nLbE^6M{q*?z?)3O_n$Pm* zzFI>VaFM~$w~)}CM%%H4@6xR3-K+ZWw;@7mymRa`t`>tyzRCTM^q+ZmbYx3sU_1|0P>-FNIQE!&Z)wX)q zx_0o>dFRV_@b&rf_xjzNP1u@L?$mwc)v)T`lDX)6r`-Sl|NsC0A^8LW004ggEC2ui z01yBW000NgfPaF6goS?(bA3+(4hRJSJtki@B@cgbe3_b?nm~VjprN9o34a5AsHv){ z0Dm!l2Ots*Wn_43T~t{^LTV0v4K4>(9}F@)MMqO_L{$iW3j_^xNqIXL889g`OIihf zdj!!s9zJL+QX5$(P66P1;RHT#1_By(UTl9+etHn_X~xvkP{+)j7JoRPq5vUH7$zfV zh%pnvPmVuOQiT8$1O=B4W{jYk@JGRl1OQ%;ID?@H5*t|L;80M=O&bd$u52+x=*JBu KDk|^{1OPkeM`{@W literal 0 HcmV?d00001 diff --git a/images/icons/arrow.gif b/images/icons/arrow.gif new file mode 100644 index 0000000000000000000000000000000000000000..286d22e63b050160e267b7a48548ab3e3a9b3868 GIT binary patch literal 654 zcmZ?wbhEHblwgoxc$UiW{rmUp*RL;MzP!D?-TiRH^XJd!&!2z){(XiJ9<62825TH6 zuVw|FO=1Y=4L+aZeLN=oa)#sHAcjyL;eM5%bIA-*yq-s+Y&#UwgTY z$OP5S|1*X9lndT8HvE}b{JzC%o43gZSIezlz9-}CcKJ{Jzl0%J*_Nq480vJDvT2+_4#N_o6*AJ$gMkPZYoQ%G>_-v4m~ABo?w1483R6bG11j+ zCLUgDe!kk=it3^I?!3ENxTP$O{KGAzWBK(ZTwR1tH3>+mnX2jui15n@I>!ZYa@(8G*&w5rJdND2YX;sFPN`^>Yh8SLk zC|=)_amSAzci0mcav?STc7e-*(Ab-KrW@T7?i6|*i)M)9O?yBlzBrB-2=(i!6UWM=3_U(f0MKT~?TPR@&3<@qL7+q^xFMEaeI z_dlJWz1*hh-{jPXWr=r-81e)Z=Ng4y&M;c%+}_?UH%nh*iDl*2F6aFrQq#08w|XVr zD>mEYuC>hi|Ns9CGy{r1Sr{1@5*c(rHh|)Uf&F7cVpDTVYg>CqXIFPmo3AWWZ@UZ+ zFUzD>9d`vqh8fNL91iM?^X9X$iU)`;o$t)bAulAQAsDTu$0x=zv3&)*zKC3uqlqU+ zU>uj~^tS!tL2hh38ho)~_9EPCTlrbpr8kAjNU50%TO|nGUe;o%F0HRDr=uXK8*d>I zDZqKBg(c-c!-2<)%o2Rlj(kv5Im%K0mW@*)U~wy>x=)pjrz0!3ke;5$A7zumQ!QMA zIV%D-C@^;ND7o~gSSGNw$+CCEL<%lQ_fP9oTNTiB;7}JE!z8t*OEVTVDRHHl&6?40 XSG|+jsAN~yRiW_C3H!XbSQxAUdX3v! literal 0 HcmV?d00001 diff --git a/images/icons/arrow_right.gif b/images/icons/arrow_right.gif new file mode 100644 index 0000000000000000000000000000000000000000..67e8268938a65003a70da9168149a132abbd535b GIT binary patch literal 201 zcmV;)05<)mbeYtm&%Zo{oL4v}3na`4*(UpqF zghYrvU7J>>)}8zO`&WombjN6IzF}y%T~?t@Pnkzzu~>1#WnGV2JAgIO;LwiAhhU;w zhsA+VlS!h~ng9R)A^8LW0018VEC2ui01yBW000F>;3tk`X`X1Rt|{TLV#kmWWJOXX zOq8)Pml0$zXm}Ecf=0nPbRHs0@t9m54uk;ogVXU03(R5@2(U5$0PJ<>5rCDFgsJ Dj*?cA literal 0 HcmV?d00001 diff --git a/images/icons/arrow_turn_left.gif b/images/icons/arrow_turn_left.gif new file mode 100644 index 0000000000000000000000000000000000000000..c77433825ea06622db891f12550e3b5979c37cf2 GIT binary patch literal 224 zcmV<603ZKHNk%w1VGsZi0K^{vhQ@tnr(b%!a+}1Kqtlvnw{DZmiz#X)ip7IorB;5x zcjfQnGj=YV&y+cRGpW|0Bx4}`{{64pskhj(uH2_|rf+DrUOe@9EnZ2Od?>;_S_5iYg5pA4&Ic6>61XWgfxqh8jiaW z#*tCaLpI?WeRF=bN5ck&bgXd~*>lueL76CuohW4m$IXty2!At7T22I8(|toa(8lwB z)=l1|lg13tcVVVkHl>$gx>QG7>0H0w^R|-c%nTY1{JhKYC@9#7&No;&qhL&#N=Ta) zbcxZLSR6&X4Z8`m1gl$(=@J920_-{Ls$k5iSVaA*Z?}b@=ZL>MFQ8-3KH@u-EZY_8 zl!`-|#CV$sO!qr)u|Q9DPz`y%cH6Hn#2f>dHihsZq~&B__FJF@##{C~Yxux=mUNf{ zP5W@|cGqK=G-VO*itP6Vs3xB1$^u5=^eg>bLj2zbe#O6yedrqz@Uo%m5t% zpE=J~oH$v=#9PuyKZ3U(0G$G_D*R75g*0b_P9f;d0qq&+_kr1J4*s(ry%!#MmOB09 z*zhGP=*V=}?r`-MdmqM4)$);Y2HC#f_atGsObCY6f#wYSliICG^j5ERshC8=`k;Xi z+S9Qg189B1@0u;7Yt&=R16FC!00RJ^|NOH66Qfcfs1Ayox8|RKXd@7J$vWZlnBL80 z^=h5Hrr8H zlCj2V+afFYP#YPu;NW4&%ca#^s>sl*TwHERzP;xZPoiAFj6Y88y7Vcx&mxCX{sIWG Bl@0&^ literal 0 HcmV?d00001 diff --git a/images/icons/attach.gif b/images/icons/attach.gif new file mode 100644 index 0000000000000000000000000000000000000000..505c3f8ef35c2170a9680677c3cb8a1e72b092e0 GIT binary patch literal 560 zcmZ?wbhEHb6krfwc;?0M`Sa(mU%yV8H0k>F>+9FAU%GVZhYugNY}xYU$&)o}*2Kof zW@Kc{n>X+N{rf+E{;aC1djJ0Y%9SfuuU`G@*RSW#pU<8>`^AeFpFVy1{{8#evu7tv zn6P>C<|$LAtXj1yEiJ8}prF0IJuWV8@#4iZX3W^RbLZ8oSC=hYHfPS9%*@Q5o}Q$n zq`7nF78VwM`}VD`ukY2XSId_#KXvNV`Sa(WJ$trf$&z*J)-^UZzJ2@l(4j+{Hf>5w zOx(VG`?YJ=qNAgGdwave!nSSOHgV#_9Xob}hlh7|cDA&%Oq(`s!-fqD7cQJWeft0Z z{}~21Q2fcl$iU#mpaXIyC{7sIdmFr(np;}iS{PYnIYio<8BCNsS@o>@7}cb;ZM=9j z+9g=sg_xT-xZ89^O)XXV>^K#;S{c+?*bNz71V!c8TG)6T*d>Me4VVxyIodO}@-i_r30lZliMNTlKJzlx)DmdtQ)Uuj=H}Ax^O8u}@WPSd N-u`9|SymG1UW@$~xd^ZEayWSF|?uF2`r;rIWrVgH0e z|F~^jipI&;>Yl&su*m4H$moKq-`L{teWB2hwdQ!E*qhXpeWl#B&FSXt_W!3;|By|L zvEziS;FGl9|DIjI)9ZD!aQ~uW|C(C5&+7k_QrqS6^7ZhSkymeE>@ z$-mR8Qrv~#S;@#5D8+3U^O?5V`)bh2-gx94As#)q!qREES=hQ?Nh$L{m_pTOb_^^~8vuPw zf&rjNUR@kV8dWQ*JAxOW7Bd52Uo>0{Hhl+zRDD8zXMPfXI({I2c?yDC1QK)$br?Wn z34198K7uVlIetlgSbhdg34S+if@>2?MGX&85i)27Av~}VB%(qDKMhVi@Kb{T9x_?P z2vSl30fGh?!=#u{#sP&6f}Xtj;fG`lKXuGFfDlKGAT3sSsF+f~!3YmmC_uoWN6-r= UJq{@F;f9aVqa+L|B@_q%JBq7kivR!s literal 0 HcmV?d00001 diff --git a/images/icons/checkbox.gif b/images/icons/checkbox.gif new file mode 100644 index 0000000000000000000000000000000000000000..7a47cadb528b610c44df2498e2b699b4b3f78aad GIT binary patch literal 668 zcmV;N0%QG0Nk%w1VHN-u0Oo%HcDy`>#8xC$D0|8pz1^pmpp?qvymrAhbHW>g(Hfhv zh*g(4NRcOVwn$g67@X2)hs;TKh;O;PxDiwmhQnuRr$)2dl4htksMUz5)tGI)97dKF z&gj8`$u{op?sT1D`T6QHjNC_)zq8Ne!lHDD@;ihDtKzqPNdBZH@<>Q6VD$LQ!YJh5=(Q;66NHdKQz{0>~oJ@k6 zbc4q}q0oNx^z?e2ago(H9#$ZprJr%b6{feBKa&oC&K-ZqE!XMJVSHCqpCfRyK%~)t zsn&qY=)0@fg09z&uCuF_$#U50&^cf_#N@HY<-FkT*gnO*;OX+@L}W)`s4q`;PE~MIX1Et`w>ChN z6q(vYVwX^Fmtta_LTH>#gOPrUmw&0^Tb9jaqSJcV+t;}1cmMzYA^8LW004ggEC2ui z02Tli000O1fPaF6goTEOh>41ZAs&l}Aaz2Ih8}cTWFjk+f;BxHDJdCrX@r}HHx*G@ zOIB+Xb%H@3TYZKn4Okooyc9cbe;#)xBNr!xC^Inx%me`>6Gduv#3LASD1r(Q78X<9 zGtfnUJ`PS*Ku>%JM+#z6Dk@MpTu4L`f;e&x4gdjr4>~~b^5DUkA1>qwXfcQfkqsKm zz|laXgGD7SjC5ger9`0?0yenNfB*pt76VcaVZbKDp%Pb`*g%;iNrD7(7QAtUD1?qS zLlS@i^Fq&p2&WQxU~=J07#MzJ;Nb)!f)g}R3ve2gC(Z>bTM3=P7j{sYq-8k;0suSi C966={ literal 0 HcmV?d00001 diff --git a/images/icons/checkbox_16.gif b/images/icons/checkbox_16.gif new file mode 100644 index 0000000000000000000000000000000000000000..3ed6a065c9f077bf7351a0d8805e369691c9dc0d GIT binary patch literal 564 zcmZ?wbhEHb6krfwcvi^Jc|~W(o*kW6w5v|a_MM3_?-Hp#BWv9&GXHYk{rmSf-I|tK zk=lOJIk777{=@sxU4Cs>)XPznBd4Fcf#-Oto&(yEUNuBP#?e@IZ z(+z5}T9)TCH`3we^(w3st<+Gn%8~jU+`=O?hPtvbm&m3guYRoFgN0lT;lf ztnB?$6vNduIC5CI;|d+wlZE_v3`2rkwZsgXJ>87+&24;`*%(4K+w$a@0__AWq|Lfx hqV?Scvlu59#(Fs@?0n!qL6pyzi_dGphC~GhYXC=k`f30G literal 0 HcmV?d00001 diff --git a/images/icons/cog.gif b/images/icons/cog.gif new file mode 100644 index 0000000000000000000000000000000000000000..730273e99964ee12fd0e018f3662104dacc6af4e GIT binary patch literal 311 zcmV-70m%MGNk%w1VGsZi0K^{vsi~>e)zzh?rNP0$XJ==%wYBBt<=WcX-QC@>v9Z0q zz5V_Dii(QP&d%xS>C)2D;^N|Ra&pGT#>B+L`T6;hl9Gagf}EV3$;rv^@bJ00xy#GT ze0+TO_xH@q%>V!YA^8LW0018VEC2ui01yBW000HF;3tkw@EBt%Qp@5QM$u*})HD=^ zAX--d5)vYFkSGFyL}C*Qehd>t;BY`59vcitGlB#>7|lg6kPHd~(E~F%G!&Nu0x%gg zDwWHmglPy6A_jCC5(oqX5DyX!2@oO>0A~Xa1O;Oa5*`HxkOK-D5d;w;0cH{s0Feqm z2_pdlr5kIRMjH_YY6=Jf3>I|}5dseu03!*&85J865g7yo3@Q#C3k(Vg1Pd8}DkBmW J917hb06W`la>W1u literal 0 HcmV?d00001 diff --git a/images/icons/colorize_32.gif b/images/icons/colorize_32.gif new file mode 100644 index 0000000000000000000000000000000000000000..b30b20b5bf85f2cbbcf3cc3d6750e274b98c8adb GIT binary patch literal 1110 zcmV-c1gZN+Nk%w1VITk?0Oo%H8}=Fh!&m;;nOn~Jwb=Ln*@XV9bpH40|EDMO^YhJ! zG1iw=)2sac<*NVHc>L$N+1c3BrE`!>2=##}{I?VTvNyz;YyZh)`r6Fb&#(UV+{tka z7pDLJd61CGPiUqvX5>0 z>ebM@r2M;8_>2TlsR-uK|LyJU|DG4=%c$Gh#{a!b|IRZ1@T$-1{P_6z{<%c??Bd?0 zQ=xTB|IKs%-;4k9$=9kdg}wX6#KF?%)t6&2|NHNd|B(HrSrx?pxM>gVhXLuhqxQ2# zyXd>~qAKpJMbmtW$ABllhyVY!KmX8d!FC+1XdeIm`Tykxg+T!J`v3p>`2XZs|IWAn z(YKOVA^ZFL@R=b0(1Y{Pl4`k)rM2><{8A^8LW004ggEC2ui z03ZM$000O7fPaF6goTEOh>41ejE#;5H4zFPOjMSX3K1A%j(vR>90UgjU}0fk1_uWzS$YZGf)P|22O9nw1UM`iu!KV#4HJ|YFrdUu3x5x? zu(#E6Xt zKm{NWAb^IN2Ox-o@F8XfiUmSE%o#Bw!HgAVfHv65HK`dhAj+gjrlE`nIU5@ASwO`F zof>-ouyE}_w*%3;L|<@i@It{4DmenHu|&m35V}DU7g$`NjAO?XaD16eL5c(gIqD)- zyx4(fAfQ2C7>#4gi4$8WJdxnxaN;1HJztqUdUSx>0babgaiUM36K7PA&{qI<0nZL- zU%-8%IS(FItW>C=g2$662oR9iVZnm}HL{g6zX5%^$?QXhkfA~21D6m9Y(!YW#K)D| zx1E=#t^z@nVPmur#Ro7*@J9$c%rJrrD`4@$c+g45Uv@D-VIdTGe6Yb0gCJ;?1tdrj zfOFANx5fh4(GY_PESlg43?8sx$QTKTK*AH`NvMJoXoT>F5-I{9BmjOi!9@{=AZP)z z6Z@$!g$z*2zyJ++0FXoy0NAl11c~gBg#zXwFhvy%lvzR=AHc!J9(5S$!U&0kkO2t@ z^e1KsRpeR11RwO-Cka15FoPmvu)sui{*}Oh3{~6#gP$LGAO-{@?6AlTM|iLv4P=Pm z!~&1@*@Of~Ohu6*@Ug(!2BG@dga;C^KxqQR5Sjo4a{M3$7bNt`g%~W@Gy<)ic&H!* c$R<0&u-tUg;TSt4AnmlY;^XYKf&>BpJJbLf{{R30 literal 0 HcmV?d00001 diff --git a/images/icons/copy_32.gif b/images/icons/copy_32.gif new file mode 100644 index 0000000000000000000000000000000000000000..4b8f28adeddc970b6e4f66e6d40465c0957c3f0a GIT binary patch literal 556 zcmV+{0@M9RNk%w1VITk?0K^{v^Yiod_4U2Iy|}o_!^6YAzP`c1!Rzbm@bK`!z`(4m zthKeZyu7@#v$LzKtFp4PxVX6d{QUU%`1$$y{{H^@`uf}3+rPiR_V)Jo_xJnz`||Sg z^z`)o{r&&{|NsC0A^8LW0018VEC2ui03ZM$000I5;CEPLX_kZZt!(RlgeT85JydVL z3RGQF8jI(qdlh=V8Kq*03`t&IvI1P>NHEd`<^u z0Eql$z}FQz9vy;%gmM}a7y%p?6df7^97ceIl#~$>8W$QELIY4zla-=_ngK#jQck0l zm=T&Br$ZYo1saYTxVgHxm=hHj5fT;$c>x0*JGQ&axD^w=7ab8N2n5Ly71`R`*%K1q z6Tms&+YCL8S(KF;?fo09qAtezTf`-@&d-wRLO&Z9TGAGz`&4UfQJhk zHY7;N;EoI!#%SEgQR9UQmqI$xCjeu|lN&#&iuC1yWFi1CW6GQf^TLE&&nkGhu!4ai zb3lU%HHYAW1ZVyx?7WzfBY>emi)KhDPr}j<1}wk~K_bHp9m+;2;K8n4h!8Po5Wq!%2b3r=OduS^Fx1BzIAmZ@*aKv!WGF|u u;6b2gfj2c5QIG(FX$T8at8T#hf$Ikf4n{dZzyN{UxO3Mwz}t4D5CA)_x&(3n literal 0 HcmV?d00001 diff --git a/images/icons/cross.gif b/images/icons/cross.gif new file mode 100644 index 0000000000000000000000000000000000000000..3e5aebbf27c6ecec519eb6b5607bc28745494562 GIT binary patch literal 1130 zcmV-w1eNgxU@Bmb$XyREIY6&2!JTcZI1{u>+a?(WZRZTkB9 zrXwT&n3%4rs{f#%|4B*c3JU)|KFk0Bn~jb86cqn?dGhk|)zsAKX=&?BO#fY7!2tpP zfq~o8)5?K?|5#Z6kdW#|M*nef|2a9;#>W4Mh{VLi|F*W|7Z>&Q_3I`k|1mL>K0bFr zLCXsZ|1~xLK|%j~eDr8&ya56KL`2d60RK)-y12O9QBnN-{Qq`#|D2rvj*hwu3zh%? z|FE#-QBnVvmY$Q7|AmF?JUr@ERe=u=nSg-YBqYKP4)QrUc@z|tjEuJ?CdrA3|EH(> zHa6P;0NmW%|GT^JL`0@9FR=gs%c`o~3=IFTuj5Qi`$0kHW*S!k#266gM)rPKJRaD_<@1l9UajK2>CKH(Yd+#b92tMwg3PBA^8LW004ggEC2ui z03ZM$000O7fPaF2a#1R6gNcfXFKlRwf^AW1I8lg@i!Ut+1qX`&Dia9_P$~+Tj6w-y z2@alv3ZXbqP&gAZr>HMWWVBFZ1FwH^0k#vzY9F|mFEhpyU{Fju5rPC_M_?b@A7D(T znFABt-7y$&W7ZHxARis?9ZXWogD(#5@ENtnivk7_ zc4)zG0T%#*kX%_XFh~;{AZ;|EQpLrW6){4JG*J-(f)j!=blEsi1eF#zTTl_QCxDHd zEo{ta=|g~$K@nyOGy+735ED?HK80$c#Q>rLHYiGZ1;RQWOJ;~2J9dc!tXdaEAaUi% zIs*g$;>wj*#q|3m4Tu7e3k-G;hR72;i4_ad zK_bVI0xKemb`ZqNjiZ_)tvRv+#){CQAv*w}A+;bERY16gUBI>A-XM5L(4a$ejU5;y z@DKqa01Oy=L<9gK0*Ha@1|DQU#YaMN3Dp#b&1 zpLjt$W`!0LBGAJKL@+SK0Igvd#D-z`@kb3JE;t?t1DrSl3v{4x!-_00aEA%KO*bRQ zhY?T^f&|L#IKvxSjNk+T7;PW`0wauIWD7}xFe3vfP(VZu1^~g_5^wxqgcEgK@`n;A z%+aM5ci7+n4AbRtL75ZgKm!OSv?)dfBvg}#5@XQ8f)PKY(8Qiu5a9$00#xwh4t>0# z$Ds{u2MGXJXdysH|1NsY$qLt5y-fnu7%)nBfMl wie=D11!-82hONjd>qQwoAW@ucCwO2+8OB~aNCqBYal>BNB7udqg9HKqI~7mm+yDRo literal 0 HcmV?d00001 diff --git a/images/icons/cross_16.gif b/images/icons/cross_16.gif new file mode 100644 index 0000000000000000000000000000000000000000..40d748f47107e304c085b0433c0a63739e3f43f2 GIT binary patch literal 644 zcmV-~0(<>ONk%w1VGsZi0Oo%H|7vR1)z#)CB=+|9#+jM^9v+=`cH-jV|9N@sN=m{8 z2LGw4|6*c&Qc}@>fB%Sx|2;kbRaNpgH_Q?e$pr!U z=`k_?bac%L3IADH|4U2%IXSGDnEy33?Kd~1hliyA0N~o%`T6<(D=YtGWdFOn{r&y_ zM@Qu^FXK8o@9*!W@i01 zHvgNO<0>lugoMYVqsOnWfLmLVOG}egRq{eYqA)PyNlC<)m;aQM@bK{22?_opBGG1M z#=5%L*4EkC+4MaHjY;(R8-b~f8b|l#bd!}?o(nHlHydj| zettYCSZIBIOD=dacN!ZMq93&tiT_nUn^rk?H5ghGR8+2~ zr>>Ked>I*F4L$+1ZdtNXMh2)4{>hQBlW>i~pOOhyVcSWMuy$BFb`d zq$(=G0|SLIG5`PnA^8LW0018VEC2ui02Tli000I5;3rxcB%bI;WmIZiK^CPabp*$B zzCkb3wq5|CD>x827-_&l9!$d1Q>%fg&hW-o(3G7 zq!tONs0KQu9~&A539q=h0|OcsGzGRAw*v+Q1O^7Zy&EV66~xB44jmm10tw2^1s@R6 z8pf~H9v;`1+RGIX6U4Zc4g?Yr5fTIrmgxfv3zL@z@#cxBch6Eb0{l8$0Z5>Mi4zbS z6g)tn!-5DL?!|K$OrnDd1USriz`=ln2Hi*!6_7Y!)rklV7Nn$AKtTgYApih7N{F2R literal 0 HcmV?d00001 diff --git a/images/icons/date.gif b/images/icons/date.gif new file mode 100644 index 0000000000000000000000000000000000000000..d5e12933f4f2b1aed0c9cae566ef3b44d7a99668 GIT binary patch literal 291 zcmV+;0o?vaNk%w1VGsZi0K^{v+uPgR7Z<#|yzB`HuBfQx<>mSL`L_`f#>U3V007Lk zw)Xb+(g+Ch^77g!DCz0x?(XiD5)$b*H_Xh;nVFgW{r%R&#NgoI!^6YL$;pwCk=y_P z`}_O+{QUp_|NsC0A^8LW0018VEC2ui01yBW000G`;3pyk#);fSAfmV>N}(j%8_%1| zScR1gg9Oi)`)nA53n35~AeA-Oz!5nx1B^p8Y8*(u4#yQcC}uk7bceH8csd!;8NHZ5 zG6;dE0+**%90m_21_p5-XB=n*fdT~!4R?MVlmvnT7Z(5kEQo8B9GCzd6&Dk7l&J;{ p4*;beryl|hif9H45C9h*3!M}K7{S8A2pAM16dKCQ%*w|h06S`jA( literal 0 HcmV?d00001 diff --git a/images/icons/decrypted.gif b/images/icons/decrypted.gif new file mode 100644 index 0000000000000000000000000000000000000000..98a11d157144da490598355b7114a7ac51f138b3 GIT binary patch literal 751 zcmVFMeE`ud27h`6}8_xJbB&CSNf#^K@N zsi~>T%F1kPY|_%wo}Qk3e0=8S=H1=h`}_Ou?(WOW%k%T|(9qDw$H&RZ$+NSw+1c65 z%*>;sqo}B;t*xz$jEr(}a>ByG&(F`gy1KWww|IDXd3kxJrlymVlYf7I{r&yGz`%BP zcIfEn>+9>EpPzz)f|8Pwy}iATj*ggww4 z?d^SieZIcFva+(PtE*&WWYg2rTU%SFr>ACSW?5NT@$vDbq@>r^*Sx&EwzjsfudkJr zm5Pdrxw*OA+}!{F|NsC0000000000000000000000000000000A^8LW004IYEC2ui z02Tli000O7fOmp}cRxlKPasWcCWMZJHW_wy2qOk|18t9v8Fh9MH&;nkI|Ft>n}cE` zRgHrsI3yQdsVp%L9FIUCC_||V1#l&s7AF?Jb~8+yMLasGDqmRwn{x)wsSp^c#Ziw= zWpW@cWN%|L2O25~1Op8)0fY=_2LoUeB$N7+A^Vvr-w$3b<>C@`>~!2=2tGOAn9 zb&yaI;ARU0lWZ_lFx4Q!g`aooK(RsLg98>D3WN~=;SzxyM4;9=QbR(E76e8-C=g%* z$`2e&w1~x`;EaY8C3eYSk$=>2Wx-7|`lFG$ zQZ(CEOZ?Q$-+6S*Qas{tX7i_``>CAiV_WWoeco$o`ns<7k$&}~pYO`X@U^x4$GZ3E z_P3rlI3*WBKan>SkQRXH4yrj`)Uf+-qpQRyp~( zukx*`_mh70=Hc|Bp6Xms`jda=SWNkne)p@P>|a#rSxx`{|NsC0A^8LW004ggEC2ui z01yBW000NOfPaF6goT9!9SJvZFk(=Ke+D0JRc1p(G9){N22XQgI4lS>Jtz|Zg9H#W zU|J~|XnIp2YC;}@JXui0}LlfO@awj6$*UI%o{;RS%PJ9cxQgs*nJKGBZ6If zZ&ujZYyokCFhMy>eeLcgATSq#KQ0te7Vdp{PC7;lg4U?O0EEw-J`J!iu_Hl%hCv*- sL`Wm0h6x)YzO*<{2!NLuWC|1*vqAtzLq3XRNphvlgF296777FaJK?ZGGXMYp literal 0 HcmV?d00001 diff --git a/images/icons/disabled.gif b/images/icons/disabled.gif new file mode 100644 index 0000000000000000000000000000000000000000..0a49f2c4397fa73e0d8a0c953cdf539bfb3f76b8 GIT binary patch literal 816 zcmV-01JC?NNk%w1VHN-u0Oo%Hsd;(-GBW>ISpUSt>p4086BGVBJG6v^|D2r7ySvjG z8nshX|GT^O_4S!}c*JXK+(=0Ow6y;V3;!Y_y9Cd)lNo)8efpP%0p6z3Tk$g{JKcl2~J9cjEo*Q8xJER4;yJGjf4#c5I+MZpeA)CDH}VPQ9wv9 z5iUtGH82$`F9;9`jB!^&3@ru(3PnX1Y6U0*3mf uBq=~ahrUc%002pW0)+qrU=--^k%_e>3T>>!*e5CA*y7-f6_ literal 0 HcmV?d00001 diff --git a/images/icons/duplicate.gif b/images/icons/duplicate.gif new file mode 100644 index 0000000000000000000000000000000000000000..e4cab368885aa82590b37ab356e88f5077d28bda GIT binary patch literal 636 zcmV-?0)zcWNk%w1VGsZi0Oo%HRD;Uy_4{g-($?qv=<@tsht86_hk;C>i^5)|J&;S(&hj0_y5}J{=C`u?DPC@nA7X@{PXz#Q-aTL zn9}6$`o!J&X_D2Q!|HmZ)OMxQScA)!wA}Uj{;$#Va-q`5;QPHpsB|NsC0A^8LW004ggEC2ui z01yBW000NsfNWp~K|w8ETL^!PjDJ!Ucswc#S8i2Zjf*K*5^orHHc3qonSTct5fM5Q zUjbS&r3Z9M0})~|6b1%iI5QB62V5p5YeEziX=wyRMo4XS0&{RoO9KX0P&pZ8c5*;9 z0xNzWejx^G5)wHlUprI)0#W1T22MUdWG_!QE*vmL^UPg%@W2O#2`8p-Xb|8G2o!lX z^ms7f2%k6^&^Q>=pn!&t07~>3(Z>S`5haF{au8r-$&*n!lwzU4rAZMA^pxs=VgZ8% WAV8Q&K%>;24p}THRSKX$AOJgz?~BC% literal 0 HcmV?d00001 diff --git a/images/icons/edit_form_32.gif b/images/icons/edit_form_32.gif new file mode 100644 index 0000000000000000000000000000000000000000..4a771fcc06c4f3762d9694d3f1e5ad2acdc9a66d GIT binary patch literal 1094 zcmV-M1iAZ1Nk%w1VITk?0Oo%H{QUg?>j_VF>eRND^V!J%(oX-j5z^iC{_1G{>`$(_ z#(a@x%qQ1VqtE;Mqm8jo)E5gFUaBy###sBBCWz~mM%f-2-a$1bL|IpCR z>gw!WTw43dIo#XZ`Q_94l`oo_oBPKXyrP)?*ktwf_5Q*H+m>v?q<8W0^5x~~{AL>$f?ehkcrvmHfhBtgNt9R8;@Qc>btF zUteB?tN+&I_|MPK*x1;~$;{Hy)u^bZ{`>ay^z+lx(W%e>@bdP#xw-$JC-sRR(9qGY zuC11ikiyXGd!+xz#>cGI|Nrj3)X>VhwYRpw#>93;)YR9_t6s&ox!~T~|MtLZezpJG zKbe=2pP!%QsX*zXTK}~}|KFeg_<-4{jQ{$Zgr3>|zc1$I>;M1%A^8LW004ggEC2ui z03ZM$000O7fPaF51Sl7Fby$OojE#nv52E6)GZje855F0~H)PxK*Feo5K|j zWqkbj@#4jv5(7Av9yZqmGt+zs`awq(U1Z<{9{s@~Lkc`}VFU*cWLS_vJT!4#f(r6r zgcxh!aRvxIFt7kRN>Je9i!kos2X6?9;D-)=xN!lBDH7nyY&A3iK^R1a!NDH@*uVj! zjS8}nVHrHEK|l`!43JGcRaE8(05Qn80v%QmR8SggkdVXxF==y5JzJ{aKo>cPASWFn zWRO7;SLAsG1P(yK<|koH!Nj10hQUJyVrZD*6@GfN2n0!*V1o^kW}$)#S!8NM3=I(R zr)4$-v%#oflq%||#vtS9AYo)t4KY&?BWtRkHbO@ibf}}NI&`SI>K|PY0mZPy7HjMk Mwf?H?B7pz^JIUub`v3p{ literal 0 HcmV?d00001 diff --git a/images/icons/edit_user.gif b/images/icons/edit_user.gif new file mode 100644 index 0000000000000000000000000000000000000000..78d46c24541a80ae08c19eba34803c6aca0e2e84 GIT binary patch literal 744 zcmVDS7+nr8{frFq4qX2zXR^V+ri&68(p zo%;Ixh*$}%fH3m%_2T60*R+W1>+*$*sgGwWy1di>)SLgwiu~olprpL1f<45>+W+Ob zl$o;4&fT`T&5e<%t+2<_)Y{hA<^25ps;$JMaTdLmO4YS|muVTiyxM4MrIMDh`t;}O z>hAyDu7iZL&d}Y$#nsHZqn@I=)z;#;yUx(k;GCbr`SfrdV8(No@}S6$+V7F(x7IvlxY0dr~lZe z&%v?Z#h|mAdcKlA$I9BFeoeZaX|#YH+t0zRlXl+J%7IuMqo=_C?8$~)Af%|k^udIy zt;w)}B=5qGjbIplfvu;AR_)B3w~$HF)Zy*w=YWTz-{R)~>cxLoA^+5q|Jj~!bELed zkam2a<>v0Rw#(tu!{^+|>)ywPim;1~xw4UBx0z?y+2g;#)BpefA^8LW004ggEC2ui z02Tli000O7fPaF6f_DZ71_c9zjExRfB_&q}dsvN^e*p{(WCUVUXp5MGcvl1f01PM% zCMTnV1_TEITd61+Xe_UPd<-WnQ4^>W88W+4WM>y$2u*HY6UMJlRZcE08*LX$W?H*{ zSqT*tPuPmze{y3M76}P&1vuz-Nfkdo7H|Rb=mSjbU;?N?C&*b#wH1O;n8tRV6Qga8#Q*>QA^8LW0018VEC2ui05AYB000I5;3tk`X`X1Ru59bRa4gSsZQppV z?|ct;2ZHdB@u@NsfD!vhfxv&K&>jB&+I3&>{gouh?t-xa=XlCCks&` z8V!g!j>r;{6?hFBdk}q52on$$fp`XbRU26y69)#2jCdJj6LVP`2nM2;nH3X7VjWKc zqof9sVj=_rw6vnMu(2BkwY{&gA{(r|v=zC!!~z+Iz_JLm2tmyw9S<2B*cA^Pu>}+h z;1&uB3F90O9v%T6JPHrs4i^^;7zG6Z0|Ocb`2z(W4;0|w059G=3=aYX(7V*g__V8^{rvmw?d{!;X40W+%%XJEqHOEHh|{5Jz?Ns;vw-z{dBdA-&Yo$? zmtdZqocH+p+Np1Tcyjgi_5S|;j*X1`{QUD|VfVnl^I28M$jbEe^z!ug{r&y&O-cX% z|NsC0A^8LW002J#EC2ui03ZM$000L6z@KnP6w(xx4z0*+I%zH%An;f^ub^!92X#>w zoj{DI&GN2_4Pi~7eRGvXAR1#69Ga`^a@DcD?gA*etz%Ym~+>C!U0Ok-_L_&jo2qqpx$bf@M4h$CHV*wHs zxEU~G%ACQ#gA5%r3ao5Nk%!OdpFn>yVBkY%#|#ui^sr!|#|0HVqN?E0!+=i%J$PK` zQ54@Tr3so|@adGS4WBl$ZtdEULJ6>9hdPy86>EK!71Mbf2l14od10|$;9Jv=04yVo&X!ILH5xRH3m=EXu9KUUQv!h{K}U&l7xgZAH! zC3dme@j{00-@t)S;LI3>@k}dt>sZdbd2<;&9x&nH0ssIP)fF%pz`eV7?>cHozanIS x_V4JuGZ;@kgn}8bA1Gch= z{{H^)@$oZ?-UBzMGKAZ`%jOnXy?&wn=jZU^;pkkU|8~0nJc0iVN3yBQ|MvFwqQw7A zqUxHw|H0Ag%Hj38-T#oY|4x(t3{wBI)&JVrXg~|Uda{nD;|JT;wfW-fMzyEQz|H$6+#Mkc6&f5L`{`mO& z_4WDf?ez2W`1<<%`}_R#^!WMt`|0WO=;-nG_WAq!{o~{A`T6|x^!eiA?TXI-@9*{0 z)YRqV>-zfo=jQBTrvKpJ?9I#AuhIW9ecN`7t@XOWek)+S&=I=O$ z-pI$)v)1&t+5g|)-v>Ud5>dF{-|PS~q{YR>?Ck7;fr0=3|NsC0A^8LW004ggEC2ui z03ZM$000O7fPaF6goTEOg=;V{ON|qcZf;CWKb0?+FE^SYoFQ)+f^-HgEfl5;3vwW7 z4LLbDI2S-bLP8j~L%DizD^3OhUqnbrCjmNTCKfXV1t_$qDYHMiSW~3(3>qo>U_X+DFF>Yp?;JKlWNZh1i)bR=RvDRkQt^{1q%j% zjg)2o{UkLibS_c=QI5dXidOB{uy`5hB?}cTm9A?6M`7SVKuQod4I}>BcCmvij{QNF zo771LDt3`x!O|q9kCleGJSj;z@MSDhLbY2=YeCizDJ GAOJh_bO5RV literal 0 HcmV?d00001 diff --git a/images/icons/fileprint.gif b/images/icons/fileprint.gif new file mode 100644 index 0000000000000000000000000000000000000000..88b03326311ecaed91e59a83c1afff8d2a90a101 GIT binary patch literal 379 zcmV->0fhcXNk%w1VHN-u0K^{vvBmEB`T41-skF4T(b3Vu!otGR>@;n^>+9>}%;&b-`d-6Yse;TZ@UEpacWv|* zG5~;KzXv!nHUTUgN&yZId47k75(XDaD+&)k4H6O!m6nzj20sA=17{u$2NtHL2L}ra zolG7Bp{@-Kvi`P0s{zK2?);D7Z^|p3JM4U z0vZGg6dUH}=;i|o1PS0N1RD|a^!4)->W2lwvX`~CZOpg9b*0g69a7#SFn7<53!gW`mN{aS;Jw2=_Emy9=~c|yE{ zi)xaJofCs(I9C+Eq!^=sqk(3kfSH=DueB(@o^~LIx@BS_2eW=KqcfWryAH2l7{^9` z771n91a}h)SyyHs!Hvv9JV61{ilW9LN*bZe8(Ekb7(Dp+SfAT-GO=vrWZ;VX_~|1T z1LsD0Cac&#fB*0@*&Ug+fq`X)4u^0P=Y|BQHOx|ba%OrIE)wTuPl{dez>#}ezrxmv z1qF&>LOf9iR>Z8l#MvyiF>3|G!KKU2&a&w_!lCTe-Kg)-%w@X3wddkukI7QJEDY8F DXwdEd literal 0 HcmV?d00001 diff --git a/images/icons/flag_green.gif b/images/icons/flag_green.gif new file mode 100644 index 0000000000000000000000000000000000000000..c39406e303af9d541579bc2d3d76eaf1d4197058 GIT binary patch literal 268 zcmV+n0rUPxNk%w1VGsZi0K^{v%IVJZ^z+EJpPX+scg$z1i(-@0g;<=MquQCd=d??y zG*pyK#E?gpuBxTS$g1F?vE!=Uvv%6cxmb^6v3@wg>b~Q@i@TwJG94D4+^2rfYjLq> z;?~I4qE?4k9smFTA^8LW0018VEC2ui01yBW000Gv;3tk`X@0=8EK}hX(y43}q%8qe ze8Hjo3PS}@NeCYJ5jnC1O*a8SAQ)s(!>v(2 znvD))AUZ&{1`r8a1bGw}eFzT^e=`6M7##x~A`?Ig3nLN(9c3pZ7ZjbJBm)eiq#_=A SJESm@LU2_ zpi1Bej0om%a6k+W)PlhT8~_ofVc-#bFb~FJVPOy%77D~88e|uW?vqhTj70>nA`KV< zDxCyEq|kDm3CnOUTo1G*G38A7Q9(g;b PAE}0{A1)JCA|U`fUF2!4 literal 0 HcmV?d00001 diff --git a/images/icons/flag_red.png b/images/icons/flag_red.png new file mode 100644 index 0000000000000000000000000000000000000000..e8a602da7b17a323b2c9afe3d8aac62cb717a0b8 GIT binary patch literal 665 zcmV;K0%rY*P)W2MxECPn{*ELdZ1op0xyVpxzDdhz3h^YVPo^S(T97!Wp}{CC5s zOO0&MCbYN{*S_u5sKy(UFm7-Lr)M|odnZ1F`|tp z;QLC~;7ZS9V!0QqC_yL9nVW1CJTMZN4M(R$+ zOTZBsFr_4h`&3JNv0I_O8fwI~`z}0v3|$@I8UFpf@&;uE8s7DoF&~bRfJhmzX*a6< zs}(O~Kx~cpZxH}pS*S{qZRPWYW?G`zW8AQcn3#1@S*BcNV6f!zir{5lPjYZSt>eR~E27PJ0+es0y~s0ch&nN;M*NkCc% zXiQ#beHkC&om4IpK8qPut?)aNVjs<%39&#|d3=N1!OZi|I!ONj#Vr@M%?lVEC`+Fg zAQwL{?FfzVoB-$9WC=Ju7r^r86-w*!nR~wgLM67#gs;7-00000NkvXXu0mjfgI^=` literal 0 HcmV?d00001 diff --git a/images/icons/form_add.gif b/images/icons/form_add.gif new file mode 100644 index 0000000000000000000000000000000000000000..d10211800f5e59e6e9ccee71b109552b949dab1a GIT binary patch literal 609 zcmZ?wbhEHb6krfwc$UQQ?%lhmPoF-2{`}p$_fMZb+jjVNaF52v4c~iFF>X)xyZ3`48u4}AZbmQgAmzyq4ef{Q*dA6iuv1;$Glqnlp5?Xh4 z?@CH+-93F%NBgdX@P6Hbndcf;C+1H-lh)^7F!A8Wj~}X*+j z*On_&8|EF~cx_VK+Pm#L6O!Ba=1)7F(RcXMr%!Q>+rNDIQn~nMLZ@d;-IkcTtx4Tp zUxDDum!3VTn~$&XsWzOnAe~h3l=U~#FgX}yJF?4m4->?HvGY6{PA12#oJ0H37N#~bBj+r zblA%@iO+{!m7V9{;X^!DNgT}1%*aY?qP*ILtJk5%_-|gh@ z_jskztHR-El)+z#w>(^d>SdwWYM{{k{r+2=)?A*_Vv4r3%jZdo!#sn*UWK&1)#*D{ zmOELQ(A?@miO1yZ^wi+)UXj0gqtJS#)IM>vv&!aamcvSr&Hw-ZA^8LW004ggEC2ui z01yBW000NgfPaF6goT9`W@kix4kkW^e-CPCQXn8;R&H^H4@4p_1SM4kKv#P^gBA`V zd{{q75(Ym4UKdb;DlKh#1~efd3=9V=MLB|NU0fhcXNk%w1VHN-u0K^{v_4xZ=uhr_J7Lt>a(&Fpn+zMy z=GfKO)v0JwZJNl*$o1soV~DWh;@;-Y$M5m?+uq~jw4UzVBx{(9w^Cd%V5A zf`o>SovZ)<|NsC0A^8LW0018VEC2ui02Tli000H}U{xhwX`blGR8En;=%N)43E!J$ z7}R|`0u1A@`4ozu%_50J0WpZdXVLL|28SyLb_g;uj=?4}=ui%WR;rT;8X}oQ!VyVO z;*Au9AaO?u6o3?g33(_G2^J9o0tN+gkO=?~dI<{!i;V@FoCyIDC>;O~6B7@N1{bBJ z016H$0S}jtnQxs6SthL)4*v7^V291Da106XILqR9XN literal 0 HcmV?d00001 diff --git a/images/icons/key.gif b/images/icons/key.gif new file mode 100644 index 0000000000000000000000000000000000000000..db2f8d94b213a77606d191941ea42e20065c94a7 GIT binary patch literal 586 zcmZ?wbhEHb6krfwc$UTR=f}O@pZ5KJ-+F$s!=JC`emw8}@p8(w4cY(xeE1In|GqzM z`v33WyAvAkPikM<(f;(pqVLb={{4CPc$4d|_q(5L@%#Pd*yn4uw@%>5a_t!_hKWhDON#pAk^Y4#3zdvofztHkpt>*Wq4cBTk|Nc05ZK2oC*YnOz za`^pm&-EtlKVMhgKR*4>*L7d6J06=8{_d#8kC%JC-Ov1Z(f0Sp-8T;OzdqCbd{6qd zdd;727Jk0r_vic7uMeB9H)>zm-Fa@Z!;My*ueW_aU9&v5H2%{y_m3AX|NZ&+>)nPk z6Yc+eUhw^4*Owd4AFnyTKWp-Mjnlc!4Ij=~e7)=W?LqU`+p*uD)V;qr@$m*1U;r^t z1{8m?FfuS?G3bDd0mTUe`|^gYrsk%M%*>3IuGUNjhK}y$HWn*Ju1wE~lUaS*IZfER zds)-jTrv}7Wfrz%GNz{+v)O2;SSWX8`blp{=MGPHFmK_>P%(2$bJa*-@)quq6A}vz z(G^i+3UF%9jC7YUFih2ov9lHL$rSbFQ;N0LGz|{B%MlgF>uAKBG*Ll*1CQlLr&G-y mS(jRV9D3B*ronMlqi~|)Au$!fs}3gulMeLvWHB)^SOWl)3MIV& literal 0 HcmV?d00001 diff --git a/images/icons/lock.gif b/images/icons/lock.gif new file mode 100644 index 0000000000000000000000000000000000000000..e870736fa20637eef33f5eb3a1d64bc1ab100095 GIT binary patch literal 1091 zcmV-J1ibr4Nk%w1VITk?0Oo%H{b&dOyPN!VG5?1a|Eh!kq;vnIXaANr{@TRETmQtU|GX{sXc+<>t9a|CCbcjadH4 zr2mBrq=$9?wJP_fHMOgu%)`C^f+qf~egB#)|H-cZnpFR;h_s16{P5`iyC>|EVdH=_ z|CVI_jZ^=d6#kAZ|CA^Ho^k)ShVonz?X!ihj7R^tmydp5|EVVNT?_xvFY@Hs*P3qc z+|RVJuf4s!^78WV-q7~z;_&b9#>U3q-{1e-V70Zi`1tt$@YMgmI_Af({@=~^%B{h( zsMNWn?2}Ia=hy#`6aT$T{JxC;uzA*uS*VnS^Ra~b`uhL>|NsC0A^8LW004ggEC2ui z03ZM$000O7fPaF2XG9Q(h>41dL}!DK5MXf#l$3Cna40BsbvvFr9HA(4M2~-Rd?Gg) z88@ysNU=yPw6r3(w+Kuq5Q8Ur2}&Nr5ycT&$N|a$2??yNuW)ZCf?;Kp+GU583X*4^BNjP6S%t;L78B=mHM~0NJr4&;tyO5Fu!QanjA$u>eMZ zpvzIEqQwFadW7)9v114)+qezWGC|@WAXlJ3nZUB53>q9Ugu=j)Mge!(ltchw5~U86 zP-L*2z{C#+BLJ0f@WTY7z;*?$^t=*9hgBI^jcD-W!-jzZGLZPuU=K0s z4;?oDY$VCEwS-p#27HXQ@-?6U2WruE0pXTMlDKsJ*u|T7FJ6En00;h4AqR*C4GcGU z0%NO!C!n8T84KeH-Vp#&cQIM{GUf(!-hAO`CQO+!Va#y+@`g^4)T&uq81edm-j2wV z`@sXig7ehEM;w@b;DYk&iY+i;@VtVc3Jj)DuZ~@LiS65+d;cRLJoO{i%OfxGW59s) z>m>}BLgk46`0{Z?pMCc+klz4Q^mjxH00#Ji9UItTpMio%0HFycv>?R`0e1A@1`*nq zABY*YFaw7j`tgDkCV(iR1QlY~LJc*Xn4*eOw9sONFtXRej9h&1!5wX2VC0cV8rjC6 z9W?3)VviDVQA3b11Q7%d6lAI8mTtHagpf^U*y9jFP zMjwNavBnlzkYMVmsHRFn7OZBm!WL_gVG0{*pfSd+xaO*>u4tsehAD$+(8sXE7Hh1r J8kiCY06TvzK7IfI literal 0 HcmV?d00001 diff --git a/images/icons/locksmall.gif b/images/icons/locksmall.gif new file mode 100644 index 0000000000000000000000000000000000000000..0432dd733ad1a69032aba00f8d0e71271667bb42 GIT binary patch literal 991 zcmd^;{WFts0KgyOSXWM=>zu1O>Lisqq0$|7w{l*hP^1f;yUw}Nk<%R-siTm!&AeR7 zwPv_EGf6WW+ghf@Bb%3^wMjh9p2wz_=h=&I`8)dj{Q2ec!{X8{`K4fuOFg zF00kb=kw`wIlZf$K9i9{23+~#=E6UE!$ z!p&f@2`n|E{oyj14E*|pNz=w}IgjVN03#PuWK7Zbv)OD+e2PY+={ZN|-lSQO0aO@4 zz&XTnKY}1*Hyk(|jun$3yl8+l0vravr`J)*S4nzNQPEUg0KmT%78d@QysCY6tjK=5-07$37(EPOTx=OhM$Qr1+pEJAiA2JEUI`W&?Q8GVYPIQY0@5B;Q<}|WGUt2Z=lOA5E>|bbXm4+~ zttuD{hHXu$sqtUwi~Tj8x~576Xa|qSn`Z@EEEes+rRL^lU}hN%24bntVw4I50-%2g z!?4+G28(wIO#!hWuzk+0s;UCGR;5w_^SjU7)1BpUvrj{Tkq(xa03Wj$MB4sj_%=z$ zj_K^|luD&G)4TCJCt#Vx`eMJlN^EIqQ7V;~nDYH)*fb*u{8Zoz`~`Nn?%9!&l9HZB zNz+`)m)95U`r?mNFKjSPC(B&_tp*0BLZQG0Gi`{_{=LdLkWyP)J9%#>&=vz-g~?>X zRhO+R5>2(=sytdO76SmF{|{fn$>HAxP|!yD#uJdM2)aTl@FLfihtcBCc2alo$OEqA+)Fozui0hw{EZWgWY!0AcVxMfE>0uT0^KI*EEhK O_r1B13~6#CbmA|0b-%{| literal 0 HcmV?d00001 diff --git a/images/icons/magnifier.gif b/images/icons/magnifier.gif new file mode 100644 index 0000000000000000000000000000000000000000..ce4168c1b0639406c4f17cc52e291c90d3b11815 GIT binary patch literal 246 zcmViXHTh|%QuyoytvXe61q-m=c_=EkIir_;LC z^T^)xmz<}%(d@#QXa4{H^z7uzrFy~J^u^uv;qCd>=l8z>$A^8LW0018VEC2ui01yBW000GZ;3tk`IX;1Mq3=s$s9vUzs7!eK#4h4&h4g>;{lOhhsIW z;oRHno#>qeuLQ{V$n*2}($nJl`ur?|ERwI7QC5TL_UYo{?$6KTv&gg9*XWv>!LYB- zg_M~=#6kZ4{{R2~A^8LW0018VEC2ui01yBW000H9;3tlwB@`E_ewiQ~g66G}sV!cl z02UcRf{n#Pv|KgVuF=isUv2;_2d>nM_Ro{Xc&EmcYo!xSatC00M}G z0SEZ^??1!OpMRa1m>8qY%rpY^^kf7cK77ltef!zy&!4~V0*e0ysRIZg3fv$Nd>sRsxkxB)-~oIij5@!{rX zPted%@G>@*XONW@gd69gv`sG&)H*UQIYkL3w3&YEoAAw%r1xGPZGtfnE zW$)a1v=1PFSlUlVGYE4@f1bCH;op0%7oc!qkYbf)C^4yIP-C-W*s%U2!*@{!ZQ(19V(EuUfizx51T z4sT-664YRDGjd@N6y^d3tPlea4+qc-e;K}i|Hbg>6VR2{A8G>x5EFwCLnDI)g8&mR z69Weq2Sc_@Hp42XRSay_Yz#doni+Wc85j%=6oG-u0S*U{3l1H+%CKzNp1WVZe9Zy~ zAQl!$7OiycbOw7Ndxl>?`0Up+25&xZhN-qw8M4o2Gko~@fq{jU9T=#87=Q_gVb`wn zZ|>fGH2d%0KNHy4*j@ny5DNn^C9v|a0u`|^eEIc-;nUAg3{q@T42;YS42*2R0AXMR zI`sv^mTgBF&Y!=v=-am+Q-M)=iV>s$2mk_zks+4hEK?$r5fcX!gTa3ThP`@w8BVjF zW(YnV$iTLdharivkKydOJ4fEUecQ&!$gmTfH2#62^e-@FGBW@K5Ho`q!!za|%zpf8 z{A~Vm{tP05A`Cg#vKXGOeZin|$^G_=TmP$m{Q6b|wDl&?fd8Oy03vXBFfuYR00a;t zgDWV#GWfE|vegQy2x&3`o&4p_F9wPGW^<(em{0!8@aG=Tzreuz2euUyh{!Gg2rvL@ WriXixs?D(g0000ii)(jxYXR- z>aDQ0sj14;_0-qb*AlN1!ou3L>9p|h^u^1@)6?ek^!S$LmdnfFot?jx+Ld#Jk?Z>F zv$MD_6&D132?Y~!B`AYUhiXp-6>$Uv3J4fDBZ-q0m3U7TnSBHS z7zIWn92^u~rIwf#3J{yC6a_a`9|;fvEVYPjimL&g8VWfV3}6=lq=%;!60*vBjd3Cp z3>0g*5DL|o*b;x+dj%^k9S|Ic0rKS)w-T)E3KR^EkXYTpLjVE;LKGH3Q$TD_zYFd_ z86Z@v#}5pH5>U86VGo6m2wWZckfNF?ObQtPTpae0<3|VuK8Y}(;lO~K0}f0$^^w4g zX$~nsfN%j~0RBL)Bvuz|I2&asK5&b literal 0 HcmV?d00001 diff --git a/images/icons/mail_generic2.gif b/images/icons/mail_generic2.gif new file mode 100644 index 0000000000000000000000000000000000000000..b1147b742fba48f2a2bde313983fc7b8b24a1adc GIT binary patch literal 390 zcmV;10eSvMNk%w1VHf}y0K^{v+_wh*^m+g2SO4x~|NrCu{`&v_+yDHQ{naS{`H27W zZ2$hG#*hI0<4*to!sopO>dGMh-aY^Su>9CE|Nrs-|Ih#byZ`TRyN3Ym?Cj>|=CiZ2 z*oFX#M*#o-|NsC0A^8LW0018VEC2ui02lxm000I5;3tk`X`X1Rt|sTca4dIO!FhPD z?_NPsgw7_zaqN5qL&af{EDnc+q9G(Yj5(yzA#p}84UAB8gES;K;I{cp3;>MB_~tnP z79L<_>0BfPaR?A|X%+wi2NX+e3UCM!4G4qh0T2dma1Rp=3=sng1Cq2i1_c)Y25c9w0~ZRx0|Lgi1p&-#Pf-B@ z3Kt9$#e~`hT?^d_3E#xi2-i2veNf)+vBM1V4iy&{)v5_-&>(`r3Gp5=7}KGl!-o(f kj>)j0qQ#3CGY%<`L4(JSAVY%8P=kfZlPFUIiUw+jtQc z9ApFuf`eyxz_>&?!9Y0lJPH~O!SFe38jmLKA!sxLf{!6s)MOvy=z#F}3@`>oVK9Iw zHW*BSp!i4tfD{q~0R#eb1seew01g!w4geB}dIK916b=j?2@a7O2M`!*69NDgP6!AI z016Elmm5^49v!L`ttSBxBNPjp7YmUD1O*W!j0*@13jn3ZD;X3P762SPD<2^MJGrlP AZvX%Q literal 0 HcmV?d00001 diff --git a/images/icons/mail_reply_16.png b/images/icons/mail_reply_16.png new file mode 100644 index 0000000000000000000000000000000000000000..cfb937993432c65092a7be57cd4ddac575a44a7a GIT binary patch literal 1061 zcmV+=1ls$FP)>nM_Ro{Xc&EmcYo!xSatC00M}G z0SEZ^??1!OpMRa1m>8qY%rpY^^kf7cK77ltef!zy&!4~V0*e0ysRIZg3fv$Nd>sRsxkxB)-~oIij5@!{rX zPted%@G>@*XONW@gd6gipRe*CCw#N|#984{!N8}^&v5+j zafV%|wlio7s57`3xiAO{a{&WZh=GTP1L%dn4Bx;1V)*pw8^iVM548aTh>1a%p^?Rw zMWEk&0z;cx8-qBrI0F+O6T@%4KMcJmTN!xy85s->6oG-u0S*U{3l1H+%CKzNp1WVZ ze9Zy~06_r0{{#RO04jGbcK~i4ZUFQB^8iZ~O8`X^MF76?z5t=vp#bvw@Bjq)1_1f_ z`~bNcg#nln{&V~Xhd9W9kBlD~c-VLt*g4r47+D#C zwlV{q`hsE0wxbN^&)-_~?c0y3z^FXM$jA)V0}wzg46hij^*!t}lIN3WNaagq*z|rA z!?b|j+MuwfNtStXPF#`ht0mRH8%JA&}m;Zj3 zB`&i`2}v<c_8dML=6`GJ+fg3->W}&4zYKrw0sRXMynnzn@fRG3AQynx fOiauS009O7q=uJJ(R^M`00000NkvXXu0mjfudwWW literal 0 HcmV?d00001 diff --git a/images/icons/nav_end.gif b/images/icons/nav_end.gif new file mode 100644 index 0000000000000000000000000000000000000000..875447bd43331ace44fff75c95fc040651258bdb GIT binary patch literal 597 zcmV-b0;>H-Nk%w1VITk?0K^{v&D!&asOI_l`eTgPN{IS4ZPhb$>~EOmv&ZaLgVdb1 z=8mY^^z`(ozUb`i?Azq_=I#09Iv1* z?L}YgodKdox;1_s17@qj~pHz9FUe8h#giV0uE~y0HLA)lam~y0D~16 z9SI{?3P}~Hp{1sxk{$pQ1|4XfYZDs7#KX3x!?_xVK_U!{1``Su2-VgI$CL=U)d9UU z3=~Nleg4A2mt^)6>SjL literal 0 HcmV?d00001 diff --git a/images/icons/nav_end_grey.gif b/images/icons/nav_end_grey.gif new file mode 100644 index 0000000000000000000000000000000000000000..b1d756112cfe6d0db46d34fce2d73644f8998535 GIT binary patch literal 642 zcmV-|0)72QNk%w1VITk?0K^{vcXxMveSL<8hL4YrkdTm+l$4m5n3|NsC0A^8LW0018VEC2ui03ZM$000I5;3tk`X`blmT@f=7!@x*cntEL% z0DSKc5*rBz@$m=;M8GJp2t67?PvEF%uA0n6vhW2_9?p*ExMVWd%?6vPba@b!_-MhL zGnhi*e#TfHJzpdp6FdSG78i;a1sog&iHjE&5=#ITgBVMP6%?JF9ifjEq!bh|4u&IP zfB+4qpPn5aI2{GB1!@!wa3UQTJO~rR#KW|-9UBD`5(OO`6RiUx&_@jr5!u=jv&Xg( z0~{R^5pPZ!3O)e_3=r<`$2b}T&K(dByZ}KN2Sxxf0ACR3Rx4bG2M!!8LGZzXx-@DW zIU9N0L^?1qA^A1ZdbJ0L79p!yrIlU~il zm;j?8-%{1^VS|N!0KV$|YS3E@0RuIB$2nD<+Wh*Z~8ILmt=>0D}k*cJm$B zycvN4ZwU}^PCz;(016&PbZGOYzybvd7Ra83F}Cd32$0gvM8QC?*RmI!yd7JC=>{B3 z;9$)ofN+e^qcgCiAVUW^7D5CP=%`IjYA-y{|kmiW{%i4ZPhb$>}{Fqv&ZbHzUWtj z)SR~Fj;Px6^Yh&0_U7&R$k+1Q+uM7e;jO~zk*?)gjqUF8`qJL@I)DGZ&+cB5@nVzh zJc0i*Xw3ir|NsC0A^8LW0018VEC2ui03ZM$000I5;3tk`X`bl$AOhhM!sK{qjSyX4 z>_y%YlL4(Za^MOE1EwMnNH9rVLP$j9lnaPuz~wp;8$<5U7@n*J48>t-yWbW>prN6&-b% zB31?z5V5kcqolL36JiT?A2@m$z`?+^q{6@wssNb}9R>^t(9zPwlF<_j5@MJit_um@ z;Nc0>8x#i^=wcKN9|9c#3-N#R^pM0G==mKI0KEkj6e!rEMlccw4*C@IBT(Q#lY$T< zVL*tXfI@#7BuIz|@gO>j3-kQpSn%M%WbHc0a0tMXBr%f+fApKs45m$()NG1j&@Yhz zmOz6BIGFPwP%#MldGIBarAcZ{1E`9??gLE&8nSBDN^PswodBv1z)|6V*|TPep*@>Q zK?G$YJV3ysv2NX3cJ1~^5Z26q1azASe&}JaU2_gf&>M05{x!uB6EWUq46ky?L&d(2BcFAXaFDsgV(zi Z5P0@BEMp=cY!e4Sy?R*Sv`2&h06Xgo2h;!n literal 0 HcmV?d00001 diff --git a/images/icons/nav_next_grey.gif b/images/icons/nav_next_grey.gif new file mode 100644 index 0000000000000000000000000000000000000000..c44ba0cd0d1b0a1d976a2278a193f3da0740f8a7 GIT binary patch literal 607 zcmV-l0-*gzNk%w1VITk?0K^;scXxMveSL<8hL4YrlarH_l$4p7nVg)QprD|kp`oRv zrKzc@u&}VQva+|gx4pf+#l^+Q$jHsj&D7M?+uPgX;^OD$=jiC@@9*#P^Yi-p`v3p` z|Ns900000000000A^8LW000~SEC2ui03ZM$000I5ASaGwX`bkbMGHX;!~#`YYC{8{ z@B9F1HQUIN;{^-`0#D}v3Lm_M#Db|-Cyc=EkO`h5+sVa>$&fElT>#@Hr2~)4cx)jQ zs&k7(pc^B|4-n4J&JnG^1kVo+2Rf1tIt>rs z;NcIyuNea^OAHwt3pxu84FmG?^90kIN=pP49DD)`EffhHIL%dt3rmi1$RQwsf-;*T zZX!o6SVDe$1{_FGkfO&|$|xx;B4EI%k0@Q-X%WfK0Du562c-O%L1Z5b93Uiw$+Kri zJ})U5;5R`{&!aC3W-uxe0!|G@j`GxT;iRhpQgukcAcBDo0bs*|HF4asLlz@8|4OJZw+)Je6doMF3KRH)2^Q4u6(XWJ21kw{jwcZU06X($^7#M& literal 0 HcmV?d00001 diff --git a/images/icons/nav_prev.gif b/images/icons/nav_prev.gif new file mode 100644 index 0000000000000000000000000000000000000000..557e6bc2a783346d34065fb027f7213f72f262fd GIT binary patch literal 589 zcmV-T0iW{%i4ZPhb$>}{Fqv&ZbHzUWtj z)SR~Fj;Px6^Yh&0_U7&R$k+1Q+uM7e;jO~zk*?)gjqUF8`qJL@I)DGZ&+cB5@nVzh zJc0i*Xw3ir|NsC0A^8LW0018VEC2ui03ZM$000I5;3tk`X`blmIg>!Vgn&G0>J1ao z?L}Yg9Ri|8x+Q)cg8?HE2r3xmkKiDB8i$=>lW+{aUkhXr-3?J!MW+xzSl;ls#X-UR z&ZV2KaJW4FfEyctfCvG1CIcC3eGZO~8y+4TkB<TxH3XnzW66^S1IXmS&mV&%B~22{$usA! z3H}fyks07+L4ib*65Um$K?F5QWg09QRb~(m9~uC-X+VS5uNn-39s5&+ucsX<99YZt zK*6?cD+C!J;tGHSYe4GNOK|Vr9}uvbb$YWv6DNoTNJ@-Y!jA-WNt`Wwn6YI6jyo)f zTx9YN1qnlo4y{J>0Ks|ACQwsAfdmTq@==iRa8-uWHaG!@z@YRR1+_mfXn>oD?%fC& b5C9JRbp`;$iF9tD6@c~Y(21ii5dr`^w1)#m literal 0 HcmV?d00001 diff --git a/images/icons/nav_prev_grey.gif b/images/icons/nav_prev_grey.gif new file mode 100644 index 0000000000000000000000000000000000000000..f392ca035ec2de783422f95dc2da311c9a2398fd GIT binary patch literal 616 zcmV-u0+; zi1BeDRxxupKxtH~)U z4i?(+SP~$^NC7;PDjmwBfxuKr36;b!ROwQ095PUtXtkiZ3`D#33{WFO1p|Zxs1-1v zz}E|Fs;mMojSIli7~EOmv&ZaLgVdb1 z=8mY^^z`(ozUb`i?Azq_=I#09_y%U6#=a_df*BM1I7{vOg0#Ut|25Ma!Li@BItG>4UV*PU<^;!0*3OqxZm&#g3wEt z(VYST0qOf892|cT4+lL1RU{921R4*IkPjRl9vqR6h8-FLB?%oE6@dVwqmz^#q^TAi z2@aehR|XUSlpLg{r>UeBQVMq;IC~nk8XCB##mUJNtgasr9R>>s2(<{ul+@bP6$%ql z8Vnz?3Jndl*dFHV4HO3(@KO}w0UZPi__e2}f&KmP@Gy{Z0IYxo3JCWpT(}P)s|W=T zGzq}4qC$8D5c6~djnDuD!NA5i7_$hYslzI=N$i16!!fChUfDyHaRv6CJP?!Fo!KtW>1m?uD% zY{En390?GL9xd8ahsdtZknpU*Q^pAt@ZqB{Awiu6l2w=R>_CC(JPB<3NDw(fY9fXi gIMCoOc<=+$Bp7Ef8M$W$$|Gps?f`qD5+MKpJ5j#`VE_OC literal 0 HcmV?d00001 diff --git a/images/icons/nav_start_grey.gif b/images/icons/nav_start_grey.gif new file mode 100644 index 0000000000000000000000000000000000000000..2e50c82e8585f4417ffd1e1908fec88e95b378e9 GIT binary patch literal 659 zcmV;E0&M+9Nk%w1VITk?0K^{vcXxMveSL<8hL4YrkdTm+l$4m5n3|NsC0A^8LW0018VEC2ui03ZM$000I5;3tk`X`bkrNzC95Omul^9SK0L z??cqlwb5m;0|X9;LJ{!z1tB}e1f!{HGL%L@ci;d|5*>nq$y7HRYbFED1vFn$I{+!K z*O-Fgj=4~900T}W7dj9Y78i<&1sog&iHjBlIT0KsTTBE66%-Yn1s$Rtouw2LIRY6S zBVhmt6KDmV6pcR~9-p+GZ4GcDH~|q89UBA_6QQ`c9mvke5k#u2894_KJ{<)R1RJ-w z5)u*P;}8!Bl^Y)qISvpI9UKFp-yQGw5DZE?4VMf#3>-KRRX~HNWd#bnc;QBe01O|t z2w=dVfrnAcF2-|&CXEIRI|N+#AWgx71zs}$W*o&*6o*UzEJO^10D%IPICFN;;BX`n z00La3%t`bjOqmCa1PCCYXwjEC42+DRV~aNd-*5?7%C+l`12QSNVOlKc%4$oL>WGlx zLx-PB4Q>rk5316xnPQ1(kcvRrpaqr{!yurr;lcnfsB=psK(`JD2y8M?4}s*%1OQE8 z^??J`R|;w(IB+1r&5IjIt3I#~!UZoQIkXaNRjz(+y|06St!2SWe= literal 0 HcmV?d00001 diff --git a/images/icons/package_applications.gif b/images/icons/package_applications.gif new file mode 100644 index 0000000000000000000000000000000000000000..f7578c36eea5747e860061306705dd54febd9131 GIT binary patch literal 1198 zcmV;f1X24(Nk%w1VITk?0Oo%H&D;O&`2QG){WF#QshAlFm&%Tio8jsIlEwYI%>8$_{o3B|?ehQe_5XQ+tnm8(`1=2wr`ql9?dI+O zzTNb-#O(U|`rX~$>+9>Krl_E-*Y)`Sy}iBJ<^SF0|MvX<<@NuDz4-I?|Mm6t%Hj0g z>GQO-w9CuOh1L0%M}1V^^kQY)wEm zl$Dp6o1LGfWVN=pdQBuCt$&sfDVm&~pkrRg$jNlNysZ#*Ofb?dEpj{8EZHnr+*lmn zdosJd5Ps(8T4iM?CtER31Oz`n1Q{ZDd{g7j=2|uEC#+lu5CBbwA9>&)fkVVhh6YB& zHKSC{PmO;8FARL*2FZvVMJPO|QUw4U0v19nAm>Mm6LwYv2B1RZVug?tx{yRr-~ksO zQdaPD8BpMbCtNIsQE`)k2><{}6u{vJi4Pt^CzZo!v;>s|U~7cQQK7;E1PDq%34_7U z&kvIS{*-%ZG{zhXMMi`jtKvZc6A#$3_4C6Hhy-%|6dhQA2#yUD^eP>(!GxF!7%+rk z3&jEuq2)3TH1ME{7#xukSgZgAN|73wM|`Z2K@G3a8Uw_L(4~NB)OzEbVE`tMzszB7 znsETPoJ`#j3h?|L@(h<21}co8nHE}Ti31Kk zIPh5tH%y_Yo-)kghiq)+RKNyhjj&k)agKmM7B0YL0}u*C8Yu}PJdl8!6-Whu7M>_NYZJj6;Xi` zHAL}62rsa*Ybz`8KtNPg2)MzVIOIhE0ZW9SzyfhSOUVjvh>!;W1^_T8UN{KRKuRxw zEAFlfD1r?5bnIZYVd&qB)Fik!X&)#fenZe{A>a%*s#D0#TbLI M!oU)D+;JcPJO0pdK>z>% literal 0 HcmV?d00001 diff --git a/images/icons/page_excel.gif b/images/icons/page_excel.gif new file mode 100644 index 0000000000000000000000000000000000000000..f75e8a15866f9d084db0469badbce07c2173cfe7 GIT binary patch literal 650 zcmV;50(JdINk%w1VGsZi0Oo%HN`=VC;QK&y!Oh*qwA1qJ^7!lX`oi4!#^3s7mr=ag z_VV`nWsJ*~$#qhV$hp?_&Eou9lgnzC-0<}HUXn>ObsANW$~J1eeX-*8`TR|L#Bicp zSdBzNd&A!9_RZt_Mu5jPX}e{XS3-X-`uqK3l~l*z`t0)e`1}3b>h`X}3pi!gSmB5ibPzNN$&LcNrWly*zZmakgE))3sNOR)n_V!Q1%F=KT8n`u+a? zgRYH`w2*46VPKX^^Y{Do_xoUzRmtW0$l1WO*!IZa`K`#K$>ICv@b}B&`;f8SbD(VB z?Duu9XFG1abfVH`msy9rbHdr>`1}7zfWzPG_MySC>F@PhkVn_%@+<;R^Z4!b z`nk^N@AUd^oLfkQI^*s4H+Ub4!EMap`_AM0OozvCo@mkJ{Qv*|A^8LW004ggEC2ui z01yBW000N)fPZs05f+ArHD4rujDKWtJ3Dcc1t)G85{rxx3npA#0SHVFXjzz=4htW9 zA6{Aq4=7DnOEiCVN(m(|P$MIDGEpZ~Y-xWmNiGc~6dM}}EH(rL6MTP8L|8z1B~uAM zK?e#7bk=`DJ_8MA99AoOCI<&{0E};V6azgt9BV}%2oM;kx23`c9c>065yPPZgcw|? zfcV3sg2fy^X5f$_0zv>TLpm@5(Z!FSGkrvq0b|lnh9itR+-XU(Wfdcg1gNQ569vvc k8sLOc;~_-~14yYKYo1u`t|$w@AvQD|NHmvr%#^>x4wG%_Q$JNuRebK z_~_B2)2B~ot$OkP{rfLpzI^`tIcfcigmtgdXFq=P@q6mxr*GfBefjcb=!6H`uYURP z^;hMNH}AjxiJbK~edgn*uYW|%dlEC@dg{{qsmouaZ-4Xp_3JNRe-v$hz5eLivfXd8 zw!VJ+`0=x6&k8oY+H(HW;lqccmpzM}^6=8budyp$y!-g$-RIv)i=JM*|0QkR%cDn+ zzW(r|bkoZZA3i*L|MSh8H{o+0KY#xG(4j-G-hVrA^i=B9hw*csY&iKgW5x5LZLbp- zJT2V(Dq+ows725AA3B-3@puJWNAX1w+RH@FV0aqHkRT%}@Z zO;^_0==AQXF@9ejEdeb>`TJp{T*~l_AoN?s%k(By$u_hsgc??BYv|}m~JP$MY?=h-5;@`1k_PXusSp5{ItX%c~+k?Uz z40f}5zJ2?aKd1J>_c;@mFDbarP&KhicPm5d>8Stz|1%5_Q2fcl$iNWJpaZfW6ekSq zr48Xt%`L5MZQgn|?X3!I$|~wTO+mcO&Pq&^J@|a3Mdi(Vto?!w1;cdp+a-iGjD$>B z8QKH1Tp0!2`Tg6)xk6b2ja|6gE!Z`!#B3cn+f^N%+{~mzCL2h~@yJ?E){*hiR^*r* VZs%nhV*e~$&2!7!Pc4lM)&N_0t&RWy literal 0 HcmV?d00001 diff --git a/images/icons/resultset_down.gif b/images/icons/resultset_down.gif new file mode 100644 index 0000000000000000000000000000000000000000..585e23af0b315718e7ab1e52efe3ad6f379fffc4 GIT binary patch literal 300 zcmZ?wbhEHb6krfw_{zXAbN8#d6%W^*cwe*fVdLt@IbD|UIluejXQ`x+OXiPP^ow_ICz z@Xds+&zaX?!G#6_sf#S4}$w{Cry7S=69fc$^B(V-n6cNX+|z+ldx z1Cj^%iGj`Y!0ZAK9jX2kONuGeoLy__?q%3q=$%%$|9mRYQ!g*XzWBNf#52 lOJ!|PXoy<2MEz(`ii)?qtgx!LxuCd6TX#=yU%w-RH2`2}jgbHV literal 0 HcmV?d00001 diff --git a/images/icons/resultset_next.gif b/images/icons/resultset_next.gif new file mode 100644 index 0000000000000000000000000000000000000000..534f12361e5e185ea8a31f1af8bfb11a67269a79 GIT binary patch literal 303 zcmZ?wbhEHb6krfwxN6QYbN8#d6%W^*cwe*fVdLt@IbD|UIluejXQ`x+OXiPP^ow_ICz z@Xds+&zaX?!G#6_sf#S4}$w{Cry7S=69fc$^B(V-n6cNX+|z+ldx z1Cj^%iGj`M!0ZAK9jX2k!c3W4b|&~da&|CwZQVF?jq1)mGp&GSBBG2uEJs@oT`6$l p4tsuR%NnibE9!@iut;ghg>wq9n}(a~^RRZ9tMK(soaD%04FFw+j+X!c literal 0 HcmV?d00001 diff --git a/images/icons/resultset_up.gif b/images/icons/resultset_up.gif new file mode 100644 index 0000000000000000000000000000000000000000..29ddb97eaa22589ee23f1834881ce4d65dbb4afb GIT binary patch literal 300 zcmZ?wbhEHb6krfw_{zXAbN8#d6%W^*cwe*fVdLt@IbD|UIluejXQ`x+OXiPP^ow_ICz z@Xds+&zaX?!G#6_sf#S4}$w{Cry7S=69fc$^B(V-n6cNX+|z+ldx z1Cj^%iGj`Y!0ZAK9jX2kONvhV1nCK;WnTKJqbkX&{nT?-l)|B;hE=kOCNob7tTN$i lRXU_PBbQ-LD8r!w0e>@oLuDl?F$qq672lrTJ`YC*YXEu$j4J>D literal 0 HcmV?d00001 diff --git a/images/icons/search.gif b/images/icons/search.gif new file mode 100644 index 0000000000000000000000000000000000000000..5e4ed4ab1688135eb62fbc113426093cbaa6da67 GIT binary patch literal 331 zcmV-R0kr-{Nk%w1VHN-u0K^{vv9-prZy>q%{rB9Er{?-_LL+~z+1393nA!Ko{r>X) z{$OT~0xUWTA)2APP;@dGee2!g}`%hU)kn`5Mt(Ig%ZLPEe!5CBJt1)(`S z4)ugy&xp@~OlJp!gAs8V2whr(Xm^G>3l@zvOM#Z6 z4GUpM4hx@VmYEBrQy;Mgw1XJ83=9DmQ%MWQ#{e4*5CIayxl;iH1JA_KE)&z$0T9^P d+t1$LEZWrKCNk%w1VGsZi0K^^ui_?Z1st+Qs6DYG6Ji;WN;gTS&5-_?QM#(Fc+l`~- zmZ<2MOwKSGsSY{7BNnF&L&qtR*ovCokSetqj@5{)>zp&ZAM5M$?(X$qU|=I{9RO6O zVq19s|NsC0{{R30A^8LW0015UEC2ui01yBW000GIpeK%GNp4~`svbJJ9vi>nX5V;T zul!EWDW6G}>2yk*BuB$!Dmf#Lv7?~?0GcUOB)woXk;Wry+KYGaYN~K@J~n$L81__h7fq4GsT@e(U=OKKS6fQCVJ4*u(%BK(G%W z%(VymVbs*>Q`h6GLfrb?EaOw|G0LaFEp4dgJiL%VLF1?{i?H{=3#|PxMOa0IxjBSc zF=KIvL|kAEwfi}Q|L}rL%JT_Yy1T1Pz^sFau?p2^6V}#H5QFt4s5UQzo0j_%$*lp* z^cZ)%^@GQeCCf-c$K?lfV4N_v(8o5Qe@y}cv}*gJfh`fY6=Vl0Ee zD(7T2VSj0p@$@|`%p!tUTXen2s%NQ?@!iH`et0hct;rGnP16VuQSmWDzJH$P0fnlT zqh7GsztZ4S=D8F?3YtJRvurh*1IT*kn+!9@Q1YWW^56aHHcNxO0SF zx%lMeh%<5RAE46FloZAow~5Cbq*c=($%%*3k;Ln9rx~qU$vC%D&{=W6RQ%>zt|%jN zB1V%2M12!9VvXIYN3v%!;u?1bqJbw#Erq`)*OSh1qf0rLdNjv#Ue$ho#GH)O7G=eQ zHM3$mT~NV#|L2sDF1^a(7t9W#27p&G??#zB>$2{uyrBw(E>6zAt>)`2ykii&_hsB^b!b;m4OEJ5M3T> zdBJ(#&}Oa66f@Uy^D-~fR=VpsJKN6L<(!@0?{_W>|B0UZ{(%oZ_%1Y@*VZ(tF*U~N zF@arY!xLFa0wE($I}q(e@z02|i}EqYp7FD! zM_|?vN!x49nB=Q35g}51aye8(l*nl`P5AL$AY=N!pfx+7C5%B$5Bkk{#6oT|b$8>ZTv?Uj42B@?o#Z*s-0 zoSITY{pAC@nu^tVS0Co>kw4g1S!Bv>Y~5e%RTr2x8xP7gg?ja&&WYzcuW!3weq32s zP7_Nq=d-+d2Pp=Ir^-f&cT+{*%LF2dB1z+6QtJ7)8k@8EP6Or;*-ii(|8Z zOsCW8V<9khaOy$e0bnmEK!S*aFvA1Vfxv0Lau(?yx75T@z)Ppo^1mW5c5rGZns@>w zZ$s!1?}K?^fKf(ZusrTO4_Qg^5G`+;eM^hbM}B=|;U}Kc;K! zxFN|0CCTL+fVwg3ZGCM}T(}&O;98$P3jy@(;GsP^j-D2P&%@s^SGoL`e{`5Q)L)-Z z9O`H0y_L3~=ezrQxN_Ctop;L+?>mCzJm3MI*04Skx;{C`cfR8C<&i$VIJ_Q!15YjU z{jVE!fzQ0+wJ5KRb8lVk7$ezSm7ks<3{1cBn57+m5-2r7S;+@LXXC(nhPQN6aa#W| z6-QEWWJl%AXWF5s+u&QHMbHe;&3l19z=#2i{oswQz+TJ^+`c`BA9UjfL5uK}YQTxV z(oy*z&MkMe-t!f?l8ZtIa|755qm$LUZnhF9^R*b*2SB`^fu0f-dv)UaFy+tvX{qh{ z!m`8r%NpnAh8l};8|(!zdUpZmYXn9CHuXwWWbL)1lkx*kEd!#1?Opsc*Lp9WNa6yB z_%M)c5YSChNtbdP>pLl5Yp;3iJ`yD!K^O-j*p9?(P!}dW371M$*70$UKmWLC66*$~ zw0aQMQgX$MbJh0$m*s$HBqHgMw@qR~ePY_QTGsI^4QJGgiNM)is3!1L>=RMG=O+*o z;01(Fwen^G8HWQoXVLLOsnR2?pvU@!k9VyqJ{~fRZECFsNlWDC9GnovQWd$`7p49ihJ?G#_!R8GDBPNIm z)`X^fCf`}%wKofRzHC;W1wH`mTG!OJEFT{q7eLpf|Lw05?>mB~k0lJjXEt>)GAQZq z??u;*mODY!g$?9DbNk%w1VHN-u0Oo%H|F*W`f`a~Zbn$+E|G~lky1M_0isISX|BjCTk&)BQ z&G(9m+7uN38yo-e@&B!@@^o~qTwMNref>g0|9N@ztgQa$=l}iv|AmGBot^zvRsXWG z^YZe$j*ipN(Epj4^qQLg#>V|xTK@$Ftzu&TGBW=qCI4k*xCRFPEG+(EVgI6{w-^}n zgMBd@G|7vRg%F4EUe7sy-{|ycKl9K=7 z;nyQ0|7~sbPEP)Vga4(a?Mh1j^z{GR+xdZk|42x@oSgsF)wqR){`vX;`}^GYWSX>`|Ck$YKh~Ytzfp#(=G0~vG3?4Lez`!9u0)-982KsS;!$b;} zGr-Uo!J~l*1351UL7J?Igc2oK?w~QFrG#!wFlf+#p-HzRP)qFK!yrWp7+w6>k#K^7 z1Rz3x9Qdga1PKy0Z}gyGFrjY-3P48slW+uth!ZM)pg8j<4+{oaREQ8@;NXxU_atBt zpg7GS4>j;;!H{6Z22`m4JZQmyMHxmm=)fT&1_FcuEm{m1@I_7yETlM)h(UafapJ_| gydX8GPXrRsBS>%Kg#+_JHWYZ+&RxNBMu7kTJFS?JbpQYW literal 0 HcmV?d00001 diff --git a/images/icons/textfield_add.gif b/images/icons/textfield_add.gif new file mode 100644 index 0000000000000000000000000000000000000000..a0544c34e328939b0ad588612607e6ac3169eb80 GIT binary patch literal 132 zcmV-~0DJ#ONk%w1VGsZi0HOu}#_^o$>gtH^2-4Eh4{!i&ZEgSm{{R30A^8LW000I6 zEC2ui01yBW0009?Xu8~6Fv?bfy|}P4y8qhqc?2D^e6atH*pYVoL?T8M>H|!`i5&%2&!ZUdQ literal 0 HcmV?d00001 diff --git a/images/icons/view_form_32.gif b/images/icons/view_form_32.gif new file mode 100644 index 0000000000000000000000000000000000000000..6891157dd8a33a70f939ac63d8c764cbfcd9ff2e GIT binary patch literal 994 zcmV<810DQFNk%w1VITk?0Oo%H`}_RP%-Oxn=M+`S`1t#6wfqA~|3!-bIF#h;>hCmp z|L*Sf>gw_(YX3Qo;qdVGD|^-c{{9tO|LpAYh^FuN_xi@$@kN*B12EE6n*SVO$O}lt z^78lPdN8uy50Yhwf|0&{|r+9v(^72Y11ll)@iQ)W~%=oYsw{Z z&Mtx3!qn`(;r|6bzJGJmW`Tq0E=;-kL+H~G|4*Stpc#O zrvKE`)QZmk_OB=U`ugYQ?DX{c;Na{yhTh@e=!>rZ-{0S_(f=}i+jflOd%*w2+3?@r z?90o`$j8*P*7Ud8|J7jz($UgByJEo zIypHS8UwN$v_iIe6fRE)1!F@2c>-c+U88BcEGUwaFUC8NBmcxxn6BN#3#1%r z%<^T&kyk@YVX%2`=b%qI$~?=O0fP@INt^}=q9cLBcNLFjPz6uyr8|2P2GFr2V!WAM zSHaRG<&Umj?|=Z{rK6SOx|L(;(461%oL<3FC(!W>l+af@bO_*lsav>oJ7#5lRy}*~ zeg6i&ZKWe-DHHI9#daNVabF)0WE5FsC7sa`asUcQAQxX8m>@>OmBC*W=i#ASfXhwz z1sWD&IGu(iamYbOnSnT zN)Y(qLk~T`qCp8%mcYW5ER3L~9$a?mWlAB4!N-_nmTBghXo?X+86ouH=9_TFDd(JP QB4X#Ac;>0+AAtY>JDBkwv;Y7A literal 0 HcmV?d00001 diff --git a/images/icons/warning.gif b/images/icons/warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..a8b1c6ed9ec7d758509163109261600ea9382b7c GIT binary patch literal 262 zcmV+h0r~z%Nk%w1VGsZi0K^{v)}lTB{PytIuf=Z&=($7p=d}6glCXsxa}> ziS^oB{Po$^n^Nq@THUcn_U6LcnZM>oX>?D=e=R}-DCXo#r^u{ z^4C}U^yBo`Pyhe_A^8LW0018VEC2ui01yBW000Gp;3tk`X?}ro1ZSzdMLQw{BGvMD zSi$zn3_`$QKqMqBhX4TpFf5o;VYO&35EwxzK!9wj0FDL%V2ut6gkkXrFBlZcsFMh2 z7K@CdGBI>6NFNv$8*5;E9&imG5Euak6AK)Z6CNHJ8w~Y5S`nscUS2ZhX`U}3M(rGIT10H!T(@mXJaXZWQ*9?3GOd2Wl;abaUd2J zSI8A9QU?s-TG4R6x2xcT+4*`iJ2Tz0)9mmf5+xGI_NNX6*yY36?VAH#kM|X8XvO7z zs~6-hNIh{@A)}Y6va8no&(WTLRbUiy?sO`9ku?X1jFS{^DzA_0E}tRaTUN5MxHlO% z4M6TwXw3(t4OU%es%fC7eZ}6RhaJ6!x$hvCgM})O=W2`?wRCE1hB=`pu!v@pJLD46 z`O8a*ETz!tcO}nT)^wKFtS1ZbJ-BxniVP7+!1Faw!0d#70pR$1IM4Z_Y3DM-%&r$~ e&aSa5?-hr+T;aCdiQ+2@iIQR9@!RW0j(z}8D|1f( literal 0 HcmV?d00001 diff --git a/images/loader-red.gif b/images/loader-red.gif new file mode 100644 index 0000000000000000000000000000000000000000..5b44ef767de5ab1fbf02f197621250bb27126e39 GIT binary patch literal 673 zcmZ?wbhEHb6krfw_{6~Q9|#y2{vA5>&&dhINJ{$G)bwxCB*lMH&PAz-C8;S2<(VZJ z3W-^X6*>8dDSDZCY55F_KUo;K7#J87|8x7fh6Fo12DlpO889;fg>--zXtV$W1G6#5 zt~>t>PI+bvCv#YFNX}vRn~}!py3z2^E|HlBx9KGuIaGK-H(J8-?lN{u2_AN@?B^ap zBf&;9BAa6ZGRLn+Q9-(eXZMC@T`q-AfguTok_rhvuF+B}YGk&S-hZ1Y!QP;7UE)!j zv*adK6)hpCK}^U7nQ`ngQr14@cw)ktDPj6-t;sTcUnKoLdO9V}SY06Vf$PlXy)wsE zXfs8=75~H7e3;*8Ws21N{VY(Un30VF`YlOS`;<}J#5Z%o;#<3yakeV*uo$|uC&~z} za%8(ma34L4aBArH%YyHLy8BlVHZMA{zsAj>4e{mg0{~p6|Ie&p`6H%mYO| zr)_gjg|As;$iv1hQk=MZgX#CFjEx2xI6HUG&(-vTnZt%`4$wJw{(aySyg4T{b{6Bi zTZIKv6FTlD&bezct<}-(sDa3YgxT8|d07rQ2+THYICSmYM3^z`7{&l&es!wTl{uQ% vXaI`8UVro0E7S`n;{>J9|dCt0Hpu`$N&S)11GpA@AdCBtu;Tj zKLcX}Z;`@4y+9#rPYTBhcGh;E>7NOf2>@mQCa@;o@!#9`+mz;%x!bvh=Y|!M70dI> zXWM6q=!wbU$#~>=*67xa%#E1Pm=LNEN4Q7e_~0nXC zkPnI8iNNu|!1KUB+CW0KLe%%vGjMyb?69%bu|T>&`u_UA@xOrMfP~|OK*vA{sR_96 zxV-7Sao2Ig41ejE#xo}r?nq@|{(sHv)} ztgWuEs1O|p6%_~_7O=XFXbDFP0zN(r3o0SGyUB$@FkcEKEYU0mL}3*o%E>}UNNF42 z;NMSXD%jbt5D!QVB_&o4bq;gw?N}Aa=d2-KOD+X!eggVo)4+wnB2Gdiir~i;5Duy= zs5o#!j1++a37pt?!j1}jg&4XLnX1DAC@HE498*LNffO)DXxXx$10s@#JW!Y*fzXQ# zekgeG6M>Kf3PKAJB}5YEDFh5Ye4rBWjZ~=z6cB+!f`kABHya+3;Ag@FKPdi?r4WI_ zQWRzX&-VPY^p8lg0U@5Ma3w&1fJ*!xD8Ph=z^*tdghgb6!XFKOGT8N_;SYzUKr2%) zL8z`s4st8+jnkqcr-Wd{3M&A> z#cF2+6vYZgC=?b(bLqrWAs}Sn!DX@?l@uWwFqDA_VgYfMUZ+@4feZi?IYJCEG*Jf7 z08_*Oh79+3vLJ(!<&%gAKkR_PmRxqZ!w=?g0--NW&kx@BMJu+ zNC3hMXD(tv2shZ!Ll8mqV8ac^`m}aV}rG0ej z>8GHED(a}DmTKy$sFJ$Js;su^>Z`EED(kGY)@rM)cjT(;uDtf@>#x8DE9|hu0*lA7 z$R?}ovdlK??6c5DE3LD7RBP?E*k-Hkw%m5>?YH1^%g4CnmTT_0=%%agy6m>=uDXE$ F06Q`d6m0+i literal 0 HcmV?d00001 diff --git a/images/machform.gif b/images/machform.gif new file mode 100644 index 0000000000000000000000000000000000000000..34641abf95ba7a9ac04367ec511429b9600045cc GIT binary patch literal 666 zcmZ?wbhEHbT+SfRaD;*3`}gnf-@kwM?Ae0{4}Sjq`TO_pSFc_@di3b;-@l(fe}3}h z$%_{+K7Rc8=FOY0U%&qU|Nq{-dkmxi#h)x-)qi41(a9XE`4?7{c&&|Ee`8JA>9UHm0?^1r9Lt?h;^X>nLhSW>jY3T$G$%-N|Fw^MLks)6~9^ XCzTpJp1(!MMFa7#|B{jj7iS+ zs)OcE7wva0yXIr7yn5EP*{VOLef_n4UPnn9PUrijtupi19zwyhTiw%xXx62*{0%^e9oU; z+x)s@)<)|c*&xJlp<&~l_ZeJ=qO%+17~<~K&rbN(5TF0}$=aoNqOCO)9I{k73KGQm dm^EI=H43pf_vNprC_VWC27t2AGqI%K3paIXLV|4VhV000000000000000 z000000000000000A^8LV00000EC2ui0C)f+000I5pdwymX`X1Ru59bR@G8!6ZQpp_ z(t7XzK$0RzEEm76k(qh8GEo76XTlVgm(eBm`%YaF`|p0u};p7h(qi0tOd} zivtLkoQ{wKszGXUbb$x~2aBX@0-*s{sJ-4kTn31py=h^6!|7hm74LAtq0~MXC%O6Y~dAKT#wE z=vyVg91$_i&JYk&1_1(iAnRQK;PDb7ksL4o1SsIq7=k`*>ZDv%Z|2FH*+>{$6YCtB zQ1VhXV;54}^riGU!Z05Wv)#y|J1S~PSh^CpFl&HED9h>b?%1Z_mVp3Kn znhAs#6b_hL!fHwbli>Mud#RUIXp6=LdKNR&osEs6dLl8c+BLd3;c-mB&p{|sdts6= z5UOD0dI`iR^OUv0%u|W5X+8l;6sf9YrxLg%U>KhhFBKNJ{U#SRsJy>0AV6SX@Z-pn z--f`vx%21Hqf4Joy}I@5*t1vI&b_<$@8H9WA5Xr#`Sa){s9(>%z5Dm@ht8}?*97K z-QDW*^ZD@4f%WXaB`c|HMoFzC7!tP3ogbQ*@)8oVM@s_ask>(9qvATa#je ztdXb1Lui{BdoaMw-q6|Rf||VG=I(Niw6Va|>+AHPv(5g$Kk@PS@9*~Y_58K9%kc2` z{=Y!@_3`fR^`xY|%8@jNT|x7%U!Z?#{k>1|>g4vdHvYRcrf)6S*ygZ!FtK$xmX@*S zp-<-B*6pn`^z{1ku}aLfjQzVf*S(Pc+lcPyY|p{k&1@q)Y6kPW`<+e^WL7y*v~`g8%>jA^8LV00000EC2ui z0E_@5000O7fPR91goTEOh>41ejE#;B;IQ>2iN9i?=Qq~zyEzX@?-oH!vfh|QZerBI-dfCGn+ zBaIaLF-WB!97u5_>E|Vlg{KyRK*fjvfd~-|rX&C=sN~6_LPqW|qJxkhAU^z%{Zk~Z zA0K7^*^cx9B;}tUDB&I&iRecUKRsNE^h0Dvk0F1~ru8ADu3oloeIUN{AjJU_CW2tb ze2~nNYZ)kL*otVSP@-UW5J@XoP>;Vv*s3=2mQY$Ce^VwoO62HXyM&JT*?|M)k-EC~cp!{11u@2vfcj$PJgHXvo zKz0z?A^&~Kv}MtDA0ZkEQ%2UyHj@a^#qQ9D$N2@YQ7&OMduRNRfkeLL_iQ z8cASEI{ZMFS{Dl7rvMD3@Btkk@DPHPpCO?oSAXp0l8zPDDXDKGmDOThLnxRMZYKS9 z2!eko=tG=_%y=guL&OE2C0zIk1p`nhK?eXNXk+WGrO|mQVQG?ex=7M=kZ#R99{F)mUfENgx0_c|n%A literal 0 HcmV?d00001 diff --git a/images/reports.gif b/images/reports.gif new file mode 100644 index 0000000000000000000000000000000000000000..4faec836df1a943257aa54e5f74acf1538a8bbe5 GIT binary patch literal 518 zcmZ?wbhEHb3}8@ZIKsei{?_Z~Z@+&2_A9(@$L+@-=5M`r_~J7Wr>6Xghqj-1xO)Gc z_QhwaXB|&&-#dBDMca(!p2Zu@5*Iqia%MvGCCj< zWG4gb{|Ab3DVg&!R;|lf-L*mcd`a)IvUTsD9{hh`L4k*kRR4)3MJIEt=3iJ*;~kzJN~^ZH{x&dQ!w zDQjn_mhNEQmAOZJ-Sd?aA>lcZWMdt%FD^7!g*Xg3Jq<_#^G!y z6@*LDC#u>Me`@}?G2l%SCtHzPk;sP&UDmTbwH}%*DqenmzJtGmgx8i87Z-a>)`~r~ z<>dvgfW=;Oy|%8px;kQWR;$*+)z{Z29PX0!-nQoE=2-a^v8T7Ky}iBQ@u|7q;kvE6 zD?Y!vdwTo&`}-T1@Ao?F*zoXhhp=|snH?LG4+$%I&-2;2>FMbi#@Y8|ELj+=0aIAq A!~g&Q literal 0 HcmV?d00001 diff --git a/images/reports_active.gif b/images/reports_active.gif new file mode 100644 index 0000000000000000000000000000000000000000..c0d56a47f63ca113ea8311886e1ff32e58371005 GIT binary patch literal 368 zcmV-$0gwJiNk%w1VNd`g0J8u9Q*@&jA^8LV00000EC2ui08juU000F4(8))uy*TU5yOy9Qj%102 zW~#20!@h7V&vb3yc&_h!@BhG{a7Zlj0HA?F$2b6y06@U8#5n*@*MkrkR0;!!fk1Hx zkYh?=8YobZib246r4SHdK>~-Y1OgNdR|<6x5&~0h2@V4QVS7je0s;g`69`lV0!}wj zQdATM4rG`MhNBC0qD}{54@jnDf^Dx3raG1q1{IPF444dtSi-d}SbY|S1t12THhqG_ zryvf&g>}fp*=5oV2xxp-Q=EtuWTynFSgQ}MyW7NDKf(U9?1po+ShlvjsHF{Lc zLYD#r1YA+Ls}sE`x8j)DW9W>Sb88&XDp-L*n1Bi$2lO*yjAV{NCT*Zh$+D%(moQ_> OoJq5$&6_wQ002AZnU!n+ literal 0 HcmV?d00001 diff --git a/images/settings.gif b/images/settings.gif new file mode 100644 index 0000000000000000000000000000000000000000..3c33675fe96d2a9b6d3da969721ebc7ad417ac76 GIT binary patch literal 549 zcmZ?wbhEHb3}8@ZIKsd%f9tjIx*eat{i>dI{Q29jB2G=WAAdM}@mc=FL)%Y0oV@1Z z>iu`x7oSOP-+TVnYuk+Fp2Zu@5*Iqia%MvGCCj< zWG4gb{{+Rjl+1YfP~f2>)qi41(a9XE`4?7{c&#;K zWZ_N}j8J4-%D5<{Fd~>?t@7yzOPv&B&IJ~WSz6w)+K5N+Rpl2ZCX0))v5RrWGIla? zr;0Oj*0JTfGBNS0bEQs5%M=r1&R?W5u`Mc+TRfAAuP%*KjGKY2)n$U%dIpuw*v-7m zkqo?ZS@yOS?Pg@0m_M8Oyx43{hU`Uqnb??_HzzbLFFN(;>BA=r>vyN#*2hS`;~aSBDFRyxTMMwd4T7`;tMLAtn6YQ#)lIYHT0F0T*+Lj zu~J~lB94$^t`r6atEv@QcfDAeuCGrx+$HP1ZOzTi8GFMbPH$U#dwap-Q**tyzl-9m z`26bb>Fw+9?{8q{KK6UThKGkcgtg<&?AZADc&nzzJfEGLo}QjzoPF<1WKqlc1jA^8LV00000EC2ui08juU000F4(8))uy*TU5yOy9Qj%102 zW~#20!@h7V&vb3yc&_h!@BhG{a7Zln00ajC5!f6CmBFFaFlGSCMsl%fxG0V)1(2{} z1cc@TIuOJufK^x$16~t$ViE*N2oG2S z4Q^Em4hR4Rbu@quo&XeiO`;3~NdOFu1gw@|0s#SmUW)_14vRSeS`w@R1p@=3P;y{m zxzoaPk#DCr2Z10U&tKEjmsQZcVhIXf1~vz3<_`q~6>;E!(f7G|tXNe6bp_yL1OWBP z0T+J8_B_agU=aZUxa>)+(x_X5000{RTvuZOB|{ZD5EMFeAPJNKZtzW{kiYg6d7|o7KHs303i%7U>8^K@d^x}d+zhvvdP(WmEn=& z(mqQc1p)fCeZI<@+g}Z}FNWIl!y`)wqO}ZeSylINhRH>k-|f?_^L32PK>0_Wx+ibm znj)m~!@|>!=!01%-jz*Gt4+r}lJ|pakX@k|^pQl!#q>u+q~G)t53x4SD|Txf;gm}v z2Fh_Xg_79OcF@A%jye%+!`%6m zX#Ig8q0|5@ExQtvFFnSx$=FojQ3EI~Q_}nzt(%+N)u{SwTiUD3MU@>2Bd~vf)a@`7 zeo{Yz(-20_wvxtdZxNs3?&>=SOQ!Ek^-gH#6?46_GjB-CM3eUrRdvp0CWjCVKdpNE zW9@}k)TuR$rs*tOlv(jcG&{@0mt$x3wdUN`z`6rodq3#{=`U$D@qRu##~4p#4tjh~ zNXW>l_8rb{P$ncbEi)^dmy>G_gOlN~JS#*5!a9%+ivfhlIF189297%GPLstVE2AB2 z08}YW5mDZFrdTEyiNgv-76pR#&ZQ3fEsE^*C#hwOd-yuiD7%U{cK88NjURs2I>4LO z8Hl?1P9u@HOf+3d9D29Ke<${Dbr1}r#C@{dTyhkPWl`8l-VB>`6YBcs;mLUSfQ8Dl zd#+6^{L)byT5XN6iKBs8>8R*nhZHIRL9^)j6oIEu1fY5JJSxA~-v`QqCRsr9AmtUx zx_TAK7(*RGgurw0Fe%Uy=uJ>d;n)jyx5#%S{R7xbc3M&Iy)wd0X(#7;ew$CbRb$fx zZA95OH>7;|{n)kF8<&N^O5xy#5K?#WXF?taf0}O1^2tPJ({hmK=>_OinlMQ$SvrWj z!4NV89OF*{v&ygnyxb6g#}T5EqGC2Q0zqs-Eww&KVQmzn3^C9Vjfmb_NIwmx0d$;h z4Ls=~d15l@apO4Wf#wlsP&p*&>UoJ<_JLRW-WfCzwg11t_xM1@KQBa3$p|q_K`C|d z$6c-h;4W;8iW1_9Z6<4uVC$0q20}hG5XVpydVI5S36N$E<5E&-amZvI0MBD11r!wKF7_-%;Kl0)J@GTf0WwH6cU*wAi2fNLsYlzW^YUB{0S j$FRes3A~;-)t58f{Z#v;XYR#_&HyB=1Gz2TfyVVa>?|a^ literal 0 HcmV?d00001 diff --git a/images/simple_modal/cancel.png b/images/simple_modal/cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..41dea1eb96798395d764b12266c700eb9a6d68ca GIT binary patch literal 3224 zcmV;J3}^F+P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0005QNkl9|P16KfvDiSq; zh68{^hrgwW9ee#JB(j@`WGyQmucDcKJ3F2kd%4^O7yyUBH87-W7~u2Y%ByfPd^_{e zVncP(x+kmS33vlefw7ac2AlvFy#VTl5U#ln!^cI@u%*5Qz8}a=e%}LMPSOc*1+33{ zcPtHtn)6K-@25}7r&?{f1rD90qdzac)tFM47-dO4qiJTRXB<08doc|uIQhQ)NB|;? z83Bv~Cy8YnHn0H7azeB^g0O{|o>GB@3KHkyCvD0000< KMNUMnLSTZmF!Nae literal 0 HcmV?d00001 diff --git a/images/simple_modal/form_bottom.gif b/images/simple_modal/form_bottom.gif new file mode 100644 index 0000000000000000000000000000000000000000..beae743f83a28de49ee3aba37ef0359fbbbceefe GIT binary patch literal 140 zcmV;70CWFGNk%w1VWa^K0Du7i6heak|NkNR1OWg50RSuj0001_0Sy2E0%L@asmtvT zqnxzbi?iOm`wxcVNS5Y_rs~SJ?hD8AOxN~}=lag~{tpZaheS-Eh)gP%%t+waj7q0e u+!I>OYPVd@726Gq$Ko%Tj83bG=I8nikK5W`x&4k8(dqfV|L?F@0029sazyU{ literal 0 HcmV?d00001 diff --git a/images/simple_modal/form_top.gif b/images/simple_modal/form_top.gif new file mode 100644 index 0000000000000000000000000000000000000000..605e2778c7f519fc2538c2185cebc3ee384c54e3 GIT binary patch literal 140 zcmV;70CWFGNk%w1VWa^K0Du7i6heak|NkNR1OWg50RSuj0001_0Sy2E0%MGCpv&zK zqnxzbi?iOm`wxcVC?cjwrs~SJ?hD8A?3@UV=lag~{*SQ%hs2`sh#aDl%%<}RjVf-^ us`ZM^dJfvI_Y0OL!sN2~91Eb=?6&(2kIU!uy8VvN>-YS={|~5A002AS)ki7- literal 0 HcmV?d00001 diff --git a/images/simple_modal/form_top_ie.gif b/images/simple_modal/form_top_ie.gif new file mode 100644 index 0000000000000000000000000000000000000000..f2a1cb1c4bb7a5f993edd406d7b36975cc576b6e GIT binary patch literal 996 zcmZ?wbhEHbT*4^D@SOn!jE#-K^e8bJ0wXR26o0ZXGBEsS&;j`zlqVQC4l?}bl+iF~ zIM~b~tQB)&!@|Su0?J-QIJ-nRH!V3iStEE=%*jnlPfzD^ z7i#g`yzK03i{e*zJOkCv&v$6%lJ)wcesYn=WUbg!TUH*N>9^QxuGiL8#~Q;nXWcz@ zHS^%Qgu`93w?E0>+?;WFRqW|)Yj1BaczkNE_x5#ncUOFVb@%l4_4oHTFmucK?AY+| yaEGvV+?gF4A0MBf>^;wC=ccEpXBcPSJF|21^YaUwyXAa$ZFzZlMK>D@gEaur3~wR; literal 0 HcmV?d00001 diff --git a/images/simple_modal/send.png b/images/simple_modal/send.png new file mode 100644 index 0000000000000000000000000000000000000000..3f1b0ed7a6046e0d70870285ab9396fa8e19a5ed GIT binary patch literal 3200 zcmV-`41e>9P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z00052NklWO+S^Uw3TW0fgW|e1^3s=xBaJ!V0*ArOj%q{Hj8rzQ-vZeKI>F5L z76K@XR!#`VBVuJ7V{U0MvqtQFJj&_=s5m6*x#k>?gPE}|L+U4FvA76lO+oSqo(EZG zomm1%Zn**sGLX3GxMYxud4~bcI43846>g^vawekba=g=`cCTLeunaRb7tY{$mI!Szxi<3cC941Ttx*)4u ze*X-JtE~H7LlFIg)Nk3VuPpIecy}M1B`N`V1{x7EamvkDaavQ2HdCa)T`;q!C?Hd# zl)u@}k0gQhYFE$Y1Ly`bI|06d17IT>OzB#cJ0g7HpOv-nx)ij6S^DXyCHMk%qesW5 mZ9C2D-2v`_oBiw5eg*)z8`&XCB(yI80000Bs=>{4NRNq^clROok?zfl8%3cdJ^uM?Lo-0w`=dI+Q$H>5NJga{W z@8O1j(r0U9Z-zGl<^TCGWZ3hv{dIHRzwOv9ZdL|{1D_8$#3WxW5xalB=|J4)`%6o; zMSu#=^D=I{cX^icfpCc%vpJ4Dt6vd(<9UDr4^YGVmWCUD_)Dd$Kg)2LsWYjzHt4lB z*tIsU(@|#uN`G`*u=JUIdxHd<*Gzwoux5vSd?j3p59Tl(T&c618LU9z->rJ-*SahX znmj(|uWy*o+E{Z`-H+*<_EdG2%jFCV4arXh3|JdpN0^%a`^kUg`}yl?Oh2tIT=)@h z_c}F3Kh;jLBk@28(3O3cPZbFj$R0lM`o`@1)`peu>{uii(yJ1hRD8HV5y0T->gTe~ HDWM4fvM!>l literal 0 HcmV?d00001 diff --git a/includes/JSON.php b/includes/JSON.php new file mode 100644 index 0000000..0cddbdd --- /dev/null +++ b/includes/JSON.php @@ -0,0 +1,806 @@ + + * @author Matt Knapp + * @author Brett Stimmerman + * @copyright 2005 Michal Migurski + * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ + * @license http://www.opensource.org/licenses/bsd-license.php + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 + */ + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_SLICE', 1); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_STR', 2); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_ARR', 3); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_OBJ', 4); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_CMT', 5); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_LOOSE_TYPE', 16); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_SUPPRESS_ERRORS', 32); + +/** + * Converts to and from JSON format. + * + * Brief example of use: + * + * + * // create a new instance of Services_JSON + * $json = new Services_JSON(); + * + * // convert a complexe value to JSON notation, and send it to the browser + * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); + * $output = $json->encode($value); + * + * print($output); + * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] + * + * // accept incoming POST data, assumed to be in JSON notation + * $input = file_get_contents('php://input', 1000000); + * $value = $json->decode($input); + * + */ +class Services_JSON +{ + /** + * constructs a new JSON instance + * + * @param int $use object behavior flags; combine with boolean-OR + * + * possible values: + * - SERVICES_JSON_LOOSE_TYPE: loose typing. + * "{...}" syntax creates associative arrays + * instead of objects in decode(). + * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. + * Values which can't be encoded (e.g. resources) + * appear as NULL instead of throwing errors. + * By default, a deeply-nested resource will + * bubble up with an error, so all return values + * from encode() should be checked with isError() + */ + function Services_JSON($use = 0) + { + $this->use = $use; + } + + /** + * convert a string from one UTF-16 char to one UTF-8 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf16 UTF-16 character + * @return string UTF-8 character + * @access private + */ + function utf162utf8($utf16) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); + } + + $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); + + switch(true) { + case ((0x7F & $bytes) == $bytes): + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x7F & $bytes); + + case (0x07FF & $bytes) == $bytes: + // return a 2-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xC0 | (($bytes >> 6) & 0x1F)) + . chr(0x80 | ($bytes & 0x3F)); + + case (0xFFFF & $bytes) == $bytes: + // return a 3-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xE0 | (($bytes >> 12) & 0x0F)) + . chr(0x80 | (($bytes >> 6) & 0x3F)) + . chr(0x80 | ($bytes & 0x3F)); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * convert a string from one UTF-8 char to one UTF-16 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf8 UTF-8 character + * @return string UTF-16 character + * @access private + */ + function utf82utf16($utf8) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + } + + switch(strlen($utf8)) { + case 1: + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return $utf8; + + case 2: + // return a UTF-16 character from a 2-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x07 & (ord($utf8{0}) >> 2)) + . chr((0xC0 & (ord($utf8{0}) << 6)) + | (0x3F & ord($utf8{1}))); + + case 3: + // return a UTF-16 character from a 3-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr((0xF0 & (ord($utf8{0}) << 4)) + | (0x0F & (ord($utf8{1}) >> 2))) + . chr((0xC0 & (ord($utf8{1}) << 6)) + | (0x7F & ord($utf8{2}))); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * encodes an arbitrary variable into JSON format + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + function encode($var) + { + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + + case 'NULL': + return 'null'; + + case 'integer': + return (int) $var; + + case 'double': + case 'float': + return (float) $var; + + case 'string': + // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT + $ascii = ''; + $strlen_var = strlen($var); + + /* + * Iterate over every character in the string, + * escaping with a slash or encoding to UTF-8 where necessary + */ + for ($c = 0; $c < $strlen_var; ++$c) { + + $ord_var_c = ord($var{$c}); + + switch (true) { + case $ord_var_c == 0x08: + $ascii .= '\b'; + break; + case $ord_var_c == 0x09: + $ascii .= '\t'; + break; + case $ord_var_c == 0x0A: + $ascii .= '\n'; + break; + case $ord_var_c == 0x0C: + $ascii .= '\f'; + break; + case $ord_var_c == 0x0D: + $ascii .= '\r'; + break; + + case $ord_var_c == 0x22: + case $ord_var_c == 0x2F: + case $ord_var_c == 0x5C: + // double quote, slash, slosh + $ascii .= '\\'.$var{$c}; + break; + + case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): + // characters U-00000000 - U-0000007F (same as ASCII) + $ascii .= $var{$c}; + break; + + case (($ord_var_c & 0xE0) == 0xC0): + // characters U-00000080 - U-000007FF, mask 110XXXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, ord($var{$c + 1})); + $c += 1; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF0) == 0xE0): + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2})); + $c += 2; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF8) == 0xF0): + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3})); + $c += 3; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFC) == 0xF8): + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4})); + $c += 4; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFE) == 0xFC): + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4}), + ord($var{$c + 5})); + $c += 5; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + } + } + + return '"'.$ascii.'"'; + + case 'array': + /* + * As per JSON spec if any array key is not an integer + * we must treat the the whole array as an object. We + * also try to catch a sparsely populated associative + * array with numeric keys here because some JS engines + * will create an array with empty indexes up to + * max_index which can cause memory issues and because + * the keys, which may be relevant, will be remapped + * otherwise. + * + * As per the ECMA and JSON specification an object may + * have any string as a property. Unfortunately due to + * a hole in the ECMA specification if the key is a + * ECMA reserved word or starts with a digit the + * parameter is only accessible using ECMAScript's + * bracket notation. + */ + + // treat as a JSON object + if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + $properties = array_map(array($this, 'name_value'), + array_keys($var), + array_values($var)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + } + + // treat it like a regular array + $elements = array_map(array($this, 'encode'), $var); + + foreach($elements as $element) { + if(Services_JSON::isError($element)) { + return $element; + } + } + + return '[' . join(',', $elements) . ']'; + + case 'object': + $vars = get_object_vars($var); + + $properties = array_map(array($this, 'name_value'), + array_keys($vars), + array_values($vars)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + + default: + return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) + ? 'null' + : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); + } + } + + /** + * array-walking function for use in generating JSON-formatted name-value pairs + * + * @param string $name name of key to use + * @param mixed $value reference to an array element to be encoded + * + * @return string JSON-formatted name-value pair, like '"name":value' + * @access private + */ + function name_value($name, $value) + { + $encoded_value = $this->encode($value); + + if(Services_JSON::isError($encoded_value)) { + return $encoded_value; + } + + return $this->encode(strval($name)) . ':' . $encoded_value; + } + + /** + * reduce a string by removing leading and trailing comments and whitespace + * + * @param $str string string value to strip of comments and whitespace + * + * @return string string value stripped of comments and whitespace + * @access private + */ + function reduce_string($str) + { + $str = preg_replace(array( + + // eliminate single line comments in '// ...' form + '#^\s*//(.+)$#m', + + // eliminate multi-line comments in '/* ... */' form, at start of string + '#^\s*/\*(.+)\*/#Us', + + // eliminate multi-line comments in '/* ... */' form, at end of string + '#/\*(.+)\*/\s*$#Us' + + ), '', $str); + + // eliminate extraneous space + return trim($str); + } + + /** + * decodes a JSON string into appropriate variable + * + * @param string $str JSON-formatted string + * + * @return mixed number, boolean, string, array, or object + * corresponding to given JSON input string. + * See argument 1 to Services_JSON() above for object-output behavior. + * Note that decode() always returns strings + * in ASCII or UTF-8 format! + * @access public + */ + function decode($str) + { + $str = $this->reduce_string($str); + + switch (strtolower($str)) { + case 'true': + return true; + + case 'false': + return false; + + case 'null': + return null; + + default: + $m = array(); + + if (is_numeric($str)) { + // Lookie-loo, it's a number + + // This would work on its own, but I'm trying to be + // good about returning integers where appropriate: + // return (float)$str; + + // Return float or int, as appropriate + return ((float)$str == (integer)$str) + ? (integer)$str + : (float)$str; + + } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { + // STRINGS RETURNED IN UTF-8 FORMAT + $delim = substr($str, 0, 1); + $chrs = substr($str, 1, -1); + $utf8 = ''; + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c < $strlen_chrs; ++$c) { + + $substr_chrs_c_2 = substr($chrs, $c, 2); + $ord_chrs_c = ord($chrs{$c}); + + switch (true) { + case $substr_chrs_c_2 == '\b': + $utf8 .= chr(0x08); + ++$c; + break; + case $substr_chrs_c_2 == '\t': + $utf8 .= chr(0x09); + ++$c; + break; + case $substr_chrs_c_2 == '\n': + $utf8 .= chr(0x0A); + ++$c; + break; + case $substr_chrs_c_2 == '\f': + $utf8 .= chr(0x0C); + ++$c; + break; + case $substr_chrs_c_2 == '\r': + $utf8 .= chr(0x0D); + ++$c; + break; + + case $substr_chrs_c_2 == '\\"': + case $substr_chrs_c_2 == '\\\'': + case $substr_chrs_c_2 == '\\\\': + case $substr_chrs_c_2 == '\\/': + if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || + ($delim == "'" && $substr_chrs_c_2 != '\\"')) { + $utf8 .= $chrs{++$c}; + } + break; + + case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): + // single, escaped unicode character + $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) + . chr(hexdec(substr($chrs, ($c + 4), 2))); + $utf8 .= $this->utf162utf8($utf16); + $c += 5; + break; + + case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): + $utf8 .= $chrs{$c}; + break; + + case ($ord_chrs_c & 0xE0) == 0xC0: + // characters U-00000080 - U-000007FF, mask 110XXXXX + //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 2); + ++$c; + break; + + case ($ord_chrs_c & 0xF0) == 0xE0: + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 3); + $c += 2; + break; + + case ($ord_chrs_c & 0xF8) == 0xF0: + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 4); + $c += 3; + break; + + case ($ord_chrs_c & 0xFC) == 0xF8: + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 5); + $c += 4; + break; + + case ($ord_chrs_c & 0xFE) == 0xFC: + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 6); + $c += 5; + break; + + } + + } + + return $utf8; + + } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { + // array, or object notation + + if ($str{0} == '[') { + $stk = array(SERVICES_JSON_IN_ARR); + $arr = array(); + } else { + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = array(); + } else { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = new stdClass(); + } + } + + array_push($stk, array('what' => SERVICES_JSON_SLICE, + 'where' => 0, + 'delim' => false)); + + $chrs = substr($str, 1, -1); + $chrs = $this->reduce_string($chrs); + + if ($chrs == '') { + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } else { + return $obj; + + } + } + + //print("\nparsing {$chrs}\n"); + + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c <= $strlen_chrs; ++$c) { + + $top = end($stk); + $substr_chrs_c_2 = substr($chrs, $c, 2); + + if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { + // found a comma that is not inside a string, array, etc., + // OR we've reached the end of the character list + $slice = substr($chrs, $top['where'], ($c - $top['where'])); + array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); + //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + // we are in an array, so just push an element onto the stack + array_push($arr, $this->decode($slice)); + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + // we are in an object, so figure + // out the property name and set an + // element in an associative array, + // for now + $parts = array(); + + if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // "name":value pair + $key = $this->decode($parts[1]); + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // name:value pair, where name is unquoted + $key = $parts[1]; + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } + + } + + } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { + // found a quote, and we are not inside a string + array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); + //print("Found start of string at {$c}\n"); + + } elseif (($chrs{$c} == $top['delim']) && + ($top['what'] == SERVICES_JSON_IN_STR) && + ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { + // found a quote, we're in a string, and it's not escaped + // we know that it's not escaped becase there is _not_ an + // odd number of backslashes at the end of the string so far + array_pop($stk); + //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '[') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-bracket, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); + //print("Found start of array at {$c}\n"); + + } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { + // found a right-bracket, and we're in an array + array_pop($stk); + //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '{') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-brace, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); + //print("Found start of object at {$c}\n"); + + } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { + // found a right-brace, and we're in an object + array_pop($stk); + //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($substr_chrs_c_2 == '/*') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a comment start, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); + $c++; + //print("Found start of comment at {$c}\n"); + + } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { + // found a comment end, and we're in one now + array_pop($stk); + $c++; + + for ($i = $top['where']; $i <= $c; ++$i) + $chrs = substr_replace($chrs, ' ', $i, 1); + + //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } + + } + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + return $obj; + + } + + } + } + } + + /** + * @todo Ultimately, this should just call PEAR::isError() + */ + function isError($data, $code = null) + { + if (class_exists('pear')) { + return PEAR::isError($data, $code); + } elseif (is_object($data) && (get_class($data) == 'services_json_error' || + is_subclass_of($data, 'services_json_error'))) { + return true; + } + + return false; + } +} + +if (class_exists('PEAR_Error')) { + + class Services_JSON_Error extends PEAR_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + parent::PEAR_Error($message, $code, $mode, $options, $userinfo); + } + } + +} else { + + /** + * @todo Ultimately, this class shall be descended from PEAR_Error + */ + class Services_JSON_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + + } + } + +} + +?> diff --git a/includes/check-session.php b/includes/check-session.php new file mode 100644 index 0000000..c54afc1 --- /dev/null +++ b/includes/check-session.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/includes/common-validator.php b/includes/common-validator.php new file mode 100644 index 0000000..0d3af64 --- /dev/null +++ b/includes/common-validator.php @@ -0,0 +1,420 @@ + 3)){ + return true; + }else{ + return $error_message; + } + } + + //validation for minimum value + function validate_min($value){ + $error_message = VAL_MIN; + + if(strlen($value[0]) < $value[1]){ + return sprintf($error_message,$value[1]); + }else{ + return true; + } + } + + //validation for maximum value + function validate_max($value){ + + $error_message = VAL_MAX; + + if(strlen($value[0]) > $value[1]){ + return sprintf($error_message,$value[1]); + }else{ + return true; + } + } + + //validation for range value + function validate_range($value){ + $error_message = VAL_RANGE; + + //$value[0] is the entered value to be compared + //$value[1] contains the value range. eg '2-10' + + $exp_array = explode('-',$value[1]); + $min = $exp_array[0]; + $max = $exp_array[1]; + + + if(!((strlen($value[0]) >= $min) && (strlen($value[0]) <= $max))){ + return sprintf($error_message,'%s',$min,$max); + }else{ + return true; + } + } + + //validation to check email address format + function validate_email($value) { + $error_message = VAL_EMAIL; + + if(!empty($value[0])){ + $regex = '/^[A-z0-9][\w.-]*@[A-z0-9][\w\-\.]*\.[A-z0-9]{2,6}$/'; + $result = preg_match($regex, $value[0]); + + if(empty($result)){ + return sprintf($error_message,'%s',$value[0]); + }else{ + return true; + } + }else{ + return true; + } + } + + //validation to check URL format + function validate_website($value) { + $error_message = VAL_WEBSITE; + $value[0] = $value[0].'/'; + + if(!empty($value[0]) && ($value[0] != '/')){ + $regex = '/^https?:\/\/([a-z0-9]([-a-z0-9]*[a-z0-9])?\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])(\/)(.*)$/i'; + $result = preg_match($regex, $value[0]); + + if(empty($result)){ + return sprintf($error_message,'%s',$value[0]); + }else{ + return true; + } + }else{ + return true; + } + } + + //validation to allow only a-z 0-9 and underscores + function validate_username($value){ + + $error_message = VAL_USERNAME; + + if(!preg_match("/^[a-z0-9][\w]*$/i",$value[0])){ + return sprintf($error_message,'%s',$value[0]); + }else{ + return true; + } + } + + + + //validation to check two variable equality. usefull for checking password + function validate_equal($value){ + $error_message = VAL_EQUAL; + + if($value[0] != $value[2][$value[1]]){ + return $error_message; + }else{ + return true; + } + } + + //validate date format + //currently only support this format: mm/dd/yyyy or mm-dd-yyyy, yyyy/mm/dd or yyyy-mm-dd + function validate_date($value) { + $error_message = VAL_DATE; + + if(!empty($value[0])){ + if($value[1] == 'yyyy/mm/dd'){ + $regex = "/^([1-9][0-9])\d\d[-\/](0?[1-9]|1[012])[-\/](0?[1-9]|[12][0-9]|3[01])$/"; + }elseif($value[1] == 'mm/dd/yyyy'){ + $regex = "/^(0[1-9]|1[012])[-\/](0[1-9]|[12][0-9]|3[01])[-\/](19|20)\d\d$/"; + } + + $result = preg_match($regex, $value[0]); + } + + + if(empty($result)){ + return sprintf($error_message,'%s',$value[1]); + }else{ + return true; + } + } + + //validation to check valid time format + function validate_time($value){ + + $error_message = VAL_TIME; + + $timestamp = strtotime($value[0]); + + if($timestamp == -1 || $timestamp === false){ + return $error_message; + }else{ + return true; + } + } + + + //validation for required file + function validate_required_file($value){ + $error_message = VAL_REQUIRED_FILE; + $element_file = $value[0]; + + if($_FILES[$element_file]['size'] > 0){ + return true; + }else{ + return $error_message; + } + } + + //validation for file upload filetype + function validate_filetype($value){ + + $error_message = VAL_FILETYPE; + $value = $value[0]; + + $ext = pathinfo(strtolower($_FILES[$value]['name']), PATHINFO_EXTENSION); + + if(defined('UPLOAD_FILETYPE_ALLOW') && (UPLOAD_FILETYPE_ALLOW != '')){ + //only allow these filetypes + $allowed_filetypes = explode(';',strtolower(UPLOAD_FILETYPE_ALLOW)); + if(!in_array($ext,$allowed_filetypes)){ + return $error_message; + } + + }elseif(defined('UPLOAD_FILETYPE_DENY') && (UPLOAD_FILETYPE_DENY != '')){ + //disallow these filetypes + $blacklisted_filetypes = explode(';',strtolower(UPLOAD_FILETYPE_DENY)); + if(in_array($ext,$blacklisted_filetypes)){ + return $error_message; + } + } + + return true; + } + + /********************************************************* + * This is main validation function + * This function will call sub function, called validate_xx + * Each sub function is specific for one rule + * + * Syntax: $rules[field_name][validation_type] = value + * validation_type: required,integer,float,min,max,range,email,username,equal,date + * Example rules: + * + * $rules['author_id']['required'] = true; //author_id is required + * $rules['author_id']['integer'] = true; //author_id must be an integer + * $rules['author_id']['range'] = '2-10'; //author_id length must be between 2 - 10 characters + * + **********************************************************/ + function validate_rules($input,$rules){ + + //traverse for each input, check for rules to be applied + foreach ($input as $key=>$value){ + $current_rules = @$rules[$key]; + $error_message = array(); + + if(!empty($current_rules)){ + //an input can be validated by many rules, check that here + foreach ($current_rules as $key2=>$value2){ + $argument_array = array($value,$value2,$input); + $result = call_user_func('validate_'.$key2,$argument_array); + + if($result !== true){ //if we got error message, break the loop + $error_message = $result; + break; + } + } + } + if(count($error_message) > 0){ + $total_error_message[$key] = $error_message; + } + } + + if(@is_array($total_error_message)){ + return $total_error_message; + }else{ + return true; + } + } + + //similar as function above, but this is specific for validating form inputs, with only one error message per input + function validate_element($input,$rules){ + + //traverse for each input, check for rules to be applied + foreach ($input as $key=>$value){ + $current_rules = @$rules[$key]; + $error_message = array(); + + if(!empty($current_rules)){ + //an input can be validated by many rules, check that here + foreach ($current_rules as $key2=>$value2){ + $argument_array = array($value,$value2,$input); + $result = call_user_func('validate_'.$key2,$argument_array); + + if($result !== true){ //if we got error message, break the loop + $error_message = $result; + break; + } + } + } + if(count($error_message) > 0){ + $last_error_message = $error_message; + break; + } + } + + if(!empty($last_error_message)){ + return $last_error_message; + }else{ + return true; + } + } +?> \ No newline at end of file diff --git a/includes/db-core.php b/includes/db-core.php new file mode 100644 index 0000000..507d1a6 --- /dev/null +++ b/includes/db-core.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/includes/db-functions.php b/includes/db-functions.php new file mode 100644 index 0000000..0b87e7c --- /dev/null +++ b/includes/db-functions.php @@ -0,0 +1,237 @@ +$value){ + $value = mysql_real_escape_string($value); + $field_list .= "`$key`,"; + $field_values .= "'$value',"; + } + + $field_list = substr($field_list,0,-1); + $field_values = substr($field_values,0,-1); + + $query = "INSERT INTO `ap_forms` ($field_list) VALUES ($field_values);"; + $result = mysql_query($query); + if(!$result){ + $error_message = 'Query failed! Error code: '.mysql_errno().' - '.mysql_error().' - Query: '.$query; + return $error_message; + } + + return true; + } + + function ap_forms_update($id,$data){ + + /** start validation **/ + //1.common validation + $rules['form_name']['max'] = 50; + + + $error_message = validate_rules($data,$rules); + if(is_array($error_message)){ + return $error_message; + } + + /** end validation **/ + + $update_values = ''; + + //dynamically create the sql update string, based on the input given + foreach ($data as $key=>$value){ + $value = mysql_real_escape_string($value); + $update_values .= "`$key`='$value',"; + } + $update_values = substr($update_values,0,-1); + + $query = "UPDATE `ap_forms` set + $update_values + where + form_id='$id';"; + + $result = mysql_query($query); + if(!$result){ + $error_message = 'Query failed! Error code: '.mysql_errno().' - '.mysql_error().' - Query: '.$query; + return $error_message; + } + + return true; + } + + /** ap_form_elements table ************************************/ + function ap_form_elements_insert($data){ + + /** start validation **/ + //1.common validation + $rules['form_id']['required'] = true; + $rules['element_id']['required'] = true; + + $error_message = validate_rules($data,$rules); + if(is_array($error_message)){ + return $error_message; + } + + /** end validation **/ + + $field_list = ''; + $field_values = ''; + + //dynamically create the field list and field values, based on the input given + foreach ($data as $key=>$value){ + $value = mysql_real_escape_string($value); + $field_list .= "`$key`,"; + $field_values .= "'$value',"; + } + + $field_list = substr($field_list,0,-1); + $field_values = substr($field_values,0,-1); + + $query = "INSERT INTO `ap_form_elements` ($field_list) VALUES ($field_values);"; + $result = mysql_query($query); + if(!$result){ + $error_message = 'Query failed! Error code: '.mysql_errno().' - '.mysql_error().' - Query: '.$query; + return $error_message; + } + + return true; + } + + function ap_form_elements_update($form_id,$element_id,$data){ + + /** start validation **/ + //1.common validation + $rules['form_id']['required'] = true; + $rules['element_id']['required'] = true; + + + $error_message = validate_rules($data,$rules); + if(is_array($error_message)){ + return $error_message; + } + + /** end validation **/ + + $update_values = ''; + + //dynamically create the sql update string, based on the input given + foreach ($data as $key=>$value){ + $value = mysql_real_escape_string($value); + $update_values .= "`$key`='$value',"; + } + $update_values = substr($update_values,0,-1); + + $query = "UPDATE `ap_form_elements` set + $update_values + where + form_id='$form_id' and element_id='$element_id';"; + + $result = mysql_query($query); + if(!$result){ + $error_message = 'Query failed! Error code: '.mysql_errno().' - '.mysql_error().' - Query: '.$query; + return $error_message; + } + + return true; + } + + /** ap_element_options table ************************************/ + function ap_element_options_insert($data){ + + /** start validation **/ + //1.common validation + $rules['form_id']['required'] = true; + $rules['element_id']['required'] = true; + $rules['option_id']['required'] = true; + + $error_message = validate_rules($data,$rules); + if(is_array($error_message)){ + return $error_message; + } + + /** end validation **/ + + $field_list = ''; + $field_values = ''; + + //dynamically create the field list and field values, based on the input given + foreach ($data as $key=>$value){ + $value = mysql_real_escape_string($value); + $field_list .= "`$key`,"; + $field_values .= "'$value',"; + } + + $field_list = substr($field_list,0,-1); + $field_values = substr($field_values,0,-1); + + $query = "INSERT INTO `ap_element_options` ($field_list) VALUES ($field_values);"; + + $result = mysql_query($query); + if(!$result){ + $error_message = 'Query failed! Error code: '.mysql_errno().' - '.mysql_error().' - Query: '.$query; + return $error_message; + } + + return true; + } + + function ap_element_options_update($form_id,$element_id,$option_id,$data){ + + /** start validation **/ + //1.common validation + $rules['form_id']['required'] = true; + $rules['element_id']['required'] = true; + $rules['option_id']['required'] = true; + + $error_message = validate_rules($data,$rules); + if(is_array($error_message)){ + return $error_message; + } + + /** end validation **/ + + $update_values = ''; + + //dynamically create the sql update string, based on the input given + foreach ($data as $key=>$value){ + $value = mysql_real_escape_string($value); + $update_values .= "`$key`='$value',"; + } + $update_values = substr($update_values,0,-1); + + $query = "UPDATE `ap_element_options` set + $update_values + where + form_id='$form_id' and element_id='$element_id' and option_id='$option_id';"; + + $result = mysql_query($query); + if(!$result){ + $error_message = 'Query failed! Error code: '.mysql_errno().' - '.mysql_error().' - Query: '.$query; + return $error_message; + } + + return true; + } +?> \ No newline at end of file diff --git a/includes/entry-functions.php b/includes/entry-functions.php new file mode 100644 index 0000000..15f44ab --- /dev/null +++ b/includes/entry-functions.php @@ -0,0 +1,487 @@ +name; + $i++; + } + + $row = do_fetch_result($result); + //store the result into array + for($i=0;$i<$fields_num;$i++){ + $column_name = $columns[$i]; + $entry_data[$column_name] = htmlspecialchars($row[$column_name],ENT_QUOTES); + } + + + //get form element options + $query = "select element_id,option_id,`option` from ap_element_options where form_id='$form_id' and live=1"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $option_id = $row['option_id']; + + $element_option_lookup[$element_id][$option_id] = true; //array index will hold option_id + } + + + //loop through each element to get the values + foreach ($form_elements as $element){ + $element_type = $element['element_type']; + $element_id = $element['element_id']; + $element_constraint = $element['element_constraint']; + + if('simple_name' == $element_type){ //Simple Name - 2 elements + $form_values['element_'.$element_id.'_1']['default_value'] = $entry_data['element_'.$element_id.'_1']; + $form_values['element_'.$element_id.'_2']['default_value'] = $entry_data['element_'.$element_id.'_2']; + }elseif ('name' == $element_type){ //Extended Name - 4 elements + $form_values['element_'.$element_id.'_1']['default_value'] = $entry_data['element_'.$element_id.'_1']; + $form_values['element_'.$element_id.'_2']['default_value'] = $entry_data['element_'.$element_id.'_2']; + $form_values['element_'.$element_id.'_3']['default_value'] = $entry_data['element_'.$element_id.'_3']; + $form_values['element_'.$element_id.'_4']['default_value'] = $entry_data['element_'.$element_id.'_4']; + }elseif ('time' == $element_type){ //Time - 4 elements + //convert into time and split into 4 elements + if(!empty($entry_data['element_'.$element_id]) && ($entry_data['element_'.$element_id] != '00:00:00')){ + $time_value = $entry_data['element_'.$element_id]; + $time_value = date("h/i/s/A",strtotime($time_value)); + + $exploded = array(); + $exploded = explode('/',$time_value); + + $form_values['element_'.$element_id.'_1']['default_value'] = $exploded[0]; + $form_values['element_'.$element_id.'_2']['default_value'] = $exploded[1]; + $form_values['element_'.$element_id.'_3']['default_value'] = $exploded[2]; + $form_values['element_'.$element_id.'_4']['default_value'] = $exploded[3]; + } + }elseif ('address' == $element_type){ //Address - 6 elements + $form_values['element_'.$element_id.'_1']['default_value'] = $entry_data['element_'.$element_id.'_1']; + $form_values['element_'.$element_id.'_2']['default_value'] = $entry_data['element_'.$element_id.'_2']; + $form_values['element_'.$element_id.'_3']['default_value'] = $entry_data['element_'.$element_id.'_3']; + $form_values['element_'.$element_id.'_4']['default_value'] = $entry_data['element_'.$element_id.'_4']; + $form_values['element_'.$element_id.'_5']['default_value'] = $entry_data['element_'.$element_id.'_5']; + $form_values['element_'.$element_id.'_6']['default_value'] = $entry_data['element_'.$element_id.'_6']; + }elseif ('money' == $element_type){ //Price + if($element_constraint == 'yen'){ //yen only has 1 element + $form_values['element_'.$element_id]['default_value'] = $entry_data['element_'.$element_id]; + }else{ //other has 2 fields + $exploded = array(); + $exploded = explode('.',$entry_data['element_'.$element_id]); + + $form_values['element_'.$element_id.'_1']['default_value'] = $exploded[0]; + $form_values['element_'.$element_id.'_2']['default_value'] = $exploded[1]; + } + + }elseif ('date' == $element_type){ //date with format MM/DD/YYYY + if(!empty($entry_data['element_'.$element_id]) && ($entry_data['element_'.$element_id] != '0000-00-00')){ + $date_value = $entry_data['element_'.$element_id]; + $date_value = date("m/d/Y",strtotime($date_value)); + + $exploded = array(); + $exploded = explode('/',$date_value); + + $form_values['element_'.$element_id.'_1']['default_value'] = $exploded[0]; + $form_values['element_'.$element_id.'_2']['default_value'] = $exploded[1]; + $form_values['element_'.$element_id.'_3']['default_value'] = $exploded[2]; + } + + }elseif ('europe_date' == $element_type){ //date with format DD/MM/YYYY + if(!empty($entry_data['element_'.$element_id]) && ($entry_data['element_'.$element_id] != '0000-00-00')){ + $date_value = $entry_data['element_'.$element_id]; + $date_value = date("d/m/Y",strtotime($date_value)); + + $exploded = array(); + $exploded = explode('/',$date_value); + + $form_values['element_'.$element_id.'_1']['default_value'] = $exploded[0]; + $form_values['element_'.$element_id.'_2']['default_value'] = $exploded[1]; + $form_values['element_'.$element_id.'_3']['default_value'] = $exploded[2]; + } + + }elseif ('phone' == $element_type){ //Phone - 3 elements + + $phone_value = $entry_data['element_'.$element_id]; + $phone_1 = substr($phone_value,0,3); + $phone_2 = substr($phone_value,3,3); + $phone_3 = substr($phone_value,-4); + + $form_values['element_'.$element_id.'_1']['default_value'] = $phone_1; + $form_values['element_'.$element_id.'_2']['default_value'] = $phone_2; + $form_values['element_'.$element_id.'_3']['default_value'] = $phone_3; + + }elseif ('checkbox' == $element_type){ //Checkbox - multiple elements + $checkbox_childs = $element_option_lookup[$element_id]; + + foreach ($checkbox_childs as $option_id=>$dumb){ + $form_values['element_'.$element_id.'_'.$option_id]['default_value'] = $entry_data['element_'.$element_id.'_'.$option_id]; + } + + }elseif ('file' == $element_type){ //File + + $filename_value = $entry_data['element_'.$element_id]; + + if(!empty($filename_value)){ + $file_1 = substr($filename_value,strpos($filename_value,'-')+1); + $filename_value = substr($file_1,strpos($file_1,'-')+1); + + //encode the long query string for more readibility + $q_string = base64_encode("form_id={$form_id}&id={$entry_id}&el=element_{$element_id}"); + + + //special for file,just provide a markup to download or delete the file + if($use_review_table == false){ + $form_values['element_'.$element_id]['default_value'] =<< {$filename_value}   + Download | + Delete +EOT; + }else{ //if using review table, only show attached filename and delete file + if(strpos($_SERVER['REQUEST_URI'],'?') === false){ + $href_url = $_SERVER['REQUEST_URI']."?delete_file={$element_id}"; + }else{ + $href_url = $_SERVER['REQUEST_URI']."&delete_file={$element_id}"; + } + + $form_values['element_'.$element_id]['default_value'] =<< {$filename_value}   + Delete +EOT; + } + } + }else{ //element with only 1 input + $form_values['element_'.$element_id]['default_value'] = $entry_data['element_'.$element_id]; + } + + } + + + return $form_values; + + + } + + //get an array containing values from respective table for certain id + //similar to get_entry_values() function, but this one is higher level and include labels + function get_entry_details($form_id,$entry_id,$options=array()){ + + $admin_clause = ''; + if(!empty($options['review_mode'])){ //hide admin fields in review page + $admin_clause = ' and element_is_private=0 '; + } + + //get form elements + $query = "select + element_id, + element_type, + element_constraint, + element_title + from + `ap_form_elements` + where + form_id='$form_id' and + element_type <> 'section' + {$admin_clause} + order by + element_position asc"; + $result = do_query($query); + $i=0; + while($row = do_fetch_result($result)){ + $form_elements[$i]['element_id'] = $row['element_id']; + $form_elements[$i]['element_type'] = $row['element_type']; + $form_elements[$i]['element_constraint'] = $row['element_constraint']; + + //store element title into array for reference later + $element_title_lookup[$row['element_id']] = $row['element_title']; + + $i++; + } + + if(!empty($options['review_mode'])){ + $table_suffix = '_review'; + }else{ + $table_suffix = ''; + } + + //get whole entry for current id + $query = "select * from `ap_form_{$form_id}{$table_suffix}` where id='$entry_id' limit 1"; + $result = do_query($query); + + //get actual field name from selected table + $i = 0; + $fields_num = mysql_num_fields($result); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + $columns[$i] = $meta->name; + $i++; + } + + $row = do_fetch_result($result); + //store the result into array + for($i=0;$i<$fields_num;$i++){ + $column_name = $columns[$i]; + $entry_data[$column_name] = htmlspecialchars($row[$column_name],ENT_QUOTES); + } + + + //get form element options + $query = "select element_id,option_id,`option` from ap_element_options where form_id='$form_id' and live=1 order by position asc"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $option_id = $row['option_id']; + + $element_option_lookup[$element_id][$option_id] = $row['option']; //array index will hold option_id + } + + + + + //loop through each element to get the values + $i = 0; + foreach ($form_elements as $element){ + $element_type = $element['element_type']; + $element_id = $element['element_id']; + $element_constraint = $element['element_constraint']; + + $entry_details[$i]['label'] = $element_title_lookup[$element_id]; + $entry_details[$i]['value'] = ' '; //default value + $entry_details[$i]['element_id'] = $element_id; + $entry_details[$i]['element_type'] = $element_type; + + + if('simple_name' == $element_type){ //Simple Name - 2 elements + $simple_name_value = trim($entry_data['element_'.$element_id.'_1'].' '.$entry_data['element_'.$element_id.'_2']); + if(!empty($simple_name_value)){ + $entry_details[$i]['value'] = $simple_name_value; + } + }elseif ('name' == $element_type){ //Extended Name - 4 elements + $name_value = trim($entry_data['element_'.$element_id.'_1'].' '. $entry_data['element_'.$element_id.'_2'].' '.$entry_data['element_'.$element_id.'_3'].' '.$entry_data['element_'.$element_id.'_4']); + if(!empty($name_value)){ + $entry_details[$i]['value'] = $name_value; + } + }elseif ('time' == $element_type){ //Time - 4 elements + //convert into time and split into 4 elements + if(!empty($entry_data['element_'.$element_id]) && ($entry_data['element_'.$element_id] != '00:00:00')){ + $time_value = $entry_data['element_'.$element_id]; + + if($element_constraint == 'show_seconds'){ + $time_value = date("h:i:s A",strtotime($time_value)); + }else{ + $time_value = date("h:i A",strtotime($time_value)); + } + + $entry_details[$i]['value'] = $time_value; + } + }elseif ('address' == $element_type){ //Address - 6 elements + + if(!empty($entry_data['element_'.$element_id.'_3'])){ + $entry_data['element_'.$element_id.'_3'] = $entry_data['element_'.$element_id.'_3'].','; + } + + $entry_details[$i]['value'] = $entry_data['element_'.$element_id.'_1'].' '.$entry_data['element_'.$element_id.'_2'].'
    '.$entry_data['element_'.$element_id.'_3'].' '.$entry_data['element_'.$element_id.'_4'].' '.$entry_data['element_'.$element_id.'_5'].'
    '.$entry_data['element_'.$element_id.'_6']; + + //if empty, shows blank instead of breaks + if(trim(str_replace("
    ","",$entry_details[$i]['value'])) == ""){ + $entry_details[$i]['value'] = ' '; + } + + }elseif ('money' == $element_type){ //Price + switch ($element_constraint){ + case 'pound' : $currency = '£';break; + case 'euro' : $currency = '€';break; + case 'yen' : $currency = '¥';break; + default : $currency = '$';break; + } + + if(!empty($entry_data['element_'.$element_id]) || $entry_data['element_'.$element_id] === 0 || $entry_data['element_'.$element_id] === '0'){ + $entry_details[$i]['value'] = $currency.$entry_data['element_'.$element_id]; + } + + }elseif ('date' == $element_type){ //date with format MM/DD/YYYY + if(!empty($entry_data['element_'.$element_id]) && ($entry_data['element_'.$element_id] != '0000-00-00')){ + $date_value = $entry_data['element_'.$element_id]; + $date_value = date("m/d/Y",strtotime($date_value)); + + $entry_details[$i]['value'] = $date_value; + } + + }elseif ('europe_date' == $element_type){ //date with format DD/MM/YYYY + if(!empty($entry_data['element_'.$element_id]) && ($entry_data['element_'.$element_id] != '0000-00-00')){ + $date_value = $entry_data['element_'.$element_id]; + $date_value = date("d/m/Y",strtotime($date_value)); + + $entry_details[$i]['value'] = $date_value; + } + + }elseif ('phone' == $element_type){ //Phone - 3 elements + + $phone_value = $entry_data['element_'.$element_id]; + $phone_1 = substr($phone_value,0,3); + $phone_2 = substr($phone_value,3,3); + $phone_3 = substr($phone_value,-4); + + if(!empty($phone_value)){ + $entry_details[$i]['value'] = "($phone_1) - $phone_2 - $phone_3"; + } + + }elseif ('checkbox' == $element_type){ //Checkbox - multiple elements + $checkbox_childs = $element_option_lookup[$element_id]; + + $checkbox_content = ''; + foreach ($checkbox_childs as $option_id=>$option_label){ + if(!empty($entry_data['element_'.$element_id.'_'.$option_id])){ + if(empty($options['strip_checkbox_image'])){ + $checkbox_content .= ' '.$option_label.'
    '; + }else{ + $checkbox_content .= '- '.$option_label.'
    '; + } + } + } + + if(!empty($checkbox_content)){ + $entry_details[$i]['value'] = $checkbox_content; + } + }elseif ('file' == $element_type){ //File + + $filename_value = $entry_data['element_'.$element_id]; + + if(!empty($filename_value)){ + $file_1 = substr($filename_value,strpos($filename_value,'-')+1); + $filename_value = substr($file_1,strpos($file_1,'-')+1); + + //encode the long query string for more readibility + $q_string = base64_encode("form_id={$form_id}&id={$entry_id}&el=element_{$element_id}"); + + if(!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] != 'off')){ + $ssl_suffix = 's'; + }else{ + $ssl_suffix = ''; + } + + //special for file,just provide a markup to download or delete the file + if(!empty($options['machform_base_path'])){ //if the form is called from advanced form code + $entry_details[$i]['value'] = ' '.$filename_value.''; + }else{ + $entry_details[$i]['value'] = ' '.$filename_value.''; + } + + if(!empty($options['strip_download_link'])){ + $entry_details[$i]['value'] = $filename_value; + } + + if(!empty($options['show_attach_image'])){ + $entry_details[$i]['value'] = ' '.$filename_value; + } + } + }elseif('select' == $element_type || 'radio' == $element_type){ + if(!empty($entry_data['element_'.$element_id])){ + $entry_details[$i]['value'] = $element_option_lookup[$element_id][$entry_data['element_'.$element_id]]; + } + }elseif ('url' == $element_type){ + if(!empty($entry_data['element_'.$element_id])){ + $entry_details[$i]['value'] = "{$entry_data['element_'.$element_id]}"; + } + }else{ //element with only 1 input + if(isset($entry_data['element_'.$element_id])){ + $entry_details[$i]['value'] = $entry_data['element_'.$element_id]; + } + } + + $i++; + } + + return $entry_details; + } + + + //delete a file element from an entry + function delete_file_entry($form_id,$entry_id,$element_id){ + //delete actual file + $query = "select element_{$element_id} from `ap_form_{$form_id}` where id='$entry_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + $filename = $row['element_'.$element_id]; + @unlink(UPLOAD_DIR."/form_{$form_id}/files/".$filename); + + //delete from table + $query = "update `ap_form_{$form_id}` set element_{$element_id}=NULL where id='$entry_id'"; + do_query($query); + } + + //delete a file element from an entry in review table + function delete_review_file_entry($form_id,$entry_id,$element_id,$options=array()){ + //delete actual file + $query = "select element_{$element_id} from `ap_form_{$form_id}_review` where id='$entry_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + $filename = $row['element_'.$element_id].'.tmp'; + @unlink($options['machform_data_path'].UPLOAD_DIR."/form_{$form_id}/files/".$filename); + + //delete from table + $query = "update `ap_form_{$form_id}_review` set element_{$element_id}=NULL where id='$entry_id'"; + do_query($query); + } + + //delete multiple entries and related uploads (if any) + function delete_entries($form_id,$entries_id){ + + //delete from table + $deleted_entry_id_joined = implode("','",$entries_id); + do_query("delete from `ap_form_{$form_id}` where id in('{$deleted_entry_id_joined}')"); + + + //get the element id for file fields + $query = "select element_id from ap_form_elements where element_type='file' and form_id='{$form_id}'"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $file_element_id_array[] = $row['element_id']; + } + + //delete the files from data folder + if(!empty($file_element_id_array)){ + foreach ($entries_id as $entry_id){ + foreach ($file_element_id_array as $element_id){ + $filename = array(); + $filename = glob(UPLOAD_DIR."/form_{$form_id}/files/element_{$element_id}_*-{$entry_id}-*"); + @unlink($filename[0]); + } + } + } + + return true; + } + +?> \ No newline at end of file diff --git a/includes/filter-functions.php b/includes/filter-functions.php new file mode 100644 index 0000000..358c984 --- /dev/null +++ b/includes/filter-functions.php @@ -0,0 +1,44 @@ +$value){ + if(!empty($value)){ + + //stripslashes added by magic quotes + if(get_magic_quotes_gpc()){ + $input_array[$key] = stripslashes($input_array[$key]); + } + + if($sanitize_html){ + $input_array[$key] = strip_tags($input_array[$key],$allowable_tags); + } + + if($sanitize_special_chars){ + $input_array[$key] = htmlspecialchars($input_array[$key]); + } + + if($escape_mysql){ + $input_array[$key] = mysql_real_escape_string($input_array[$key]); + } + } + } + + return $input_array; + + } + +?> \ No newline at end of file diff --git a/includes/footer.php b/includes/footer.php new file mode 100644 index 0000000..0861d69 --- /dev/null +++ b/includes/footer.php @@ -0,0 +1,12 @@ + +
    + + + + + + + + \ No newline at end of file diff --git a/includes/header.php b/includes/header.php new file mode 100644 index 0000000..dd21a79 --- /dev/null +++ b/includes/header.php @@ -0,0 +1,37 @@ + + + + +MachForm - PHP Form Builder + + + + + + + + +
    +
    +
    Loading Data ...
    +
    +
    + + + +
    + + + + + + +
    diff --git a/includes/helper-functions.php b/includes/helper-functions.php new file mode 100644 index 0000000..35ba3cf --- /dev/null +++ b/includes/helper-functions.php @@ -0,0 +1,514 @@ +0) { + // over a month old, just show date ("Month, Day Year") + if(!empty($input_date)){ + return date('F jS, Y',strtotime($input_date)); + }else{ + return 'N/A'; + } + } else { + if ($weeks>0) { + // weeks and days + $relative_date .= ($relative_date?', ':'').$weeks.' week'.($weeks>1?'s':''); + $relative_date .= $days>0?($relative_date?', ':'').$days.' day'.($days>1?'s':''):''; + } elseif ($days>0) { + // days and hours + $relative_date .= ($relative_date?', ':'').$days.' day'.($days>1?'s':''); + $relative_date .= $hours>0?($relative_date?', ':'').$hours.' hour'.($hours>1?'s':''):''; + } elseif ($hours>0) { + // hours and minutes + $relative_date .= ($relative_date?', ':'').$hours.' hour'.($hours>1?'s':''); + $relative_date .= $minutes>0?($relative_date?', ':'').$minutes.' minute'.($minutes>1?'s':''):''; + } elseif ($minutes>0) { + // minutes only + $relative_date .= ($relative_date?', ':'').$minutes.' minute'.($minutes>1?'s':''); + } else { + // seconds only + $relative_date .= ($relative_date?', ':'').$seconds.' second'.($seconds>1?'s':''); + } + + // show relative date and add proper verbiage + return $relative_date.' ago'; + } + + } + + //this function accept 'YYYY-MM-DD HH:MM:SS' + function short_relative_date($input_date) { + + $tz = 0; // change this if your web server and weblog are in different timezones + + $posted_date = str_replace(array('-',' ',':'),'',$input_date); + $month = substr($posted_date,4,2); + $year = substr($posted_date,0,4); + + if ($month == "02") { // february + // check for leap year + $leapYear = isLeapYear($year); + if ($leapYear) $month_in_seconds = 2505600; // leap year + else $month_in_seconds = 2419200; + } + else { // not february + // check to see if the month has 30/31 days in it + if ($month == "04" or + $month == "06" or + $month == "09" or + $month == "11") + $month_in_seconds = 2592000; // 30 day month + else $month_in_seconds = 2678400; // 31 day month; + } + + $in_seconds = strtotime(substr($posted_date,0,8).' '. + substr($posted_date,8,2).':'. + substr($posted_date,10,2).':'. + substr($posted_date,12,2)); + $diff = time() - ($in_seconds + ($tz*3600)); + $months = floor($diff/$month_in_seconds); + $diff -= $months*2419200; + $weeks = floor($diff/604800); + $diff -= $weeks*604800; + $days = floor($diff/86400); + $diff -= $days*86400; + $hours = floor($diff/3600); + $diff -= $hours*3600; + $minutes = floor($diff/60); + $diff -= $minutes*60; + $seconds = $diff; + + $relative_date = ''; + if ($months>0) { + + // over a month old + if(!empty($input_date)){ + if($year < date('Y')){ //over a year, show international date + return date('Y-m-d',strtotime($input_date)); + }else{ //less than a year + return date('M j',strtotime($input_date)); + } + + }else{ + return ''; + } + } else { + if ($weeks>0) { + // weeks and days + $relative_date .= ($relative_date?', ':'').$weeks.' week'.($weeks>1?'s':''); + //$relative_date .= $days>0?($relative_date?', ':'').$days.' day'.($days>1?'s':''):''; + } elseif ($days>0) { + // days and hours + $relative_date .= ($relative_date?', ':'').$days.' day'.($days>1?'s':''); + //$relative_date .= $hours>0?($relative_date?', ':'').$hours.' hour'.($hours>1?'s':''):''; + } elseif ($hours>0) { + // hours and minutes + $relative_date .= ($relative_date?', ':'').$hours.' hour'.($hours>1?'s':''); + //$relative_date .= $minutes>0?($relative_date?', ':'').$minutes.' minute'.($minutes>1?'s':''):''; + } elseif ($minutes>0) { + // minutes only + $relative_date .= ($relative_date?', ':'').$minutes.' minute'.($minutes>1?'s':''); + } else { + // seconds only + $relative_date .= ($relative_date?', ':'').$seconds.' second'.($seconds>1?'s':''); + } + + // show relative date and add proper verbiage + return $relative_date.' ago'; + } + + } + + function isLeapYear($year) { + return $year % 4 == 0 && ($year % 400 == 0 || $year % 100 != 0); + } + + //remove a folder and all it's content + function full_rmdir($dirname){ + if ($dirHandle = opendir($dirname)){ + $old_cwd = getcwd(); + chdir($dirname); + + while ($file = readdir($dirHandle)){ + if ($file == '.' || $file == '..') continue; + + if (is_dir($file)){ + if (!full_rmdir($file)) return false; + }else{ + if (!unlink($file)) return false; + } + } + + closedir($dirHandle); + chdir($old_cwd); + if (!rmdir($dirname)) return false; + + return true; + }else{ + return false; + } + } + + //show success or error messages + function show_message(){ + + if(!empty($_SESSION['AP_ERROR'])){ + if(!empty($_SESSION['AP_ERROR']['desc'])){ + $error_desc = '

    '.$_SESSION['AP_ERROR']['desc'].'

    '; + }else{ + $error_desc = ''; + } + + $ul_markup =<< +
  • +

    {$_SESSION['AP_ERROR']['title']}  

    + {$error_desc} +
  • + +EOT; + + echo $ul_markup; + + $_SESSION['AP_ERROR'] = array(); + unset($_SESSION['AP_ERROR']); + } + + if(!empty($_SESSION['AP_SUCCESS'])){ + if(!empty($_SESSION['AP_SUCCESS']['desc'])){ + $success_desc = '

    '.$_SESSION['AP_SUCCESS']['desc'].'

    '; + }else{ + $success_desc = ''; + } + + $ul_markup =<< +
  • +

    {$_SESSION['AP_SUCCESS']['title']} 

    + {$success_desc} +
  • + +EOT; + + echo $ul_markup; + + $_SESSION['AP_SUCCESS'] = array(); + unset($_SESSION['AP_SUCCESS']); + } + + } + + //send notification email + //$to_emails is a comma separated list of email address or {element_x} field + function send_notification($form_id,$entry_id,$to_emails,$email_param){ + + $from_name = $email_param['from_name']; + $from_email = $email_param['from_email']; + $subject = $email_param['subject']; + $content = nl2br($email_param['content']); + $as_plain_text = $email_param['as_plain_text']; //if set to 'true' the email content will be a simple plain text + $target_is_admin = $email_param['target_is_admin']; //if set to 'false', the download link for uploaded file will be removed + + + //get data for the particular entry id + if($target_is_admin === false){ + $options['strip_download_link'] = true; + } + + $options['strip_checkbox_image'] = true; + $options['machform_base_path'] = $email_param['machform_base_path']; //the path to machform + $entry_details = get_entry_details($form_id,$entry_id,$options); + + //populate field values to template variables + $i=0; + foreach ($entry_details as $data){ + $template_variables[$i] = '{element_'.$data['element_id'].'}'; + $template_values[$i] = $data['value']; + + if($data['element_type'] == 'textarea'){ + $template_values[$i] = nl2br($data['value']); + }elseif ($data['element_type'] == 'file'){ + if($target_is_admin === false){ + $template_values[$i] = strip_tags($data['value']); + }else{ + $template_values[$i] = strip_tags($data['value'],''); + } + }else{ + $template_values[$i] = $data['value']; + } + + $i++; + } + + //get entry timestamp + $query = "select date_created,ip_address from `ap_form_{$form_id}` where id='$entry_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + + $date_created = $row['date_created']; + $ip_address = $row['ip_address']; + + //get form name + $query = "select form_name from `ap_forms` where form_id='$form_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + $form_name = $row['form_name']; + + + $template_variables[$i] = '{date_created}'; + $template_values[$i] = $date_created; + $i++; + $template_variables[$i] = '{ip_address}'; + $template_values[$i] = $ip_address; + $i++; + $template_variables[$i] = '{form_name}'; + $template_values[$i] = $form_name; + $i++; + $template_variables[$i] = '{entry_no}'; + $template_values[$i] = $entry_id; + $i++; + $template_variables[$i] = '{form_id}'; + $template_values[$i] = $form_id; + + + //compose {entry_data} based on 'as_plain_text' preferences + $email_body = ''; + if(!$as_plain_text){ + //compose html format + $email_body = ''."\n"; + + $toggle = false; + foreach ($entry_details as $data){ + //0 should be displayed, empty string don't + if((empty($data['value']) || $data['value'] == ' ') && $data['value'] !== 0 && $data['value'] !== '0'){ + continue; + } + + if($toggle){ + $toggle = false; + $row_style = 'style="background-color:#F3F7FB"'; + }else{ + $toggle = true; + $row_style = ''; + } + + if($data['element_type'] == 'textarea'){ + $data['value'] = nl2br($data['value']); + }elseif ($data['element_type'] == 'file'){ + + if($target_is_admin === false){ + $data['value'] = strip_tags($data['value']); + }else{ + $data['value'] = strip_tags($data['value'],''); + } + } + + $email_body .= "\n"; + $email_body .= ''."\n"; + $email_body .= ''."\n"; + $email_body .= ''."\n"; + + $i++; + } + $email_body .= "
    '.$data['label'].' '.$data['value'].'
    \n"; + }else{ + + //compose text format + foreach ($entry_details as $data){ + + //0 should be displayed, empty string don't + if((empty($data['value']) || $data['value'] == ' ') && $data['value'] !== 0 && $data['value'] !== '0'){ + continue; + } + + if($data['element_type'] == 'textarea'){ + $email_body .= "{$data['label']}
    ".nl2br($data['value'])."

    \n"; + }elseif ($data['element_type'] == 'checkbox' || $data['element_type'] == 'address'){ + $email_body .= "{$data['label']}
    ".$data['value']."

    \n"; + }elseif ($data['element_type'] == 'file'){ + if($target_is_admin === false){ + $data['value'] = strip_tags($data['value']); + $email_body .= "{$data['label']} - {$data['value']}
    \n"; + }else{ + $data['value'] = strip_tags($data['value'],'
    '); + $email_body .= "{$data['label']}
    ".$data['value']."

    \n"; + } + }else{ + $email_body .= "{$data['label']} - {$data['value']}
    \n"; + } + + + } + } + + $i = count($template_variables); + $template_variables[$i] = '{entry_data}'; + $template_values[$i] = $email_body; + + $mail = new PHPMailer(); + $mail->CharSet = 'UTF-8'; + $mail->Host = "127.0.0.1"; + $mail->IsHTML(true); + $mail->Mailer = "mail"; + $mail->SMTPAuth = false; + + if(USE_SMTP === true){ + $mail->Mailer = "smtp"; + $mail->Host = SMTP_HOST; + $mail->Port = SMTP_PORT; + + if(SMTP_AUTH === true){ + $mail->SMTPAuth = true; + $mail->Username = SMTP_USERNAME; + $mail->Password = SMTP_PASSWORD; + } + + if(SMTP_SECURE === true){ + $mail->SMTPSecure = 'tls'; + } + } + + //parse from_name template + if(!empty($from_name)){ + $from_name = str_replace($template_variables,$template_values,$from_name); + $mail->FromName = str_replace(' ','',$from_name); + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $mail->FromName = utf8_encode(str_replace(' ','',str_replace($template_variables,$template_values,NOTIFICATION_MAIL_FROM_NAME))); + }else{ + $mail->FromName = 'MachForm'; + } + + //decode any html entity + $mail->FromName = html_entity_decode($mail->FromName,ENT_QUOTES); + + //parse from_email_address template + if(!empty($from_email)){ + $from_email = str_replace($template_variables,$template_values,$from_email); + $mail->From = $from_email; + }elseif(NOTIFICATION_MAIL_FROM != ''){ + $mail->From = utf8_encode(str_replace($template_variables,$template_values,NOTIFICATION_MAIL_FROM)); + }else{ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $mail->From = "no-reply@{$domain}"; + } + + //parse subject template + if(!empty($subject)){ + $subject = str_replace($template_variables,$template_values,$subject); + $mail->Subject = str_replace(' ','',$subject); + }elseif (NOTIFICATION_MAIL_SUBJECT != ''){ + $mail->Subject = utf8_encode(str_replace(' ','',str_replace($template_variables,$template_values,NOTIFICATION_MAIL_SUBJECT))); + }else{ + if($target_is_admin){ + $mail->Subject = utf8_encode("{$form_name} [#{$entry_id}]"); + }else{ + $mail->Subject = utf8_encode("{$form_name} - Receipt"); + } + } + //decode any html entity + $mail->Subject = html_entity_decode($mail->Subject,ENT_QUOTES); + + + //parse content template + $email_content = str_replace($template_variables,$template_values,$content); + + //add footer + $email_content .= "




    Powered by
    MachForm"; + + //enclose with container div + $email_content = '
    '.$email_content.'
    '; + + $mail->Body = $email_content; + + //send email + $to_emails = str_replace(' ','',str_replace($template_variables,$template_values,$to_emails)); + $email_address = explode(',',$to_emails); + + $has_email = false; + foreach ($email_address as $email){ + $email = trim($email); + if(!empty($email)){ + $mail->AddAddress($email); + $has_email = true; + } + } + + if($has_email){ + $send_status = $mail->Send(); + $mail->ClearAddresses(); + + if($send_status !== true){ + echo "Error sending email: ".$mail->ErrorInfo; + } + } + } + + function get_ssl_suffix(){ + if(!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] != 'off')){ + $ssl_suffix = 's'; + }else{ + $ssl_suffix = ''; + } + + return $ssl_suffix; + } + + function get_dirname($path){ + $current_dir = dirname($path); + + if($current_dir == "/" || $current_dir == "\\"){ + $current_dir = ''; + } + + return $current_dir; + } + +?> \ No newline at end of file diff --git a/includes/language.php b/includes/language.php new file mode 100644 index 0000000..b91e06a --- /dev/null +++ b/includes/language.php @@ -0,0 +1,96 @@ +highlighted below.'; + + //form buttons + $lang['submit_button'] = 'Submit'; + $lang['continue_button'] = 'Continue'; + $lang['back_button'] = 'Back'; + + //form status + $lang['form_inactive'] = 'This form is currently inactive.'; + + //form password + $lang['form_pass_title'] = 'This form is password protected.'; + $lang['form_pass_desc'] = 'Please enter your password.'; + $lang['form_pass_invalid'] = 'Invalid Password!'; + + //form review + $lang['review_title'] = 'Review Your Entry'; + $lang['review_message'] = 'Please review your entry below. Click Submit button to finish.'; + + //validation message + $lang['val_required'] = 'This field is required. Please enter a value.'; + $lang['val_required_file'] = 'This field is required. Please upload a file.'; + $lang['val_unique'] = 'This field requires a unique entry and this value has already been used.'; + $lang['val_integer'] = 'This field must be an integer.'; + $lang['val_float'] = 'This field must be a float.'; + $lang['val_numeric'] = 'This field must be a number.'; + $lang['val_min'] = 'This field can not be less than %s characters.'; + $lang['val_max'] = 'This field can not be greater than %s characters.'; + $lang['val_range'] = 'This field is not in the range %s through %s characters.'; + $lang['val_email'] = 'This field is not in the correct email format.'; + $lang['val_website'] = 'This field is not in the correct website address format.'; + $lang['val_username'] = 'This field may only consist of a-z 0-9 and underscores.'; + $lang['val_equal'] = '%s must match.'; + $lang['val_date'] = 'This field is not in the correct date format.'; + $lang['val_time'] = 'This field is not in the correct time format.'; + $lang['val_phone'] = 'Please enter a valid phone number.'; + $lang['val_filetype'] = 'The filetype you are attempting to upload is not allowed.'; + + //fields on excel/csv + $lang['export_num'] = 'No.'; + $lang['date_created'] = 'Date Created'; + $lang['date_updated'] = 'Date Updated'; + $lang['ip_address'] = 'IP Address'; +?> \ No newline at end of file diff --git a/includes/post-functions.php b/includes/post-functions.php new file mode 100644 index 0000000..706b634 --- /dev/null +++ b/includes/post-functions.php @@ -0,0 +1,2328 @@ + address, simple_name, name + //element has virtual child -> phone, date, europe_date, time, money + + $query = "select + element_id, + element_title, + element_is_required, + element_is_unique, + element_type, + element_constraint, + element_total_child, + element_is_private, + element_default_value + from + ap_form_elements + where + form_id='$form_id' order by element_id asc"; + + $result = do_query($query); + + $element_to_get = array(); + $private_elements = array(); //admin-only fields + + while($row = do_fetch_result($result)){ + if($row['element_type'] == 'section'){ + continue; + } + //store element info + $element_info[$row['element_id']]['title'] = $row['element_title']; + $element_info[$row['element_id']]['type'] = $row['element_type']; + $element_info[$row['element_id']]['is_required'] = $row['element_is_required']; + $element_info[$row['element_id']]['is_unique'] = $row['element_is_unique']; + $element_info[$row['element_id']]['is_private'] = $row['element_is_private']; + $element_info[$row['element_id']]['constraint'] = $row['element_constraint']; + $element_info[$row['element_id']]['default_value'] = $row['element_default_value']; + + //get element form name, complete with the childs + if(empty($element_child_lookup[$row['element_type']]) || ($row['element_constraint'] == 'yen')){ //elements with no child + $element_to_get[] = 'element_'.$row['element_id']; + + }else{ //elements with child + if($row['element_type'] != 'checkbox'){ + $max = $element_child_lookup[$row['element_type']] + 1; + + for ($j=1;$j<=$max;$j++){ + $element_to_get[] = "element_{$row['element_id']}_{$j}"; + } + }else{ + //for checkbox, get childs elements from ap_element_options table + $sub_query = "select + option_id + from + ap_element_options + where + form_id='{$form_id}' and element_id='{$row['element_id']}' and live=1 + order by + `position` asc"; + $sub_result = do_query($sub_query); + while($sub_row = do_fetch_result($sub_result)){ + $element_to_get[] = "element_{$row['element_id']}_{$sub_row['option_id']}"; + $checkbox_childs[$row['element_id']][] = $sub_row['option_id']; //store the child into array for further reference + } + } + } + + //if the back button pressed after review page, we need to store the file info + if(!empty($_SESSION['review_id'])){ + if($row['element_type'] == 'file'){ + $existing_file_id[] = $row['element_id']; + } + } + } + + + if(!empty($existing_file_id)){ + $existing_file_id_list = ''; + foreach ($existing_file_id as $value){ + $existing_file_id_list .= 'element_'.$value.','; + } + $existing_file_id_list = rtrim($existing_file_id_list,','); + + $query = "select {$existing_file_id_list} from ap_form_{$form_id}_review where `id`='{$_SESSION['review_id']}'"; + $result = do_query($query); + $row = do_fetch_result($result); + + foreach ($existing_file_id as $value){ + if(!empty($row['element_'.$value])){ + $element_info[$value]['existing_file'] = $row['element_'.$value]; + } + } + } + + //pick user input + $user_input = array(); + foreach ($element_to_get as $element_name){ + $user_input[$element_name] = @$input[$element_name]; + } + + + $error_elements = array(); + $table_data = array(); + //validate input based on rules specified for each field + foreach ($user_input as $element_name=>$element_data){ + + //get element_id from element_name + $exploded = array(); + $exploded = explode('_',$element_name); + $element_id = $exploded[1]; + + $rules = array(); + $target_input = array(); + + $element_type = $element_info[$element_id]['type']; + + + //if this is private fields and not logged-in as admin, bypass operation below, just supply the default value if any + if(($element_info[$element_id]['is_private'] == 1) && empty($_SESSION['logged_in'])){ + if(!empty($element_info[$element_id]['default_value'])){ + $table_data['element_'.$element_id] = $element_info[$element_id]['default_value']; + } + continue; + } + + + if('text' == $element_type){ //Single Line Text + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['max'] = 255; + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('textarea' == $element_type){ //Paragraph + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('radio' == $element_type){ //Multiple Choice + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = $element_data; + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('number' == $element_type){ //Number + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + //check for numeric if not empty + if(!empty($user_input[$element_name])){ + $rules[$element_name]['numeric'] = true; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = $element_data; + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('url' == $element_type){ //Website + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['website'] = true; + + if($element_data == 'http://'){ + $element_data = ''; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('email' == $element_type){ //Email + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['email'] = true; + + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('simple_name' == $element_type){ //Simple Name + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 2 elements total + $element_name_2 = substr($element_name,0,-1).'2'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed on next loop + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + $rules[$element_name_2]['required'] = true; + } + + $target_input[$element_name] = $user_input[$element_name]; + $target_input[$element_name_2] = $user_input[$element_name_2]; + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + $table_data[$element_name_2] = $user_input[$element_name_2]; + + }elseif ('name' == $element_type){ //Name - Extended + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 4 elements total + //only element no 2&3 matters (first and last name) + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + $element_name_4 = substr($element_name,0,-1).'4'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + $processed_elements[] = $element_name_4; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + } + + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + $form_data[$element_name_4]['default_value'] = htmlspecialchars($user_input[$element_name_4]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + $table_data[$element_name_2] = $user_input[$element_name_2]; + $table_data[$element_name_3] = $user_input[$element_name_3]; + $table_data[$element_name_4] = $user_input[$element_name_4]; + + }elseif ('time' == $element_type){ //Time + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 4 elements total + + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + $element_name_4 = substr($element_name,0,-1).'4'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + $processed_elements[] = $element_name_4; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + $rules[$element_name_4]['required'] = true; + } + + //check time validity if any of the compound field entered + $time_entry_exist = false; + if(!empty($user_input[$element_name]) || !empty($user_input[$element_name_2]) || !empty($user_input[$element_name_3])){ + $rules['element_time']['time'] = true; + $time_entry_exist = true; + } + + if($time_entry_exist && empty($element_info[$element_id]['constraint'])){ + $user_input[$element_name_3] = '00'; + } + + if($element_info[$element_id]['is_unique']){ + $rules['element_time_no_meridiem']['unique'] = $form_id.'#'.substr($element_name,0,-2); //to check uniquenes we need to use 24 hours HH:MM:SS format + } + + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + $target_input[$element_name_4] = $user_input[$element_name_4]; + if($time_entry_exist){ + $target_input['element_time'] = $user_input[$element_name].':'.$user_input[$element_name_2].':'.$user_input[$element_name_3].' '.$user_input[$element_name_4]; + $target_input['element_time_no_meridiem'] = @date("G:i:s",strtotime($target_input['element_time'])); + } + + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + $form_data[$element_name_4]['default_value'] = htmlspecialchars($user_input[$element_name_4]); + + //prepare data for table column + $table_data[substr($element_name,0,-2)] = @$target_input['element_time_no_meridiem']; + + }elseif ('address' == $element_type){ //Address + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 6 elements total, element #2 (address line 2) is optional + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + $element_name_4 = substr($element_name,0,-1).'4'; + $element_name_5 = substr($element_name,0,-1).'5'; + $element_name_6 = substr($element_name,0,-1).'6'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + $processed_elements[] = $element_name_4; + $processed_elements[] = $element_name_5; + $processed_elements[] = $element_name_6; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + $rules[$element_name_3]['required'] = true; + $rules[$element_name_4]['required'] = true; + $rules[$element_name_5]['required'] = true; + $rules[$element_name_6]['required'] = true; + + } + + $target_input[$element_name] = $user_input[$element_name]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + $target_input[$element_name_4] = $user_input[$element_name_4]; + $target_input[$element_name_5] = $user_input[$element_name_5]; + $target_input[$element_name_6] = $user_input[$element_name_6]; + + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + $form_data[$element_name_4]['default_value'] = htmlspecialchars($user_input[$element_name_4]); + $form_data[$element_name_5]['default_value'] = htmlspecialchars($user_input[$element_name_5]); + $form_data[$element_name_6]['default_value'] = htmlspecialchars($user_input[$element_name_6]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + $table_data[$element_name_2] = $user_input[$element_name_2]; + $table_data[$element_name_3] = $user_input[$element_name_3]; + $table_data[$element_name_4] = $user_input[$element_name_4]; + $table_data[$element_name_5] = $user_input[$element_name_5]; + $table_data[$element_name_6] = $user_input[$element_name_6]; + + }elseif ('money' == $element_type){ //Price + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 2 elements total (for currency other than yen) + if($element_info[$element_id]['constraint'] != 'yen'){ //if other than yen + $base_element_name = substr($element_name,0,-1); + $element_name_2 = $base_element_name.'2'; + $processed_elements[] = $element_name_2; + + if($element_info[$element_id]['is_required']){ + $rules[$base_element_name]['required'] = true; + } + + //check for numeric if not empty + if(!empty($user_input[$element_name]) || !empty($user_input[$element_name_2])){ + $rules[$base_element_name]['numeric'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$base_element_name]['unique'] = $form_id.'#'.substr($element_name,0,-2); + } + + $target_input[$base_element_name] = $user_input[$element_name].'.'.$user_input[$element_name_2]; //join dollar+cent + if($target_input[$base_element_name] == '.'){ + $target_input[$base_element_name] = ''; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + + //prepare data for table column + if(!empty($user_input[$element_name]) || !empty($user_input[$element_name_2]) + || $user_input[$element_name] === '0' || $user_input[$element_name_2] === '0'){ + $table_data[substr($element_name,0,-2)] = $user_input[$element_name].'.'.$user_input[$element_name_2]; + } + }else{ + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + //check for numeric if not empty + if(!empty($user_input[$element_name])){ + $rules[$element_name]['numeric'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $target_input[$element_name] = $user_input[$element_name]; + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + } + + + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + }elseif ('checkbox' == $element_type){ //Checkboxes + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + if($element_info[$element_id]['is_required']){ + //checking 'required' for checkboxes is more complex + //we need to get total child, and join it into one element + //only one element is required to be checked + $all_child_array = array(); + $all_child_array = $checkbox_childs[$element_id]; + $base_element_name = 'element_' . $element_id . '_'; + + $all_checkbox_value = ''; + foreach ($all_child_array as $i){ + $all_checkbox_value .= $user_input[$base_element_name.$i]; + $processed_elements[] = $base_element_name.$i; + + //save old data into array, for form redisplay in case errors occured + $form_data[$base_element_name.$i]['default_value'] = $user_input[$base_element_name.$i]; + + //prepare data for table column + $table_data[$base_element_name.$i] = $user_input[$base_element_name.$i]; + + } + + $rules[$base_element_name]['required'] = true; + + $target_input[$base_element_name] = $all_checkbox_value; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + }else{ //if not required, we only need to capture all data + $all_child_array = array(); + $base_exploded = array(); + $all_child_array = $checkbox_childs[$element_id]; + + $base_exploded = explode("_",$element_name); + $base_element_name = "element_".$base_exploded[1]."_"; + + + foreach ($all_child_array as $i){ + + //save old data into array, for form redisplay in case errors occured + $form_data[$base_element_name.$i]['default_value'] = $user_input[$base_element_name.$i]; + + //prepare data for table column + $table_data[$base_element_name.$i] = $user_input[$base_element_name.$i]; + } + + } + }elseif ('select' == $element_type){ //Drop Down + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = $user_input[$element_name]; + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + }elseif ('date' == $element_type || 'europe_date' == $element_type){ //Date + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 3 elements total + + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + } + + $rules['element_date']['date'] = 'yyyy/mm/dd'; + + if($element_info[$element_id]['is_unique']){ + $rules['element_date']['unique'] = $form_id.'#'.substr($element_name,0,-2); + } + + $target_input[$element_name] = $user_input[$element_name]; + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + + $base_element_name = substr($element_name,0,-2); + if('date' == $element_type){ //MM/DD/YYYY + $target_input['element_date'] = $user_input[$element_name_3].'-'.$user_input[$element_name].'-'.$user_input[$element_name_2]; + + //prepare data for table column + $table_data[$base_element_name] = $user_input[$element_name_3].'-'.$user_input[$element_name].'-'.$user_input[$element_name_2]; + }else{ //DD/MM/YYYY + $target_input['element_date'] = $user_input[$element_name_3].'-'.$user_input[$element_name_2].'-'.$user_input[$element_name]; + + //prepare data for table column + $table_data[$base_element_name] = $user_input[$element_name_3].'-'.$user_input[$element_name_2].'-'.$user_input[$element_name]; + } + + $test_empty = str_replace('-','',$target_input['element_date']); //if user not submitting any entry, remove the dashes + if(empty($test_empty)){ + unset($target_input['element_date']); + $table_data[$base_element_name] = ''; + } + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + + }elseif ('simple_phone' == $element_type){ //Simple Phone + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if(!empty($user_input[$element_name])){ + $rules[$element_name]['simple_phone'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $target_input[$element_name] = $user_input[$element_name]; + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + }elseif ('phone' == $element_type){ //Phone - US format + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 3 elements total + + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + } + + $rules['element_phone']['phone'] = true; + + + if($element_info[$element_id]['is_unique']){ + $rules['element_phone']['unique'] = $form_id.'#'.substr($element_name,0,-2); + } + + $target_input[$element_name] = $user_input[$element_name]; + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + $target_input['element_phone'] = $user_input[$element_name].$user_input[$element_name_2].$user_input[$element_name_3]; + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + + //prepare data for table column + $table_data[substr($element_name,0,-2)] = $user_input[$element_name].$user_input[$element_name_2].$user_input[$element_name_3]; + + }elseif ('email' == $element_type){ //Email + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['email'] = true; + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + }elseif ('file' == $element_type){ //File + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required_file'] = true; + $rules[$element_name]['filetype'] = true; + + //if form review enabled, and user pressed back button after going to review page + //disable the required file checking if file already uploaded + if(!empty($_SESSION['review_id'])){ + if(!empty($element_info[$element_id]['existing_file'])){ + unset($rules[$element_name]['required_file']); + unset($rules[$element_name]['filetype']); + } + } + }else{ + if($_FILES[$element_name]['size'] > 0){ + $rules[$element_name]['filetype'] = true; + } + } + + $target_input[$element_name] = $element_name; //special for file, only need to pass input name + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + }else{ + //if validation passed, store uploaded file info into array + if($_FILES[$element_name]['size'] > 0){ + $uploaded_files[] = $element_name; + } + } + + + } + + } + + + + //get form redirect info, if any + //get form properties data + $query = "select + form_redirect, + form_email, + form_unique_ip, + form_captcha, + form_review, + esl_from_name, + esl_from_email_address, + esl_subject, + esl_content, + esl_plain_text, + esr_email_address, + esr_from_name, + esr_from_email_address, + esr_subject, + esr_content, + esr_plain_text + from + `ap_forms` + where + form_id='$form_id'"; + + $result = do_query($query); + $row = do_fetch_result($result); + $form_redirect = $row['form_redirect']; + $form_unique_ip = $row['form_unique_ip']; + $form_email = $row['form_email']; + $form_captcha = $row['form_captcha']; + $form_review = $row['form_review']; + $user_ip_address = $_SERVER['REMOTE_ADDR']; + + $esl_from_name = $row['esl_from_name']; + $esl_from_email_address = $row['esl_from_email_address']; + $esl_subject = $row['esl_subject']; + $esl_content = $row['esl_content']; + $esl_plain_text = $row['esl_plain_text']; + + $esr_email_address = $row['esr_email_address']; + $esr_from_name = $row['esr_from_name']; + $esr_from_email_address = $row['esr_from_email_address']; + $esr_subject = $row['esr_subject']; + $esr_content = $row['esr_content']; + $esr_plain_text = $row['esr_plain_text']; + + $process_result['form_redirect'] = $form_redirect; + $process_result['old_values'] = $form_data; + $process_result['error_elements'] = $error_elements; + + //check for ip address + if(!empty($form_unique_ip)){ + //if ip address checking enabled, compare user ip address with value in db + $query = "select count(id) total_ip from `ap_form_{$form_id}` where ip_address='$user_ip_address'"; + $result = do_query($query); + $row = do_fetch_result($result); + if(!empty($row['total_ip'])){ + $process_result['custom_error'] = 'Sorry, but this form is limited to one submission per user.'; + } + } + + //check for captcha if enabled and there is no errors from previous fields + if(!empty($form_captcha) && empty($error_elements)){ + + if(USE_INTERNAL_CAPTCHA === true){//if internal captcha is being used + if(!empty($_POST['captcha_response_field'])){ + $captcha_response_field = trim($_POST['captcha_response_field']); + if (PhpCaptcha::Validate($captcha_response_field) !== true) { + $error_elements['element_captcha'] = 'incorrect-captcha-sol'; + $process_result['error_elements'] = $error_elements; + } + }else{ //user not entered the words at all + $error_elements['element_captcha'] = 'el-required'; + $process_result['error_elements'] = $error_elements; + } + }else{ //otherwise reCaptcha is being used + if(!empty($_POST['recaptcha_response_field'])){ + $recaptcha_response = recaptcha_check_answer (RECAPTCHA_PRIVATE_KEY, + $user_ip_address, + $_POST["recaptcha_challenge_field"], + $_POST["recaptcha_response_field"]); + + if($recaptcha_response !== false){ //if false, then we can't connect to captcha server, bypass captcha checking + if ($recaptcha_response->is_valid === false) { + $error_elements['element_captcha'] = $recaptcha_response->error; + $process_result['error_elements'] = $error_elements; + } + } + }else{ //user not entered the words at all + $error_elements['element_captcha'] = 'el-required'; + $process_result['error_elements'] = $error_elements; + } + } + + } + + + //insert ip address and date created + $table_data['ip_address'] = $user_ip_address; + $table_data['date_created'] = date("Y-m-d H:i:s"); + + $is_inserted = false; + + //start insert data into table ---------------------- + //dynamically create the field list and field values, based on the input given + if(!empty($table_data) && empty($error_elements) && empty($process_result['custom_error'])){ + $has_value = false; + + $field_list = ''; + $field_values = ''; + + foreach ($table_data as $key=>$value){ + + if($value == ''){ //don't insert blank entry + continue; + } + $value = mysql_real_escape_string($value); + $field_list .= "`$key`,"; + $field_values .= "'$value',"; + + if(!empty($value)){ + $has_value = true; + } + } + + //add session_id to query if 'form review' enabled + if(!empty($form_review)){ + //save previously uploaded file list, so users don't need to reupload files + //get all file uploads elements first + + if(!empty($_SESSION['review_id'])){ + + $query = "SELECT + element_id + FROM + ap_form_elements + WHERE + form_id='{$form_id}' AND + element_type='file' AND + element_is_private=0"; + $result = do_query($query); + $file_uploads_array = array(); + while($row = do_fetch_result($result)){ + $file_uploads_array[] = 'element_'.$row['element_id']; + } + + $file_uploads_column = implode('`,`',$file_uploads_array); + $file_uploads_column = '`'.$file_uploads_column.'`'; + + if(!empty($file_uploads_array)){ + $query = "SELECT {$file_uploads_column} FROM `ap_form_{$form_id}_review` where id='{$_SESSION['review_id']}'"; + $result = do_query($query); + $row = do_fetch_result($result); + foreach ($file_uploads_array as $element_name){ + if(!empty($row[$element_name])){ + $uploaded_file_lookup[$element_name] = $row[$element_name]; + } + } + } + } + + + //add session_id to query if 'form review' enabled + $session_id = session_id(); + + do_query("DELETE FROM `ap_form_{$form_id}_review` where session_id='{$session_id}'"); + + $field_list .= "`session_id`,"; + $field_values .= "'{$session_id}',"; + } + + + if($has_value){ //if blank form submitted, dont insert anything + + //start insert query ---------------------------------------- + $field_list = substr($field_list,0,-1); + $field_values = substr($field_values,0,-1); + + if(empty($form_review)){ + $query = "INSERT INTO `ap_form_{$form_id}` ($field_list) VALUES ($field_values);"; + }else{ //insert to temporary table, if form review is enabled + $query = "INSERT INTO `ap_form_{$form_id}_review` ($field_list) VALUES ($field_values);"; + } + + do_query($query); + + $record_insert_id = mysql_insert_id(); + //end insert query ------------------------------------------ + + $is_inserted = true; + } + } + //end insert data into table ------------------------- + + //upload the files + if(!empty($record_insert_id)){ + if(!empty($uploaded_files)){ + foreach ($uploaded_files as $element_name){ + $file_token = md5(uniqid(rand(), true)); //add random token to uploaded filename, to increase security + + if(empty($form_review)){ + //move file and check for invalid file + $destination_file = $input['machform_data_path'].UPLOAD_DIR."/form_{$form_id}/files/{$element_name}_{$file_token}-{$record_insert_id}-{$_FILES[$element_name]['name']}"; + if (move_uploaded_file($_FILES[$element_name]['tmp_name'], $destination_file)) { + $filename = mysql_real_escape_string($_FILES[$element_name]['name']); + $query = "update ap_form_{$form_id} set $element_name='{$element_name}_{$file_token}-{$record_insert_id}-{$filename}' where id='$record_insert_id'"; + do_query($query); + } + }else{ + //for form with review enabled, append .tmp suffix to all uploaded files + //move file and check for invalid file + $destination_file = $input['machform_data_path'].UPLOAD_DIR."/form_{$form_id}/files/{$element_name}_{$file_token}-{$record_insert_id}-{$_FILES[$element_name]['name']}.tmp"; + if (move_uploaded_file($_FILES[$element_name]['tmp_name'], $destination_file)) { + $filename = mysql_real_escape_string($_FILES[$element_name]['name']); + $query = "update ap_form_{$form_id}_review set $element_name='{$element_name}_{$file_token}-{$record_insert_id}-{$filename}' where id='$record_insert_id'"; + do_query($query); + } + + if(!empty($uploaded_file_lookup[$element_name])){ + unset($uploaded_file_lookup[$element_name]); + } + } + } + } + + //update the previouly uploaded file to the current record + if(!empty($form_review) && !empty($uploaded_file_lookup)){ + //update the database record + $update_clause = ''; + foreach ($uploaded_file_lookup as $element_name=>$filename){ + $update_clause .= "`{$element_name}`='{$filename}',"; + } + $update_clause = rtrim($update_clause,","); + do_query("UPDATE `ap_form_{$form_id}_review` SET {$update_clause} WHERE id='{$record_insert_id}'"); + } + } + + + //start sending notification email to admin ------------------------------------------ + if($is_inserted && !empty($form_email) && empty($form_review)){ + //get parameters for the email + + //from name + if(!empty($esl_from_name)){ + $admin_email_param['from_name'] = $esl_from_name; + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $admin_email_param['from_name'] = NOTIFICATION_MAIL_FROM_NAME; + }else{ + $admin_email_param['from_name'] = 'MachForm'; + } + + //from email address + if(!empty($esl_from_email_address)){ + if(is_numeric($esl_from_email_address)){ + $admin_email_param['from_email'] = '{element_'.$esl_from_email_address.'}'; + }else{ + $admin_email_param['from_email'] = $esl_from_email_address; + } + }elseif(NOTIFICATION_MAIL_FROM != ''){ + $admin_email_param['from_email'] = NOTIFICATION_MAIL_FROM; + }else{ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $admin_email_param['from_email'] = "no-reply@{$domain}"; + } + + //subject + if(!empty($esl_subject)){ + $admin_email_param['subject'] = $esl_subject; + }elseif (NOTIFICATION_MAIL_SUBJECT != ''){ + $admin_email_param['subject'] = NOTIFICATION_MAIL_SUBJECT; + }else{ + $admin_email_param['subject'] = '{form_name} [#{entry_no}]'; + } + + //content + if(!empty($esl_content)){ + $admin_email_param['content'] = $esl_content; + }else{ + $admin_email_param['content'] = '{entry_data}'; + } + + $admin_email_param['as_plain_text'] = $esl_plain_text; + $admin_email_param['target_is_admin'] = true; + $admin_email_param['machform_base_path'] = $input['machform_base_path']; + send_notification($form_id,$record_insert_id,$form_email,$admin_email_param); + + } + //end emailing notifications to admin ---------------------------------------------- + + + //start sending notification email to user ------------------------------------------ + if($is_inserted && !empty($esr_email_address) && empty($form_review)){ + //get parameters for the email + + //to email + if(is_numeric($esr_email_address)){ + $esr_email_address = '{element_'.$esr_email_address.'}'; + } + + //from name + if(!empty($esr_from_name)){ + $user_email_param['from_name'] = $esr_from_name; + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $user_email_param['from_name'] = NOTIFICATION_MAIL_FROM_NAME; + }else{ + $user_email_param['from_name'] = 'MachForm'; + } + + //from email address + if(!empty($esr_from_email_address)){ + if(is_numeric($esr_from_email_address)){ + $user_email_param['from_email'] = '{element_'.$esr_from_email_address.'}'; + }else{ + $user_email_param['from_email'] = $esr_from_email_address; + } + }elseif(NOTIFICATION_MAIL_FROM != ''){ + $user_email_param['from_email'] = NOTIFICATION_MAIL_FROM; + }else{ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $user_email_param['from_email'] = "no-reply@{$domain}"; + } + + //subject + if(!empty($esr_subject)){ + $user_email_param['subject'] = $esr_subject; + }elseif (NOTIFICATION_MAIL_SUBJECT != ''){ + $user_email_param['subject'] = NOTIFICATION_MAIL_SUBJECT; + }else{ + $user_email_param['subject'] = '{form_name} - Receipt'; + } + + //content + if(!empty($esr_content)){ + $user_email_param['content'] = $esr_content; + }else{ + $user_email_param['content'] = '{entry_data}'; + } + + $user_email_param['as_plain_text'] = $esr_plain_text; + $user_email_param['target_is_admin'] = false; + + send_notification($form_id,$record_insert_id,$esr_email_address,$user_email_param); + } + //end emailing notifications to user ---------------------------------------------- + + + //if there is any error message or elements, send false as status + if(empty($error_elements) && empty($process_result['custom_error'])){ + $process_result['status'] = true; + + //if 'form review' enabled, send review_id + if(!empty($form_review)){ + $process_result['review_id'] = $record_insert_id; + } + }else{ + $process_result['status'] = false; + } + + + return $process_result; + } + + + //similar to above, except this function is being used to update form data + function process_form_update($input){ + + $form_id = (int) trim($input['form_id']); + $entry_id = (int) trim($input['edit_id']); + + global $lang; + + //this function handle password submission and general form submission + if(isset($input['password'])){ //if there is password input, do validation + $query = "select count(form_id) valid_password from `ap_forms` where form_password='{$input['password']}'"; + $result = do_query($query); + $row = do_fetch_result($result); + if(!empty($row['valid_password'])){ + $process_result['status'] = true; + $_SESSION['user_authenticated'] = $form_id; + }else{ + $process_result['status'] = false; + $process_result['custom_error'] = $lang['form_pass_invalid']; + } + + return $process_result; + } + + + $element_child_lookup['address'] = 5; + $element_child_lookup['simple_name'] = 1; + $element_child_lookup['name'] = 3; + $element_child_lookup['phone'] = 2; + $element_child_lookup['date'] = 2; + $element_child_lookup['europe_date'] = 2; + $element_child_lookup['time'] = 3; + $element_child_lookup['money'] = 1; //this applies to dollar,euro and pound. yen don't have child + $element_child_lookup['checkbox'] = 1; //this is just a dumb value + + //never trust user input, get a list of input fields based on info stored on table + //element has real child -> address, simple_name, name + //element has virtual child -> phone, date, europe_date, time, money + + $query = "select + element_id, + element_title, + element_is_required, + element_is_unique, + element_type, + element_constraint, + element_total_child + from + ap_form_elements + where + form_id='$form_id' order by element_id asc"; + + $result = do_query($query); + + $element_to_get = array(); + + while($row = do_fetch_result($result)){ + if($row['element_type'] == 'section'){ + continue; + } + //store element info + $element_info[$row['element_id']]['title'] = $row['element_title']; + $element_info[$row['element_id']]['type'] = $row['element_type']; + $element_info[$row['element_id']]['is_required'] = $row['element_is_required']; + $element_info[$row['element_id']]['is_unique'] = $row['element_is_unique']; + $element_info[$row['element_id']]['constraint'] = $row['element_constraint']; + + //get element form name, complete with the childs + if(empty($element_child_lookup[$row['element_type']]) || ($row['element_constraint'] == 'yen')){ //elements with no child + $element_to_get[] = 'element_'.$row['element_id']; + }else{ //elements with child + if($row['element_type'] != 'checkbox'){ + $max = $element_child_lookup[$row['element_type']] + 1; + + for ($j=1;$j<=$max;$j++){ + $element_to_get[] = "element_{$row['element_id']}_{$j}"; + } + }else{ + //for checkbox, get childs elements from ap_element_options table + $sub_query = "select + option_id + from + ap_element_options + where + form_id='{$form_id}' and element_id='{$row['element_id']}' and live=1 + order by + `position` asc"; + $sub_result = do_query($sub_query); + while($sub_row = do_fetch_result($sub_result)){ + $element_to_get[] = "element_{$row['element_id']}_{$sub_row['option_id']}"; + $checkbox_childs[$row['element_id']][] = $sub_row['option_id']; //store the child into array for further reference + } + + //add base element id for checkbox processing + //add "_" in the end to indicate base element + $element_to_get[] = "element_{$row['element_id']}_"; + } + + + + } + + } + + //pick user input + $user_input = array(); + foreach ($element_to_get as $element_name){ + $user_input[$element_name] = $input[$element_name]; + } + + + $error_elements = array(); + $table_data = array(); + //validate input based on rules specified for each field + foreach ($user_input as $element_name=>$element_data){ + + //get element_id from element_name + $exploded = array(); + $exploded = explode('_',$element_name); + $element_id = $exploded[1]; + + $rules = array(); + $target_input = array(); + + $element_type = $element_info[$element_id]['type']; + + if('text' == $element_type){ //Single Line Text + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['max'] = 255; + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('textarea' == $element_type){ //Paragraph + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('radio' == $element_type){ //Multiple Choice + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = $element_data; + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('number' == $element_type){ //Number + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + //check for numeric if not empty + if(!empty($user_input[$element_name])){ + $rules[$element_name]['numeric'] = true; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = $element_data; + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('url' == $element_type){ //Website + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['website'] = true; + + if($element_data == 'http://'){ + $element_data = ''; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('email' == $element_type){ //Email + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['email'] = true; + + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($element_data); + + //prepare data for table column + $table_data[$element_name] = $element_data; + + }elseif ('simple_name' == $element_type){ //Simple Name + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 2 elements total + $element_name_2 = substr($element_name,0,-1).'2'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed on next loop + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + $rules[$element_name_2]['required'] = true; + } + + $target_input[$element_name] = $user_input[$element_name]; + $target_input[$element_name_2] = $user_input[$element_name_2]; + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + $table_data[$element_name_2] = $user_input[$element_name_2]; + + }elseif ('name' == $element_type){ //Name - Extended + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 4 elements total + //only element no 2&3 matters (first and last name) + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + $element_name_4 = substr($element_name,0,-1).'4'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + $processed_elements[] = $element_name_4; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + } + + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + $form_data[$element_name_4]['default_value'] = htmlspecialchars($user_input[$element_name_4]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + $table_data[$element_name_2] = $user_input[$element_name_2]; + $table_data[$element_name_3] = $user_input[$element_name_3]; + $table_data[$element_name_4] = $user_input[$element_name_4]; + + }elseif ('time' == $element_type){ //Time + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 4 elements total + + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + $element_name_4 = substr($element_name,0,-1).'4'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + $processed_elements[] = $element_name_4; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + $rules[$element_name_4]['required'] = true; + } + + //check time validity if any of the compound field entered + $time_entry_exist = false; + if(!empty($user_input[$element_name]) || !empty($user_input[$element_name_2]) || !empty($user_input[$element_name_3])){ + $rules['element_time']['time'] = true; + $time_entry_exist = true; + } + + if($time_entry_exist && empty($element_info[$element_id]['constraint'])){ + $user_input[$element_name_3] = '00'; + } + + if($element_info[$element_id]['is_unique']){ + $rules['element_time_no_meridiem']['unique'] = $form_id.'#'.substr($element_name,0,-2); //to check uniquenes we need to use 24 hours HH:MM:SS format + } + + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + $target_input[$element_name_4] = $user_input[$element_name_4]; + if($time_entry_exist){ + $target_input['element_time'] = $user_input[$element_name].':'.$user_input[$element_name_2].':'.$user_input[$element_name_3].' '.$user_input[$element_name_4]; + $target_input['element_time_no_meridiem'] = @date("G:i:s",strtotime($target_input['element_time'])); + } + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + $form_data[$element_name_4]['default_value'] = htmlspecialchars($user_input[$element_name_4]); + + //prepare data for table column + $table_data[substr($element_name,0,-2)] = $target_input['element_time_no_meridiem']; + + }elseif ('address' == $element_type){ //Address + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 6 elements total, element #2 (address line 2) is optional + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + $element_name_4 = substr($element_name,0,-1).'4'; + $element_name_5 = substr($element_name,0,-1).'5'; + $element_name_6 = substr($element_name,0,-1).'6'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + $processed_elements[] = $element_name_4; + $processed_elements[] = $element_name_5; + $processed_elements[] = $element_name_6; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name_3]['required'] = true; + $rules[$element_name_4]['required'] = true; + $rules[$element_name_5]['required'] = true; + $rules[$element_name_6]['required'] = true; + + } + + $target_input[$element_name_3] = $user_input[$element_name_3]; + $target_input[$element_name_4] = $user_input[$element_name_4]; + $target_input[$element_name_5] = $user_input[$element_name_5]; + $target_input[$element_name_6] = $user_input[$element_name_6]; + + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + $form_data[$element_name_4]['default_value'] = htmlspecialchars($user_input[$element_name_4]); + $form_data[$element_name_5]['default_value'] = htmlspecialchars($user_input[$element_name_5]); + $form_data[$element_name_6]['default_value'] = htmlspecialchars($user_input[$element_name_6]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + $table_data[$element_name_2] = $user_input[$element_name_2]; + $table_data[$element_name_3] = $user_input[$element_name_3]; + $table_data[$element_name_4] = $user_input[$element_name_4]; + $table_data[$element_name_5] = $user_input[$element_name_5]; + $table_data[$element_name_6] = $user_input[$element_name_6]; + + }elseif ('money' == $element_type){ //Price + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 2 elements total (for currency other than yen) + if($element_info[$element_id]['constraint'] != 'yen'){ //if other than yen + $base_element_name = substr($element_name,0,-1); + $element_name_2 = $base_element_name.'2'; + $processed_elements[] = $element_name_2; + + if($element_info[$element_id]['is_required']){ + $rules[$base_element_name]['required'] = true; + } + + //check for numeric if not empty + if(!empty($user_input[$element_name]) || !empty($user_input[$element_name_2])){ + $rules[$base_element_name]['numeric'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$base_element_name]['unique'] = $form_id.'#'.substr($element_name,0,-2); + } + + $target_input[$base_element_name] = $user_input[$element_name].'.'.$user_input[$element_name_2]; //join dollar+cent + if($target_input[$base_element_name] == '.'){ + $target_input[$base_element_name] = ''; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + + //prepare data for table column + if(!empty($user_input[$element_name]) || !empty($user_input[$element_name_2])){ + $table_data[substr($element_name,0,-2)] = $user_input[$element_name].'.'.$user_input[$element_name_2]; + } + }else{ + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + //check for numeric if not empty + if(!empty($user_input[$element_name])){ + $rules[$element_name]['numeric'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $target_input[$element_name] = $user_input[$element_name]; + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + } + + + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + }elseif ('checkbox' == $element_type){ //Checkboxes + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //validate base element, will not process child data + $base_element = substr($element_name,-1); + + if ($base_element != '_') { + continue; + } + + + //checking 'required' for checkboxes is more complex + //we need to get total child, and join it into one element + //only one element is required to be checked + $all_child_array = array(); + $all_child_array = $checkbox_childs[$element_id]; + $base_element_name = $element_name; + + $all_checkbox_value = ''; + + foreach ($all_child_array as $i){ + $all_checkbox_value .= $user_input[$base_element_name.$i]; + $processed_elements[] = $base_element_name.$i; + + //save old data into array, for form redisplay in case errors occured + $form_data[$base_element_name.$i]['default_value'] = $user_input[$base_element_name.$i]; + + //prepare data for table column + //add zero if no data + if (!empty($user_input[$base_element_name.$i])) + $table_data[$base_element_name.$i] = $user_input[$base_element_name.$i]; + else + $table_data[$base_element_name.$i] = '0'; + + } + + if($element_info[$element_id]['is_required']){ + $rules[$base_element_name]['required'] = true; + } + + $target_input[$base_element_name] = $all_checkbox_value; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + }elseif ('select' == $element_type){ //Drop Down + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = $user_input[$element_name]; + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + }elseif ('date' == $element_type || 'europe_date' == $element_type){ //Date + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 3 elements total + + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + } + + $rules['element_date']['date'] = 'yyyy/mm/dd'; + + if($element_info[$element_id]['is_unique']){ + $rules['element_date']['unique'] = $form_id.'#'.substr($element_name,0,-2); + } + + $target_input[$element_name] = $user_input[$element_name]; + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + + $base_element_name = substr($element_name,0,-2); + if('date' == $element_type){ //MM/DD/YYYY + $target_input['element_date'] = $user_input[$element_name_3].'-'.$user_input[$element_name].'-'.$user_input[$element_name_2]; + + //prepare data for table column + $table_data[$base_element_name] = $user_input[$element_name_3].'-'.$user_input[$element_name].'-'.$user_input[$element_name_2]; + }else{ //DD/MM/YYYY + $target_input['element_date'] = $user_input[$element_name_3].'-'.$user_input[$element_name_2].'-'.$user_input[$element_name]; + + //prepare data for table column + $table_data[$base_element_name] = $user_input[$element_name_3].'-'.$user_input[$element_name_2].'-'.$user_input[$element_name]; + } + + $test_empty = str_replace('-','',$target_input['element_date']); //if user not submitting any entry, remove the dashes + if(empty($test_empty)){ + unset($target_input['element_date']); + $table_data[$base_element_name] = ''; + } + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + + }elseif ('simple_phone' == $element_type){ //Simple Phone + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if(!empty($user_input[$element_name])){ + $rules[$element_name]['simple_phone'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $target_input[$element_name] = $user_input[$element_name]; + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + }elseif ('phone' == $element_type){ //Phone - US format + + if(!empty($processed_elements) && is_array($processed_elements) && in_array($element_name,$processed_elements)){ + continue; + } + + //compound element, grab the other element, 3 elements total + + $element_name_2 = substr($element_name,0,-1).'2'; + $element_name_3 = substr($element_name,0,-1).'3'; + + $processed_elements[] = $element_name_2; //put this element into array so that it won't be processed next + $processed_elements[] = $element_name_3; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + $rules[$element_name_2]['required'] = true; + $rules[$element_name_3]['required'] = true; + } + + $rules['element_phone']['phone'] = true; + + + if($element_info[$element_id]['is_unique']){ + $rules['element_phone']['unique'] = $form_id.'#'.substr($element_name,0,-2); + } + + $target_input[$element_name] = $user_input[$element_name]; + $target_input[$element_name_2] = $user_input[$element_name_2]; + $target_input[$element_name_3] = $user_input[$element_name_3]; + $target_input['element_phone'] = $user_input[$element_name].$user_input[$element_name_2].$user_input[$element_name_3]; + + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + $form_data[$element_name_2]['default_value'] = htmlspecialchars($user_input[$element_name_2]); + $form_data[$element_name_3]['default_value'] = htmlspecialchars($user_input[$element_name_3]); + + //prepare data for table column + $table_data[substr($element_name,0,-2)] = $user_input[$element_name].$user_input[$element_name_2].$user_input[$element_name_3]; + + }elseif ('email' == $element_type){ //Email + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required'] = true; + } + + if($element_info[$element_id]['is_unique']){ + $rules[$element_name]['unique'] = $form_id.'#'.$element_name; + } + + $rules[$element_name]['email'] = true; + + $target_input[$element_name] = $element_data; + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + } + + //save old data into array, for form redisplay in case errors occured + $form_data[$element_name]['default_value'] = htmlspecialchars($user_input[$element_name]); + + //prepare data for table column + $table_data[$element_name] = $user_input[$element_name]; + + }elseif ('file' == $element_type){ //File + //file upload field doesn't need to be required on edit mode + $element_info[$element_id]['is_required'] = false; + + if($element_info[$element_id]['is_required']){ + $rules[$element_name]['required_file'] = true; + } + + $target_input[$element_name] = $element_name; //special for file, only need to pass input name + $validation_result = validate_element($target_input,$rules); + + if($validation_result !== true){ + $error_elements[$element_id] = $validation_result; + }else{ + //if validation passed, store uploaded file info into array + if($_FILES[$element_name]['size'] > 0){ + $uploaded_files[] = $element_name; + } + } + + + } + + } + + + + + $process_result['old_values'] = $form_data; + $process_result['error_elements'] = $error_elements; + + $table_data['date_updated'] = date("Y-m-d H:i:s"); + + //start update data into table ---------------------- + //dynamically create the field list and field values, based on the input given + if(!empty($table_data) && empty($error_elements) && empty($process_result['custom_error'])){ + + //dynamically create the sql update string, based on the input given + $update_values = ''; + foreach ($table_data as $key=>$value){ + $value = mysql_real_escape_string($value); + $update_values .= "`$key`='$value',"; + } + $update_values = substr($update_values,0,-1); + + $query = "UPDATE `ap_form_{$form_id}` set + $update_values + where + id='{$entry_id}';"; + do_query($query); + } + //end update data into table ------------------------- + + + //upload the files + if(!empty($uploaded_files)){ + + foreach ($uploaded_files as $element_name){ + //remove old file if any + $query = "select $element_name from `ap_form_{$form_id}` where id='$entry_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + if(!empty($row[$element_name])){ + $old_filename = $row[$element_name]; + } + + $file_token = md5(uniqid(rand(), true)); //add random token to uploaded filename, to increase security + + //move new file and check for invalid file + $destination_file = UPLOAD_DIR."/form_{$form_id}/files/{$element_name}_{$file_token}-{$entry_id}-{$_FILES[$element_name]['name']}"; + if (move_uploaded_file($_FILES[$element_name]['tmp_name'], $destination_file)) { + $filename = mysql_real_escape_string($_FILES[$element_name]['name']); + $query = "update ap_form_{$form_id} set $element_name='{$element_name}_{$file_token}-{$entry_id}-{$filename}' where id='$entry_id'"; + do_query($query); + + //remove old file if any + if(!empty($old_filename)){ + @unlink(UPLOAD_DIR."/form_{$form_id}/files/".$old_filename); + } + } + } + } + + + + //if there is any error message or elements, send false as status + if(empty($error_elements) && empty($process_result['custom_error'])){ + $process_result['status'] = true; + }else{ + $process_result['status'] = false; + } + + + return $process_result; + } + + //process form review submit + //move the record from temporary review table to the actual table + function commit_form_review($form_id,$record_id,$options=array()){ + //move data from ap_form_x_review table to ap_form_x table + //get all column name except session_id and id + $query = "SELECT * FROM `ap_form_{$form_id}_review` WHERE id='$record_id'"; + $result = do_query($query); + + $i = 0; + $fields_num = mysql_num_fields($result); + $columns = array(); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + if(($meta->name != 'session_id') && ($meta->name != 'id')){ + $columns[] = $meta->name; + } + $i++; + } + + $columns_joined = implode("`,`",$columns); + $columns_joined = '`'.$columns_joined.'`'; + + //copy data from review table + $query = "INSERT INTO `ap_form_{$form_id}`($columns_joined) SELECT {$columns_joined} from `ap_form_{$form_id}_review` WHERE id='{$record_id}'"; + do_query($query); + + $new_record_id = mysql_insert_id(); + + //rename file uploads, if any + //get all file uploads elements first + $query = "SELECT + element_id + FROM + ap_form_elements + WHERE + form_id='{$form_id}' AND + element_type='file' AND + element_is_private=0"; + $result = do_query($query); + $file_uploads_array = array(); + while($row = do_fetch_result($result)){ + $file_uploads_array[] = 'element_'.$row['element_id']; + } + if(!empty($file_uploads_array)){ + $file_uploads_column = implode('`,`',$file_uploads_array); + $file_uploads_column = '`'.$file_uploads_column.'`'; + + $query = "SELECT {$file_uploads_column} FROM `ap_form_{$form_id}_review` where id='{$record_id}'"; + $result = do_query($query); + $row = do_fetch_result($result); + $file_update_query = ''; + + foreach ($file_uploads_array as $element_name){ + $filename = $row[$element_name]; + + if(empty($filename)){ + continue; + } + + $target_filename = $options['machform_data_path'].UPLOAD_DIR."/form_{$form_id}/files/{$filename}.tmp"; + + $regex = '/^element_([0-9]*)_([0-9a-zA-Z]*)-([0-9]*)-(.*)$/'; + $matches = array(); + preg_match($regex, $filename,$matches); + $filename_noelement = $matches[4]; + + $file_token = md5(uniqid(rand(), true)); //add random token to uploaded filename, to increase security + $destination_filename = $options['machform_data_path'].UPLOAD_DIR."/form_{$form_id}/files/{$element_name}_{$file_token}-{$new_record_id}-{$filename_noelement}"; + + if(file_exists($target_filename)){ + rename($target_filename,$destination_filename); + } + + //build update query + $filename_noelement = mysql_real_escape_string($filename_noelement); + $file_update_query .= "`{$element_name}`='{$element_name}_{$file_token}-{$new_record_id}-{$filename_noelement}',"; + } + + $file_update_query = rtrim($file_update_query,','); + if(!empty($file_update_query)){ + do_query("UPDATE `ap_form_{$form_id}` SET {$file_update_query} WHERE id='{$new_record_id}'"); + } + } + + //send notification emails + //get form properties data + $query = "select + form_redirect, + form_email, + esl_from_name, + esl_from_email_address, + esl_subject, + esl_content, + esl_plain_text, + esr_email_address, + esr_from_name, + esr_from_email_address, + esr_subject, + esr_content, + esr_plain_text + from + `ap_forms` + where + form_id='$form_id'"; + + $result = do_query($query); + $row = do_fetch_result($result); + $form_redirect = $row['form_redirect']; + $form_email = $row['form_email']; + + $esl_from_name = $row['esl_from_name']; + $esl_from_email_address = $row['esl_from_email_address']; + $esl_subject = $row['esl_subject']; + $esl_content = $row['esl_content']; + $esl_plain_text = $row['esl_plain_text']; + + $esr_email_address = $row['esr_email_address']; + $esr_from_name = $row['esr_from_name']; + $esr_from_email_address = $row['esr_from_email_address']; + $esr_subject = $row['esr_subject']; + $esr_content = $row['esr_content']; + $esr_plain_text = $row['esr_plain_text']; + + //start sending notification email to admin ------------------------------------------ + if(!empty($form_email)){ + //get parameters for the email + + //from name + if(!empty($esl_from_name)){ + $admin_email_param['from_name'] = $esl_from_name; + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $admin_email_param['from_name'] = NOTIFICATION_MAIL_FROM_NAME; + }else{ + $admin_email_param['from_name'] = 'MachForm'; + } + + //from email address + if(!empty($esl_from_email_address)){ + if(is_numeric($esl_from_email_address)){ + $admin_email_param['from_email'] = '{element_'.$esl_from_email_address.'}'; + }else{ + $admin_email_param['from_email'] = $esl_from_email_address; + } + }elseif(NOTIFICATION_MAIL_FROM != ''){ + $admin_email_param['from_email'] = NOTIFICATION_MAIL_FROM; + }else{ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $admin_email_param['from_email'] = "no-reply@{$domain}"; + } + + //subject + if(!empty($esl_subject)){ + $admin_email_param['subject'] = $esl_subject; + }elseif (NOTIFICATION_MAIL_SUBJECT != ''){ + $admin_email_param['subject'] = NOTIFICATION_MAIL_SUBJECT; + }else{ + $admin_email_param['subject'] = '{form_name} [#{entry_no}]'; + } + + //content + if(!empty($esl_content)){ + $admin_email_param['content'] = $esl_content; + }else{ + $admin_email_param['content'] = '{entry_data}'; + } + + $admin_email_param['as_plain_text'] = $esl_plain_text; + $admin_email_param['target_is_admin'] = true; + $admin_email_param['machform_base_path'] = $options['machform_base_path']; + + send_notification($form_id,$new_record_id,$form_email,$admin_email_param); + + } + //end emailing notifications to admin ---------------------------------------------- + + + //start sending notification email to user ------------------------------------------ + if(!empty($esr_email_address)){ + //get parameters for the email + + //to email + if(is_numeric($esr_email_address)){ + $esr_email_address = '{element_'.$esr_email_address.'}'; + } + + //from name + if(!empty($esr_from_name)){ + $user_email_param['from_name'] = $esr_from_name; + }elseif (NOTIFICATION_MAIL_FROM_NAME != ''){ + $user_email_param['from_name'] = NOTIFICATION_MAIL_FROM_NAME; + }else{ + $user_email_param['from_name'] = 'MachForm'; + } + + //from email address + if(!empty($esr_from_email_address)){ + if(is_numeric($esr_from_email_address)){ + $user_email_param['from_email'] = '{element_'.$esr_from_email_address.'}'; + }else{ + $user_email_param['from_email'] = $esr_from_email_address; + } + }elseif(NOTIFICATION_MAIL_FROM != ''){ + $user_email_param['from_email'] = NOTIFICATION_MAIL_FROM; + }else{ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $user_email_param['from_email'] = "no-reply@{$domain}"; + } + + //subject + if(!empty($esr_subject)){ + $user_email_param['subject'] = $esr_subject; + }elseif (NOTIFICATION_MAIL_SUBJECT != ''){ + $user_email_param['subject'] = NOTIFICATION_MAIL_SUBJECT; + }else{ + $user_email_param['subject'] = '{form_name} - Receipt'; + } + + //content + if(!empty($esr_content)){ + $user_email_param['content'] = $esr_content; + }else{ + $user_email_param['content'] = '{entry_data}'; + } + + $user_email_param['as_plain_text'] = $esr_plain_text; + $user_email_param['target_is_admin'] = false; + + send_notification($form_id,$new_record_id,$esr_email_address,$user_email_param); + } + //end emailing notifications to user ---------------------------------------------- + + //delete all entry from this user in review table + $session_id = session_id(); + do_query("DELETE FROM `ap_form_{$form_id}_review` where id='{$record_id}' or session_id='{$session_id}'"); + + $commit_result['form_redirect'] = $form_redirect; + + return $commit_result; + } +?> \ No newline at end of file diff --git a/includes/view-functions.php b/includes/view-functions.php new file mode 100644 index 0000000..4f118fa --- /dev/null +++ b/includes/view-functions.php @@ -0,0 +1,2495 @@ +is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for populated value, if exist, use it instead default_value + if(isset($element->populated_value['element_'.$element->id]['default_value'])){ + $element->default_value = $element->populated_value['element_'.$element->id]['default_value']; + } + + +$element_markup = << + +
    + +
    {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + + //Paragraph Text + function display_textarea($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for populated value, if exist, use it instead default_value + if(isset($element->populated_value['element_'.$element->id]['default_value'])){ + $element->default_value = $element->populated_value['element_'.$element->id]['default_value']; + } + +$element_markup = << + +
    + +
    {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + //File Upload + function display_file($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for populated value (this is being used for edit_entry.php only) + if(!empty($element->populated_value)){ + $file_option = $element->populated_value['element_'.$element->id]['default_value']; //this should be contain html markup to download or delete current file + } + +$element_markup = << + +
    + +
    {$file_option} {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + //Website + function display_url($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for default value + if(empty($element->default_value)){ + $element->default_value = 'http://'; + } + + //check for populated value, if exist, use it instead default_value + if(!empty($element->populated_value['element_'.$element->id]['default_value'])){ + $element->default_value = $element->populated_value['element_'.$element->id]['default_value']; + } + +$element_markup = << + +
    + +
    {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + //Email + function display_email($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for populated value, if exist, use it instead default_value + if(!empty($element->populated_value['element_'.$element->id]['default_value'])){ + $element->default_value = $element->populated_value['element_'.$element->id]['default_value']; + } + +$element_markup = << + +
    + +
    {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + //Phone - Extended + function display_phone($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check default value + if(!empty($element->default_value)){ + //split into (xxx) xxx - xxxx + $default_value_1 = substr($element->default_value,0,3); + $default_value_2 = substr($element->default_value,3,3); + $default_value_3 = substr($element->default_value,6,4); + } + + if(!empty($element->populated_value['element_'.$element->id.'_1']['default_value']) || + !empty($element->populated_value['element_'.$element->id.'_2']['default_value']) || + !empty($element->populated_value['element_'.$element->id.'_3']['default_value']) + ){ + $default_value_1 = ''; + $default_value_2 = ''; + $default_value_3 = ''; + $default_value_1 = $element->populated_value['element_'.$element->id.'_1']['default_value']; + $default_value_2 = $element->populated_value['element_'.$element->id.'_2']['default_value']; + $default_value_3 = $element->populated_value['element_'.$element->id.'_3']['default_value']; + } + + +$element_markup = << + + + - + + + + - + + + + + + + {$guidelines} {$error_message} + +EOT; + + + return $element_markup; + } + + //Phone - Simple + function display_simple_phone($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for populated value + if(!empty($element->populated_value['element_'.$element->id]['default_value'])){ + $element->default_value = $element->populated_value['element_'.$element->id]['default_value']; + } + +$element_markup = << + +
    + +
    {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + + //Date - Normal + function display_date($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + $machform_path = ''; + if(!empty($element->machform_path)){ + $machform_path = $element->machform_path; + } + + +$element_markup = << + + + / + + + + / + + + + + + + + + Pick a date. + + + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + //Date - Normal + function display_europe_date($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + $machform_path = ''; + if(!empty($element->machform_path)){ + $machform_path = $element->machform_path; + } + +$element_markup = << + + + / + + + + / + + + + + + + + + Pick a date. + + + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + //Multiple Choice + function display_radio($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + $option_markup = ''; + + if($element->constraint == 'random'){ + $temp = $element->options; + shuffle($temp); + $element->options = $temp; + } + + foreach ($element->options as $option){ + + if($option->is_default){ + $checked = 'checked="checked"'; + }else{ + $checked = ''; + } + + //check for populated values + if(!empty($element->populated_value['element_'.$element->id]['default_value'])){ + $checked = ''; + if($element->populated_value['element_'.$element->id]['default_value'] == $option->id){ + $checked = 'checked="checked"'; + } + } + + $option_markup .= "id}_{$option->id}\" name=\"element_{$element->id}\" class=\"element radio\" type=\"radio\" value=\"{$option->id}\" {$checked} />\n"; + $option_markup .= "\n"; + } + +$element_markup = << + + + {$option_markup} + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + //Checkboxes + function display_checkbox($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for populated value first, if any exist, unselect all default value + $is_populated = false; + foreach ($element->options as $option){ + + if(!empty($element->populated_value['element_'.$element->id.'_'.$option->id]['default_value'])){ + $is_populated = true; + break; + } + } + + $option_markup = ''; + + foreach ($element->options as $option){ + if(!$is_populated){ + if($option->is_default){ + $checked = 'checked="checked"'; + }else{ + $checked = ''; + } + }else{ + + if(!empty($element->populated_value['element_'.$element->id.'_'.$option->id]['default_value'])){ + $checked = 'checked="checked"'; + }else{ + $checked = ''; + } + } + + + + $option_markup .= "id}_{$option->id}\" name=\"element_{$element->id}_{$option->id}\" class=\"element checkbox\" type=\"checkbox\" value=\"1\" {$checked} />\n"; + $option_markup .= "\n"; + } + +$element_markup = << + + + {$option_markup} + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + //Dropdown + function display_select($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + $option_markup = ''; + + $has_default = false; + foreach ($element->options as $option){ + + if($option->is_default){ + $selected = 'selected="selected"'; + $has_default = true; + }else{ + $selected = ''; + } + + if(!empty($element->populated_value['element_'.$element->id]['default_value'])){ + $selected = ''; + if($element->populated_value['element_'.$element->id]['default_value'] == $option->id){ + $selected = 'selected="selected"'; + } + } + + $option_markup .= "\n"; + } + + if(!$has_default){ + if(!empty($element->populated_value['element_'.$element->id]['default_value'])){ + $option_markup = ''."\n".$option_markup; + }else{ + $option_markup = ''."\n".$option_markup; + } + } + +$element_markup = << + +
    + +
    {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + //Name - Simple + function display_simple_name($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + +$element_markup = << + + + + + + + + + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + //Name + function display_name($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + +$element_markup = << + + + + + + + + + + + + + + + + + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + //Time + function display_time($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + if(!empty($element->populated_value['element_'.$element->id.'_4']['default_value'])){ + if($element->populated_value['element_'.$element->id.'_4']['default_value'] == 'AM'){ + $selected_am = 'selected'; + }else{ + $selected_pm = 'selected'; + } + } + + if($element->constraint == 'show_seconds'){ + $seconds_markup =<< + + + +EOT; + $seconds_separator = ':'; + }else{ + $seconds_markup = ''; + $seconds_separator = ''; + } + +$element_markup = << + + + : + + + + {$seconds_separator} + + + {$seconds_markup} + + + + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + //Price + function display_money($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + if($element->constraint != 'yen'){ //for dollar, pound and euro + if($element->constraint == 'pound'){ + $main_cur = $lang['price_pound_main']; + $child_cur = $lang['price_pound_sub']; + $cur_symbol = '£'; + }elseif ($element->constraint == 'euro'){ + $main_cur = $lang['price_euro_main']; + $child_cur = $lang['price_euro_sub']; + $cur_symbol = '€'; + }else{ //dollar + $main_cur = $lang['price_dollar_main']; + $child_cur = $lang['price_dollar_sub']; + $cur_symbol = '$'; + } + +$element_markup = << + + {$cur_symbol} + + . + + + + + + + {$guidelines} {$error_message} + +EOT; + + }else{ //for yen, only display one textfield + $main_cur = $lang['price_yen']; + $cur_symbol = '¥'; + +$element_markup = << + + {$cur_symbol} + + + + + {$guidelines} {$error_message} + +EOT; + + } + + + + return $element_markup; + } + + //Section Break + function display_section($element){ + $element->guidelines = nl2br($element->guidelines); +$element_markup = << +

    {$element->title}

    +

    {$element->guidelines}

    + +EOT; + + return $element_markup; + } + + + + //Number + function display_number($element){ + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + //check for populated value, if exist, use it instead default_value + if(isset($element->populated_value['element_'.$element->id]['default_value'])){ + $element->default_value = $element->populated_value['element_'.$element->id]['default_value']; + } + +$element_markup = << + +
    + +
    {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + + //Address + function display_address($element){ + + $country[0]['label'] = "Afghanistan"; + $country[1]['label'] = "Albania"; + $country[2]['label'] = "Algeria"; + $country[3]['label'] = "Andorra"; + $country[4]['label'] = "Antigua and Barbuda"; + $country[5]['label'] = "Argentina"; + $country[6]['label'] = "Armenia"; + $country[7]['label'] = "Australia"; + $country[8]['label'] = "Austria"; + $country[9]['label'] = "Azerbaijan"; + $country[10]['label'] = "Bahamas"; + $country[11]['label'] = "Bahrain"; + $country[12]['label'] = "Bangladesh"; + $country[13]['label'] = "Barbados"; + $country[14]['label'] = "Belarus"; + $country[15]['label'] = "Belgium"; + $country[16]['label'] = "Belize"; + $country[17]['label'] = "Benin"; + $country[18]['label'] = "Bhutan"; + $country[19]['label'] = "Bolivia"; + $country[20]['label'] = "Bosnia and Herzegovina"; + $country[21]['label'] = "Botswana"; + $country[22]['label'] = "Brazil"; + $country[23]['label'] = "Brunei"; + $country[24]['label'] = "Bulgaria"; + $country[25]['label'] = "Burkina Faso"; + $country[26]['label'] = "Burundi"; + $country[27]['label'] = "Cambodia"; + $country[28]['label'] = "Cameroon"; + $country[29]['label'] = "Canada"; + $country[30]['label'] = "Cape Verde"; + $country[31]['label'] = "Central African Republic"; + $country[32]['label'] = "Chad"; + $country[33]['label'] = "Chile"; + $country[34]['label'] = "China"; + $country[35]['label'] = "Colombia"; + $country[36]['label'] = "Comoros"; + $country[37]['label'] = "Congo"; + $country[38]['label'] = "Costa Rica"; + $country[39]['label'] = "Côte d'Ivoire"; + $country[40]['label'] = "Croatia"; + $country[41]['label'] = "Cuba"; + $country[42]['label'] = "Cyprus"; + $country[43]['label'] = "Czech Republic"; + $country[44]['label'] = "Denmark"; + $country[45]['label'] = "Djibouti"; + $country[46]['label'] = "Dominica"; + $country[47]['label'] = "Dominican Republic"; + $country[48]['label'] = "East Timor"; + $country[49]['label'] = "Ecuador"; + $country[50]['label'] = "Egypt"; + $country[51]['label'] = "El Salvador"; + $country[52]['label'] = "Equatorial Guinea"; + $country[53]['label'] = "Eritrea"; + $country[54]['label'] = "Estonia"; + $country[55]['label'] = "Ethiopia"; + $country[56]['label'] = "Fiji"; + $country[57]['label'] = "Finland"; + $country[58]['label'] = "France"; + $country[59]['label'] = "Gabon"; + $country[60]['label'] = "Gambia"; + $country[61]['label'] = "Georgia"; + $country[62]['label'] = "Germany"; + $country[63]['label'] = "Ghana"; + $country[64]['label'] = "Greece"; + $country[65]['label'] = "Grenada"; + $country[66]['label'] = "Guatemala"; + $country[67]['label'] = "Guinea"; + $country[68]['label'] = "Guinea-Bissau"; + $country[69]['label'] = "Guyana"; + $country[70]['label'] = "Haiti"; + $country[71]['label'] = "Honduras"; + $country[72]['label'] = "Hong Kong"; + $country[73]['label'] = "Hungary"; + $country[74]['label'] = "Iceland"; + $country[75]['label'] = "India"; + $country[76]['label'] = "Indonesia"; + $country[77]['label'] = "Iran"; + $country[78]['label'] = "Iraq"; + $country[79]['label'] = "Ireland"; + $country[80]['label'] = "Israel"; + $country[81]['label'] = "Italy"; + $country[82]['label'] = "Jamaica"; + $country[83]['label'] = "Japan"; + $country[84]['label'] = "Jordan"; + $country[85]['label'] = "Kazakhstan"; + $country[86]['label'] = "Kenya"; + $country[87]['label'] = "Kiribati"; + $country[88]['label'] = "North Korea"; + $country[89]['label'] = "South Korea"; + $country[90]['label'] = "Kuwait"; + $country[91]['label'] = "Kyrgyzstan"; + $country[92]['label'] = "Laos"; + $country[93]['label'] = "Latvia"; + $country[94]['label'] = "Lebanon"; + $country[95]['label'] = "Lesotho"; + $country[96]['label'] = "Liberia"; + $country[97]['label'] = "Libya"; + $country[98]['label'] = "Liechtenstein"; + $country[99]['label'] = "Lithuania"; + $country[100]['label'] = "Luxembourg"; + $country[101]['label'] = "Macedonia"; + $country[102]['label'] = "Madagascar"; + $country[103]['label'] = "Malawi"; + $country[104]['label'] = "Malaysia"; + $country[105]['label'] = "Maldives"; + $country[106]['label'] = "Mali"; + $country[107]['label'] = "Malta"; + $country[108]['label'] = "Marshall Islands"; + $country[109]['label'] = "Mauritania"; + $country[110]['label'] = "Mauritius"; + $country[111]['label'] = "Mexico"; + $country[112]['label'] = "Micronesia"; + $country[113]['label'] = "Moldova"; + $country[114]['label'] = "Monaco"; + $country[115]['label'] = "Mongolia"; + $country[116]['label'] = "Montenegro"; + $country[117]['label'] = "Morocco"; + $country[118]['label'] = "Mozambique"; + $country[119]['label'] = "Myanmar"; + $country[120]['label'] = "Namibia"; + $country[121]['label'] = "Nauru"; + $country[122]['label'] = "Nepal"; + $country[123]['label'] = "Netherlands"; + $country[124]['label'] = "New Zealand"; + $country[125]['label'] = "Nicaragua"; + $country[126]['label'] = "Niger"; + $country[127]['label'] = "Nigeria"; + $country[128]['label'] = "Norway"; + $country[129]['label'] = "Oman"; + $country[130]['label'] = "Pakistan"; + $country[131]['label'] = "Palau"; + $country[132]['label'] = "Panama"; + $country[133]['label'] = "Papua New Guinea"; + $country[134]['label'] = "Paraguay"; + $country[135]['label'] = "Peru"; + $country[136]['label'] = "Philippines"; + $country[137]['label'] = "Poland"; + $country[138]['label'] = "Portugal"; + $country[139]['label'] = "Puerto Rico"; + $country[140]['label'] = "Qatar"; + $country[141]['label'] = "Romania"; + $country[142]['label'] = "Russia"; + $country[143]['label'] = "Rwanda"; + $country[144]['label'] = "Saint Kitts and Nevis"; + $country[145]['label'] = "Saint Lucia"; + $country[146]['label'] = "Saint Vincent and the Grenadines"; + $country[147]['label'] = "Samoa"; + $country[148]['label'] = "San Marino"; + $country[149]['label'] = "Sao Tome and Principe"; + $country[150]['label'] = "Saudi Arabia"; + $country[151]['label'] = "Senegal"; + $country[152]['label'] = "Serbia and Montenegro"; + $country[153]['label'] = "Seychelles"; + $country[154]['label'] = "Sierra Leone"; + $country[155]['label'] = "Singapore"; + $country[156]['label'] = "Slovakia"; + $country[157]['label'] = "Slovenia"; + $country[158]['label'] = "Solomon Islands"; + $country[159]['label'] = "Somalia"; + $country[160]['label'] = "South Africa"; + $country[161]['label'] = "Spain"; + $country[162]['label'] = "Sri Lanka"; + $country[163]['label'] = "Sudan"; + $country[164]['label'] = "Suriname"; + $country[165]['label'] = "Swaziland"; + $country[166]['label'] = "Sweden"; + $country[167]['label'] = "Switzerland"; + $country[168]['label'] = "Syria"; + $country[169]['label'] = "Taiwan"; + $country[170]['label'] = "Tajikistan"; + $country[171]['label'] = "Tanzania"; + $country[172]['label'] = "Thailand"; + $country[173]['label'] = "Togo"; + $country[174]['label'] = "Tonga"; + $country[175]['label'] = "Trinidad and Tobago"; + $country[176]['label'] = "Tunisia"; + $country[177]['label'] = "Turkey"; + $country[178]['label'] = "Turkmenistan"; + $country[179]['label'] = "Tuvalu"; + $country[180]['label'] = "Uganda"; + $country[181]['label'] = "Ukraine"; + $country[182]['label'] = "United Arab Emirates"; + $country[183]['label'] = "United Kingdom"; + $country[184]['label'] = "United States"; + $country[185]['label'] = "Uruguay"; + $country[186]['label'] = "Uzbekistan"; + $country[187]['label'] = "Vanuatu"; + $country[188]['label'] = "Vatican City"; + $country[189]['label'] = "Venezuela"; + $country[190]['label'] = "Vietnam"; + $country[191]['label'] = "Yemen"; + $country[192]['label'] = "Zambia"; + $country[193]['label'] = "Zimbabwe"; + + + $country[0]['value'] = "Afghanistan"; + $country[1]['value'] = "Albania"; + $country[2]['value'] = "Algeria"; + $country[3]['value'] = "Andorra"; + $country[4]['value'] = "Antigua and Barbuda"; + $country[5]['value'] = "Argentina"; + $country[6]['value'] = "Armenia"; + $country[7]['value'] = "Australia"; + $country[8]['value'] = "Austria"; + $country[9]['value'] = "Azerbaijan"; + $country[10]['value'] = "Bahamas"; + $country[11]['value'] = "Bahrain"; + $country[12]['value'] = "Bangladesh"; + $country[13]['value'] = "Barbados"; + $country[14]['value'] = "Belarus"; + $country[15]['value'] = "Belgium"; + $country[16]['value'] = "Belize"; + $country[17]['value'] = "Benin"; + $country[18]['value'] = "Bhutan"; + $country[19]['value'] = "Bolivia"; + $country[20]['value'] = "Bosnia and Herzegovina"; + $country[21]['value'] = "Botswana"; + $country[22]['value'] = "Brazil"; + $country[23]['value'] = "Brunei"; + $country[24]['value'] = "Bulgaria"; + $country[25]['value'] = "Burkina Faso"; + $country[26]['value'] = "Burundi"; + $country[27]['value'] = "Cambodia"; + $country[28]['value'] = "Cameroon"; + $country[29]['value'] = "Canada"; + $country[30]['value'] = "Cape Verde"; + $country[31]['value'] = "Central African Republic"; + $country[32]['value'] = "Chad"; + $country[33]['value'] = "Chile"; + $country[34]['value'] = "China"; + $country[35]['value'] = "Colombia"; + $country[36]['value'] = "Comoros"; + $country[37]['value'] = "Congo"; + $country[38]['value'] = "Costa Rica"; + $country[39]['value'] = "Côte d'Ivoire"; + $country[40]['value'] = "Croatia"; + $country[41]['value'] = "Cuba"; + $country[42]['value'] = "Cyprus"; + $country[43]['value'] = "Czech Republic"; + $country[44]['value'] = "Denmark"; + $country[45]['value'] = "Djibouti"; + $country[46]['value'] = "Dominica"; + $country[47]['value'] = "Dominican Republic"; + $country[48]['value'] = "East Timor"; + $country[49]['value'] = "Ecuador"; + $country[50]['value'] = "Egypt"; + $country[51]['value'] = "El Salvador"; + $country[52]['value'] = "Equatorial Guinea"; + $country[53]['value'] = "Eritrea"; + $country[54]['value'] = "Estonia"; + $country[55]['value'] = "Ethiopia"; + $country[56]['value'] = "Fiji"; + $country[57]['value'] = "Finland"; + $country[58]['value'] = "France"; + $country[59]['value'] = "Gabon"; + $country[60]['value'] = "Gambia"; + $country[61]['value'] = "Georgia"; + $country[62]['value'] = "Germany"; + $country[63]['value'] = "Ghana"; + $country[64]['value'] = "Greece"; + $country[65]['value'] = "Grenada"; + $country[66]['value'] = "Guatemala"; + $country[67]['value'] = "Guinea"; + $country[68]['value'] = "Guinea-Bissau"; + $country[69]['value'] = "Guyana"; + $country[70]['value'] = "Haiti"; + $country[71]['value'] = "Honduras"; + $country[72]['value'] = "Hong Kong"; + $country[73]['value'] = "Hungary"; + $country[74]['value'] = "Iceland"; + $country[75]['value'] = "India"; + $country[76]['value'] = "Indonesia"; + $country[77]['value'] = "Iran"; + $country[78]['value'] = "Iraq"; + $country[79]['value'] = "Ireland"; + $country[80]['value'] = "Israel"; + $country[81]['value'] = "Italy"; + $country[82]['value'] = "Jamaica"; + $country[83]['value'] = "Japan"; + $country[84]['value'] = "Jordan"; + $country[85]['value'] = "Kazakhstan"; + $country[86]['value'] = "Kenya"; + $country[87]['value'] = "Kiribati"; + $country[88]['value'] = "North Korea"; + $country[89]['value'] = "South Korea"; + $country[90]['value'] = "Kuwait"; + $country[91]['value'] = "Kyrgyzstan"; + $country[92]['value'] = "Laos"; + $country[93]['value'] = "Latvia"; + $country[94]['value'] = "Lebanon"; + $country[95]['value'] = "Lesotho"; + $country[96]['value'] = "Liberia"; + $country[97]['value'] = "Libya"; + $country[98]['value'] = "Liechtenstein"; + $country[99]['value'] = "Lithuania"; + $country[100]['value'] = "Luxembourg"; + $country[101]['value'] = "Macedonia"; + $country[102]['value'] = "Madagascar"; + $country[103]['value'] = "Malawi"; + $country[104]['value'] = "Malaysia"; + $country[105]['value'] = "Maldives"; + $country[106]['value'] = "Mali"; + $country[107]['value'] = "Malta"; + $country[108]['value'] = "Marshall Islands"; + $country[109]['value'] = "Mauritania"; + $country[110]['value'] = "Mauritius"; + $country[111]['value'] = "Mexico"; + $country[112]['value'] = "Micronesia"; + $country[113]['value'] = "Moldova"; + $country[114]['value'] = "Monaco"; + $country[115]['value'] = "Mongolia"; + $country[116]['value'] = "Montenegro"; + $country[117]['value'] = "Morocco"; + $country[118]['value'] = "Mozambique"; + $country[119]['value'] = "Myanmar"; + $country[120]['value'] = "Namibia"; + $country[121]['value'] = "Nauru"; + $country[122]['value'] = "Nepal"; + $country[123]['value'] = "Netherlands"; + $country[124]['value'] = "New Zealand"; + $country[125]['value'] = "Nicaragua"; + $country[126]['value'] = "Niger"; + $country[127]['value'] = "Nigeria"; + $country[128]['value'] = "Norway"; + $country[129]['value'] = "Oman"; + $country[130]['value'] = "Pakistan"; + $country[131]['value'] = "Palau"; + $country[132]['value'] = "Panama"; + $country[133]['value'] = "Papua New Guinea"; + $country[134]['value'] = "Paraguay"; + $country[135]['value'] = "Peru"; + $country[136]['value'] = "Philippines"; + $country[137]['value'] = "Poland"; + $country[138]['value'] = "Portugal"; + $country[139]['value'] = "Puerto Rico"; + $country[140]['value'] = "Qatar"; + $country[141]['value'] = "Romania"; + $country[142]['value'] = "Russia"; + $country[143]['value'] = "Rwanda"; + $country[144]['value'] = "Saint Kitts and Nevis"; + $country[145]['value'] = "Saint Lucia"; + $country[146]['value'] = "Saint Vincent and the Grenadines"; + $country[147]['value'] = "Samoa"; + $country[148]['value'] = "San Marino"; + $country[149]['value'] = "Sao Tome and Principe"; + $country[150]['value'] = "Saudi Arabia"; + $country[151]['value'] = "Senegal"; + $country[152]['value'] = "Serbia and Montenegro"; + $country[153]['value'] = "Seychelles"; + $country[154]['value'] = "Sierra Leone"; + $country[155]['value'] = "Singapore"; + $country[156]['value'] = "Slovakia"; + $country[157]['value'] = "Slovenia"; + $country[158]['value'] = "Solomon Islands"; + $country[159]['value'] = "Somalia"; + $country[160]['value'] = "South Africa"; + $country[161]['value'] = "Spain"; + $country[162]['value'] = "Sri Lanka"; + $country[163]['value'] = "Sudan"; + $country[164]['value'] = "Suriname"; + $country[165]['value'] = "Swaziland"; + $country[166]['value'] = "Sweden"; + $country[167]['value'] = "Switzerland"; + $country[168]['value'] = "Syria"; + $country[169]['value'] = "Taiwan"; + $country[170]['value'] = "Tajikistan"; + $country[171]['value'] = "Tanzania"; + $country[172]['value'] = "Thailand"; + $country[173]['value'] = "Togo"; + $country[174]['value'] = "Tonga"; + $country[175]['value'] = "Trinidad and Tobago"; + $country[176]['value'] = "Tunisia"; + $country[177]['value'] = "Turkey"; + $country[178]['value'] = "Turkmenistan"; + $country[179]['value'] = "Tuvalu"; + $country[180]['value'] = "Uganda"; + $country[181]['value'] = "Ukraine"; + $country[182]['value'] = "United Arab Emirates"; + $country[183]['value'] = "United Kingdom"; + $country[184]['value'] = "United States"; + $country[185]['value'] = "Uruguay"; + $country[186]['value'] = "Uzbekistan"; + $country[187]['value'] = "Vanuatu"; + $country[188]['value'] = "Vatican City"; + $country[189]['value'] = "Venezuela"; + $country[190]['value'] = "Vietnam"; + $country[191]['value'] = "Yemen"; + $country[192]['value'] = "Zambia"; + $country[193]['value'] = "Zimbabwe"; + + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + //check for required + if($element->is_required){ + $span_required = "id}\" class=\"required\">*"; + } + + //check for guidelines + if(!empty($element->guidelines)){ + $guidelines = "

    id}\">{$element->guidelines}

    "; + } + + + //create country markup, if no default value, provide a blank option + if(empty($element->default_value)){ + $country_markup = ''."\n"; + }else{ + $country_markup = ''; + } + + foreach ($country as $data){ + if($data['value'] == $element->default_value){ + $selected = 'selected="selected"'; + }else{ + $selected = ''; + } + + //check for populated value, use it instead of default value + if(!empty($element->populated_value['element_'.$element->id.'_6']['default_value'])){ + $selected = ''; + if($element->populated_value['element_'.$element->id.'_6']['default_value'] == $data['value']){ + $selected = 'selected="selected"'; + } + } + + $country_markup .= "\n"; + } + +$element_markup = << + + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
     {$guidelines} {$error_message} + +EOT; + + + return $element_markup; + } + + + //Captcha + function display_captcha($element){ + + if(!empty($element->error_message)){ + $error_code = $element->error_message; + }else{ + $error_code = ''; + } + + //check for error + $error_class = ''; + $error_message = ''; + $span_required = ''; + $guidelines = ''; + global $lang; + + if(!empty($element->is_error)){ + + if($element->error_message == 'el-required'){ + $element->error_message = $lang['captcha_required']; + $error_code = ''; + }elseif ($element->error_message == 'incorrect-captcha-sol'){ + $element->error_message = $lang['captcha_mismatch']; + }else{ + $element->error_message = "{$lang['captcha_error']} ({$element->error_message})"; + } + + $error_class = 'class="error"'; + $error_message = "

    {$element->error_message}

    "; + } + + if(!empty($_SERVER['HTTPS'])){ + $use_ssl = true; + }else{ + $use_ssl = false; + } + + + if(USE_INTERNAL_CAPTCHA === true){ //use the internal captcha if enabled + + $machform_path = ''; + if(!empty($element->machform_path)){ + $machform_path = $element->machform_path; + } + + $timestamp = time(); //use this as paramater for captcha.php, to prevent caching + + $element->title = $lang['captcha_title']; +$captcha_html = <<
    +
    +EOT; + + }else{ //otherwise use the reCAPTCHA + $captcha_html = recaptcha_get_html(RECAPTCHA_PUBLIC_KEY, $error_code,$use_ssl); + + if($captcha_html === false){ + $domain = str_replace('www.','',$_SERVER['SERVER_NAME']); + $captcha_html = "Error! You have enabled CAPTCHA but no API key available.

    To use CAPTCHA you must get an API key from http://recaptcha.net/api/getkey

    After getting the API key, save them into your config.php file."; + $error_class = 'class="error"'; + } + } + + + if(function_exists("form{$element->form_id}_hook_pre_captcha")){ + $custom_precaptcha = call_user_func("form{$element->form_id}_hook_pre_captcha"); + } + +$element_markup = << {$custom_precaptcha} + +
    + {$captcha_html} +
    + {$guidelines} {$error_message} + +EOT; + + return $element_markup; + } + + + //Main function to display a form + //There are few mode when displaying a form + //1. New blank form (form populated with default values) + //2. New form with error (displayed when 1 submitted and having error, form populated with user inputs) + //3. Edit form (form populated with data from db) + //4. Edit form with error (displayed when 3 submiteed and having error) + function display_form($form_id,$populated_values=array(),$error_elements=array(),$custom_error='',$edit_id=0,$embed=false){ + + global $lang; + + //if there is custom error, don't show other errors + if(!empty($custom_error)){ + $error_elements = array(); + } + + //get form properties data + $query = "select + form_name, + form_description, + form_redirect, + form_success_message, + form_password, + form_unique_ip, + form_frame_height, + form_has_css, + form_active, + form_captcha, + form_review + from + ap_forms + where + form_id='$form_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + + $form = new stdClass(); + + $form->id = $form_id; + $form->name = $row['form_name']; + $form->description = $row['form_description']; + $form->redirect = $row['form_redirect']; + $form->success_message = $row['form_success_message']; + $form->password = $row['form_password']; + $form->frame_height = $row['form_frame_height']; + $form->unique_ip = $row['form_unique_ip']; + $form->has_css = $row['form_has_css']; + $form->active = $row['form_active']; + $form->captcha = $row['form_captcha']; + $form->review = $row['form_review']; + + if(empty($error_elements)){ + $form->is_error = 0; + }else{ + $form->is_error = 1; + } + + //if this form has review enabled and user are having $_SESSION['review_id'], then populate the form with that values + if(!empty($form->review) && !empty($_SESSION['review_id']) && empty($populated_values)){ + $populated_values = get_entry_values($form_id,$_SESSION['review_id'],true); + } + + //get elements data + //get element options first and store it into array + $query = "select + element_id, + option_id, + `position`, + `option`, + option_is_default + from + ap_element_options + where + form_id='$form_id' and live=1 + order by + element_id asc,`position` asc"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $option_id = $row['option_id']; + $options_lookup[$element_id][$option_id]['position'] = $row['position']; + $options_lookup[$element_id][$option_id]['option'] = $row['option']; + $options_lookup[$element_id][$option_id]['option_is_default'] = $row['option_is_default']; + } + + + //get elements data + $element = array(); + $query = "select + element_id, + element_title, + element_guidelines, + element_size, + element_is_required, + element_is_unique, + element_is_private, + element_type, + element_position, + element_default_value, + element_constraint + from + ap_form_elements + where + form_id='$form_id' + order by + element_position asc"; + $result = do_query($query); + + $j=0; + $has_calendar = false; //assume the form doesn't have calendar, so it won't load calendar.js + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + + //lookup element options first + if(!empty($options_lookup[$element_id])){ + $element_options = array(); + $i=0; + foreach ($options_lookup[$element_id] as $option_id=>$data){ + $element_options[$i] = new stdClass(); + $element_options[$i]->id = $option_id; + $element_options[$i]->option = $data['option']; + $element_options[$i]->is_default = $data['option_is_default']; + $element_options[$i]->is_db_live = 1; + $i++; + } + } + + + //populate elements + $element[$j] = new stdClass(); + $element[$j]->title = nl2br($row['element_title']); + $element[$j]->guidelines = $row['element_guidelines']; + $element[$j]->size = $row['element_size']; + $element[$j]->is_required = $row['element_is_required']; + $element[$j]->is_unique = $row['element_is_unique']; + $element[$j]->is_private = $row['element_is_private']; + $element[$j]->type = $row['element_type']; + $element[$j]->position = $row['element_position']; + $element[$j]->id = $row['element_id']; + $element[$j]->is_db_live = 1; + + //this data came from db or form submit + //being used to display edit form or redisplay form with errors and previous inputs + //this should be optimized in the future, only pass necessary data, not the whole array + $element[$j]->populated_value = $populated_values; + + //if there is file upload type, set form enctype to multipart + if($row['element_type'] == 'file'){ + $form_enc_type = 'enctype="multipart/form-data"'; + } + + if(!empty($error_elements[$element[$j]->id])){ + $element[$j]->is_error = 1; + $element[$j]->error_message = $error_elements[$element[$j]->id]; + } + + + $element[$j]->default_value = htmlspecialchars($row['element_default_value']); + + + $element[$j]->constraint = $row['element_constraint']; + if(!empty($element_options)){ + $element[$j]->options = $element_options; + }else{ + $element[$j]->options = ''; + } + + + //check for calendar type + if($row['element_type'] == 'date' || $row['element_type'] == 'europe_date'){ + $has_calendar = true; + } + + $j++; + } + + + //add captcha if enable + if(!empty($form->captcha) && (empty($edit_id))){ + $element[$j] = new stdClass(); + $element[$j]->type = 'captcha'; + $element[$j]->form_id = $form_id; + $element[$j]->is_private = 0; + + if(!empty($error_elements['element_captcha'])){ + $element[$j]->is_error = 1; + $element[$j]->error_message = $error_elements['element_captcha']; + } + } + + //generate html markup for each element + $all_element_markup = ''; + foreach ($element as $element_data){ + if($element_data->is_private && empty($_SESSION['logged_in'])){ //don't show private element + continue; + } + $all_element_markup .= call_user_func('display_'.$element_data->type,$element_data); + } + + if(!empty($custom_error)){ + $form->error_message =<< +

    {$custom_error}

    + +EOT; + }elseif(!empty($error_elements)){ + $form->error_message =<< +

    {$lang['error_title']}

    +

    {$lang['error_desc']}

    + +EOT; + } + + + //display edit_id if there is any + if(!empty($edit_id)){ + $edit_markup = "\n"; + }else{ + $edit_markup = ''; + } + + if(empty($form->review)){ + $button_text = $lang['submit_button']; + }else{ + $button_text = $lang['continue_button']; + } + + //markup for submit button + $button_markup =<< + + {$edit_markup} + + + +EOT; + + //check for specific form css, if any, use it instead + if($form->has_css){ + $css_dir = DATA_DIR."/form_{$form_id}/css/"; + } + + if(!empty($form->password) && empty($_SESSION['user_authenticated'])){ //if form require password and password hasn't set yet + $show_password_form = true; + + }elseif (!empty($form->password) && !empty($_SESSION['user_authenticated']) && $_SESSION['user_authenticated'] != $form_id){ //if user authenticated but not for this form + $show_password_form = true; + + }else{ //user authenticated for this form, or no password required + $show_password_form = false; + } + + + if(empty($form->active)){ //if form is not active, don't show the fields + $form_desc_div =''; + $all_element_markup = ''; + $button_markup = ''; + $ul_class = 'class="password"'; + $custom_element =<< +

    {$lang['form_inactive']}

    + +EOT; + }elseif($show_password_form){ //don't show form description if this page is password protected and user not authenticated + $form_desc_div =''; + $all_element_markup = ''; + $custom_element =<< +

    {$lang['form_pass_title']}

    +
    + + +
    + +EOT; + $ul_class = 'class="password"'; + }else{ + if(!empty($form->name) || !empty($form->description)){ + $form->description = nl2br($form->description); + $form_desc_div =<< +

    {$form->name}

    +

    {$form->description}

    +
    +EOT; + } + } + + if($embed){ + $embed_class = 'class="embed"'; + } + + if($has_calendar){ + $calendar_js = ''; + }else{ + $calendar_js = ''; + } + + //If you would like to remove the "Powered by MachForm" link, please contact us at customer.service@appnitro.com before doing so + $form_markup = << + + + +{$form->name} + + +{$calendar_js} + + + + +
    + +

    {$form->name}

    +
    + {$form_desc_div} +
      + {$form->error_message} + {$all_element_markup} + {$custom_element} + {$button_markup} +
    +
    + +
    + + + +EOT; + return $form_markup; + + } + + //this function is similar as display_form, but designed to display form without IFRAME + function display_integrated_form($form_id,$populated_values=array(),$error_elements=array(),$custom_error='',$edit_id=0,$machform_path){ + + global $lang; + + //if there is custom error, don't show other errors + if(!empty($custom_error)){ + $error_elements = array(); + } + + //get form properties data + $query = "select + form_name, + form_description, + form_redirect, + form_success_message, + form_password, + form_unique_ip, + form_frame_height, + form_has_css, + form_active, + form_captcha, + form_review + from + ap_forms + where + form_id='$form_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + + $form = new stdClass(); + + $form->id = $form_id; + $form->name = $row['form_name']; + $form->description = $row['form_description']; + $form->redirect = $row['form_redirect']; + $form->success_message = $row['form_success_message']; + $form->password = $row['form_password']; + $form->frame_height = $row['form_frame_height']; + $form->unique_ip = $row['form_unique_ip']; + $form->has_css = $row['form_has_css']; + $form->active = $row['form_active']; + $form->captcha = $row['form_captcha']; + $form->review = $row['form_review']; + + if(empty($error_elements)){ + $form->is_error = 0; + }else{ + $form->is_error = 1; + } + + //if this form has review enabled and user are having $_SESSION['review_id'], then populate the form with that values + if(!empty($form->review) && !empty($_SESSION['review_id']) && empty($populated_values)){ + $param['machform_path'] = $machform_path; + $populated_values = get_entry_values($form_id,$_SESSION['review_id'],true,$param); + } + + //get elements data + //get element options first and store it into array + $query = "select + element_id, + option_id, + `position`, + `option`, + option_is_default + from + ap_element_options + where + form_id='$form_id' and live=1 + order by + element_id asc,`position` asc"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $option_id = $row['option_id']; + $options_lookup[$element_id][$option_id]['position'] = $row['position']; + $options_lookup[$element_id][$option_id]['option'] = $row['option']; + $options_lookup[$element_id][$option_id]['option_is_default'] = $row['option_is_default']; + } + + + //get elements data + $element = array(); + $query = "select + element_id, + element_title, + element_guidelines, + element_size, + element_is_required, + element_is_unique, + element_is_private, + element_type, + element_position, + element_default_value, + element_constraint + from + ap_form_elements + where + form_id='$form_id' + order by + element_position asc"; + $result = do_query($query); + + $j=0; + $has_calendar = false; + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + + //lookup element options first + if(!empty($options_lookup[$element_id])){ + $element_options = array(); + $i=0; + foreach ($options_lookup[$element_id] as $option_id=>$data){ + $element_options[$i] = new stdClass(); + $element_options[$i]->id = $option_id; + $element_options[$i]->option = $data['option']; + $element_options[$i]->is_default = $data['option_is_default']; + $element_options[$i]->is_db_live = 1; + $i++; + } + } + + + //populate elements + $element[$j] = new stdClass(); + $element[$j]->title = nl2br($row['element_title']); + + if(empty($edit_id)){ + $element[$j]->guidelines = $row['element_guidelines']; + }else{ + $element[$j]->guidelines = ''; + } + + $element[$j]->size = $row['element_size']; + $element[$j]->is_required = $row['element_is_required']; + $element[$j]->is_unique = $row['element_is_unique']; + $element[$j]->is_private = $row['element_is_private']; + $element[$j]->type = $row['element_type']; + $element[$j]->position = $row['element_position']; + $element[$j]->id = $row['element_id']; + $element[$j]->is_db_live = 1; + $element[$j]->machform_path = $machform_path; + + //this data came from db or form submit + //being used to display edit form or redisplay form with errors and previous inputs + //this should be optimized in the future, only pass necessary data, not the whole array + $element[$j]->populated_value = $populated_values; + + //if there is file upload type, set form enctype to multipart + if($row['element_type'] == 'file'){ + $form_enc_type = 'enctype="multipart/form-data"'; + } + + if(!empty($error_elements[$element[$j]->id])){ + $element[$j]->is_error = 1; + $element[$j]->error_message = $error_elements[$element[$j]->id]; + } + + + $element[$j]->default_value = htmlspecialchars($row['element_default_value']); + + + $element[$j]->constraint = $row['element_constraint']; + if(!empty($element_options)){ + $element[$j]->options = $element_options; + }else{ + $element[$j]->options = ''; + } + + //check for calendar type + if($row['element_type'] == 'date' || $row['element_type'] == 'europe_date'){ + $has_calendar = true; + } + + $j++; + } + + + //add captcha if enable + if(!empty($form->captcha) && (empty($edit_id))){ + $element[$j] = new stdClass(); + $element[$j]->type = 'captcha'; + $element[$j]->form_id = $form_id; + $element[$j]->machform_path = $machform_path; + + if(!empty($error_elements['element_captcha'])){ + $element[$j]->is_error = 1; + $element[$j]->error_message = $error_elements['element_captcha']; + } + } + + //generate html markup for each element + $all_element_markup = ''; + foreach ($element as $element_data){ + if($element_data->is_private && empty($_SESSION['logged_in'])){ //don't show private element + continue; + } + $all_element_markup .= call_user_func('display_'.$element_data->type,$element_data); + } + + if(!empty($custom_error)){ + $form->error_message =<< +

    {$custom_error}

    + +EOT; + }elseif(!empty($error_elements)){ + $form->error_message =<< +

    {$lang['error_title']}

    +

    {$lang['error_desc']}

    + +EOT; + } + + if(!empty($form->password) && empty($_SESSION['user_authenticated'])){ //if form require password and password hasn't set yet + $show_password_form = true; + + }elseif (!empty($form->password) && !empty($_SESSION['user_authenticated']) && $_SESSION['user_authenticated'] != $form_id){ //if user authenticated but not for this form + $show_password_form = true; + + }else{ //user authenticated for this form, or no password required + $show_password_form = false; + } + + //display edit_id if there is any + if(!empty($edit_id)){ + $edit_markup = "\n"; + $submit_button = ''; + }else{ + $edit_markup = ''; + + if(!empty($form->review) && !$show_password_form){ + $submit_button = ''."\n".''; + }else{ + $submit_button = ''."\n".''; + } + } + + + //markup for submit button + $button_markup =<< + + {$edit_markup} + {$submit_button} + +EOT; + + //check for specific form css, if any, use it instead + if($form->has_css){ + $css_dir = DATA_DIR."/form_{$form_id}/css/"; + } + + + if(empty($form->active)){ //if form is not active, don't show the fields + $form_desc_div =''; + $all_element_markup = ''; + $button_markup = ''; + $ul_class = 'class="password"'; + $custom_element =<< +

    {$lang['form_inactive']}

    + +EOT; + }elseif($show_password_form){ //don't show form description if this page is password protected and user not authenticated + $form_desc_div =''; + $all_element_markup = ''; + $custom_element =<< +

    {$lang['form_pass_title']}

    +
    + + +
    + +EOT; + $ul_class = 'class="password"'; + }else{ + if(!empty($form->name) || !empty($form->description)){ + $form->description = nl2br($form->description); + $form_desc_div =<< +

    {$form->name}

    +

    {$form->description}

    +
    +EOT; + } + } + + + $embed_class = 'class="integrated"'; + + if(empty($edit_id)){ + $css_markup = ""; + }else{ + $css_markup = ""; + } + + if($has_calendar){ + $calendar_js = ""; + }else{ + $calendar_js = ''; + } + + + //If you would like to remove the "Powered by MachForm" link, please contact us at customer.service@appnitro.com before doing so + $form_markup =<< +{$calendar_js} + +
    + +
    + +

    {$form->name}

    +
    + {$form_desc_div} +
      + {$form->error_message} + {$all_element_markup} + {$custom_element} + {$button_markup} +
    +
    + +
    +
    +EOT; + return $form_markup; + + } + + function display_success($form_id,$embed=false){ + //get form properties data + $query = "select + form_success_message, + form_has_css, + form_name + from + ap_forms + where + form_id='$form_id'"; + + $result = do_query($query); + $row = do_fetch_result($result); + + $form = new stdClass(); + + $form->id = $form_id; + $form->success_message = nl2br($row['form_success_message']); + $form->has_css = $row['form_has_css']; + $form->name = $row['form_name']; + + + //check for specific form css, if any, use it instead + if($form->has_css){ + $css_dir = DATA_DIR."/form_{$form_id}/css/"; + } + + if($embed){ + $embed_class = 'class="embed"'; + } + + $form_markup = << + + + +{$form->name} + + + + + +
    + +

    Appnitro MachForm

    + +
    +

    {$form->success_message}

    +
    + +
    + + + +EOT; + return $form_markup; + } + + //this function is similar as display_success, but designed to display success page without IFRAME + function display_integrated_success($form_id,$machform_path){ + //get form properties data + $query = "select + form_success_message, + form_has_css + from + ap_forms + where + form_id='$form_id'"; + + $result = do_query($query); + $row = do_fetch_result($result); + + $form = new stdClass(); + + $form->id = $form_id; + $form->success_message = nl2br($row['form_success_message']); + $form->has_css = $row['form_has_css']; + + + //check for specific form css, if any, use it instead + if($form->has_css){ + $css_dir = DATA_DIR."/form_{$form_id}/css/"; + } + + + $form_markup = << +
    +
    +

    Appnitro MachForm

    + +
    +

    {$form->success_message}

    +
    + +
    +
    +EOT; + return $form_markup; + } + + //display form confirmation page + function display_form_review($form_id,$record_id,$embed=false){ + global $lang; + + //get form properties data + $query = "select + form_has_css, + form_redirect + from + ap_forms + where + form_id='$form_id'"; + + $result = do_query($query); + $row = do_fetch_result($result); + + + $form_has_css = $row['form_has_css']; + $form_redirect = $row['form_redirect']; + + //prepare entry data for previewing + $param['strip_download_link'] = true; + $param['review_mode'] = true; + $param['show_attach_image'] = true; + $entry_details = get_entry_details($form_id,$record_id,$param); + + $entry_data = ''."\n"; + + $toggle = false; + foreach ($entry_details as $data){ + if($toggle){ + $toggle = false; + $row_style = 'class="alt"'; + }else{ + $toggle = true; + $row_style = ''; + } + + $entry_data .= "\n"; + $entry_data .= "\n"; + $entry_data .= "\n"; + $entry_data .= "\n"; + } + + $entry_data .= '
    {$data['label']}".nl2br($data['value'])."
    '; + + //check for specific form css, if any, use it instead + if($form_has_css){ + $css_dir = DATA_DIR."/form_{$form_id}/css/"; + } + + if($embed){ + $embed_class = 'class="embed"'; + } + + $form_markup = << + + + +{$form_name} + + + + + + + + +
    + +

    Appnitro MachForm

    +
    +
    +

    {$lang['review_title']}

    +

    {$lang['review_message']}

    +
    + {$entry_data} +
      +
    • + + + +
    • +
    +
    + +
    + + + +EOT; + return $form_markup; + } + + //display form confirmation page for integrated embed code + function display_integrated_form_review($form_id,$record_id,$machform_path){ + global $lang; + + //get form properties data + $query = "select + form_has_css, + form_redirect + from + ap_forms + where + form_id='$form_id'"; + + $result = do_query($query); + $row = do_fetch_result($result); + + + $form_has_css = $row['form_has_css']; + $form_redirect = $row['form_redirect']; + + //prepare entry data for previewing + $param['strip_download_link'] = true; + $param['review_mode'] = true; + $param['show_attach_image'] = true; + $param['machform_path'] = $machform_path; + $entry_details = get_entry_details($form_id,$record_id,$param); + + $entry_data = ''."\n"; + + $toggle = false; + foreach ($entry_details as $data){ + if($toggle){ + $toggle = false; + $row_style = 'class="alt"'; + }else{ + $toggle = true; + $row_style = ''; + } + + $entry_data .= "\n"; + $entry_data .= "\n"; + $entry_data .= "\n"; + $entry_data .= "\n"; + } + + $entry_data .= '
    {$data['label']}".nl2br($data['value'])."
    '; + + //check for specific form css, if any, use it instead + if($form_has_css){ + $css_dir = DATA_DIR."/form_{$form_id}/css/"; + } + + if($embed){ + $embed_class = 'class="embed"'; + } + + $form_action = str_replace(array("&show_review=1","?show_review=1"),"",$_SERVER['REQUEST_URI']); + + $form_markup = << + + + + +
    +
    +

    Appnitro MachForm

    +
    +
    +

    {$lang['review_title']}

    +

    {$lang['review_message']}

    +
    + {$entry_data} +
      +
    • + + + +
    • +
    +
    + +
    +
    +EOT; + return $form_markup; + } +?> \ No newline at end of file diff --git a/index.css b/index.css new file mode 100644 index 0000000..6b2cad1 --- /dev/null +++ b/index.css @@ -0,0 +1,1236 @@ +* { + margin: 0pt; + padding: 0pt; +} +body { + margin: 7px 0pt 15px; + background:#E8DFEC url(images/ap_bg.gif) repeat scroll left top; + text-align: center; + font-size: small; + font-family: "Lucida Grande",Tahoma,Arial,Verdana,sans-serif; + +} +* html body { + font-size: small; +} +#container { + text-align: left; +} +#header { + background: rgb(20, 66, 130) none repeat; position: relative; height: 100px; +} + +#header[id] { + height: 100px; } +#panel { + border-style: none; + background: rgb(255, 255, 255) none repeat; + overflow: hidden; + width: 100%; +} +#container, #top, #bottom, #footer { + margin: 0pt auto; + width: 900px; +} +#top{ + height: 5px; + display: block ! important; +} +#bottom { + height: 10px; + display: block ! important; +} +.footer { + padding-top: 5px; + line-height: 40px; +} +#footer { + padding: 7px 0pt 10px; + text-align: left; +} +#footer h1 { + margin: -3px 5px 0pt 0pt; + float: right; +} +#footer p { + margin: 0pt 10px; + font-weight: bold; + color: rgb(182, 56, 31); +} +#footer a, #footer span { + font-size: 85%; + color: rgb(51, 51, 51); + text-decoration: none; +} +#footer a:hover { + text-decoration: underline; +} +#header_tab { + margin: 0pt 5px 0pt 0pt; + position: absolute; + bottom: 0pt; + left: 10pt; + list-style-type: none; + list-style-image: none; + list-style-position: outside; +} +#header_tab li { margin: 0px 0px; float: left; } +#header_tab li a { + + padding-left: 1px; + background: #144282 none repeat; + font-size: 95%; + display: block; + text-decoration: none; + color: rgb(255, 204, 102); + font-weight: bold; +} +#header_tab li a img { + margin: 0px; +} + +#statusBar { + margin: 0pt 0pt 0pt -435px; + position: absolute; + bottom: 0pt; + z-index: 5000; + width: 870px; + left: 50%; +} +#statusBar[id] { + position: fixed ! important; +} +#statusBar #statusPanel { + border: 1px solid #1A5BB2; + background-color: #1A5BB2; + position: relative; + text-align: left; +} +#statusText { + padding: 0pt 30px; + line-height: 30px; + color: rgb(255, 255, 204); +} + + +.tooltip { + font-weight: bold; + color: rgb(207, 153, 25) ! important; + text-decoration: none; + cursor: help ! important; +} +#tooltip { + border-style: solid; + border-color: rgb(107, 147, 191) rgb(69, 112, 159) rgb(69, 112, 159) rgb(107, 147, 191); + border-width: 1px; + margin: 7px 0pt 0pt 7px; + padding: 9px 15px 10px 10px; + position: absolute; z-index: 10000; + width: 250px; + background-color: rgb(87, 129, 175); + font-size: 11px; line-height: 15px ! important; + font-weight: normal; color: rgb(255, 255, 255); +} +#tooltip b { + margin: 0pt 0pt 3px; + display: block; + color: rgb(255, 255, 255) ! important; +} +#tooltip em { + display: block; font-style: normal; + letter-spacing: 0.02em; +} +h1, h2, h3 { + font-weight: normal; +} +p { color: rgb(34, 34, 34); } +hr { visibility: hidden; clear: both; height: 20px; width: 0pt; } +.inline { display: inline ! important; } +.center { text-align: center ! important; } +.left { float: left; } +.right { float: right; } +.hide { display: none ! important; } +.strong { font-weight: bold; } + + +* html #panel { height: 1%; } +#panel[id] { display: block; } +h1 { font-size: 100%; text-indent: -9000px; text-decoration: none; } +h1 a { + background: transparent url('images/appnitro_logo.png') no-repeat scroll left top; + overflow: hidden; height: 100%; + min-height: 3em; + display: block; +} +* html h1 a { background-image: none; } +#footer h1 a, .footer h1 a { height: 40px; width: 90px; } +.buttons a, button { + border-style: solid; + border-color: rgb(238, 238, 238) rgb(222, 222, 222) rgb(222, 222, 222) rgb(238, 238, 238); + border-width: 1px; + margin: 0pt 7px 0pt 0pt; + padding: 5px 10px 6px 7px; + cursor: pointer; + font-size: 100%; + line-height: 130%; + display: block; + float: left; + background-color: rgb(245, 245, 245); + text-decoration: none; + font-weight: bold; + color: rgb(86, 86, 86); +} + +fieldset { + border: 1px solid #CCCCCC; + margin: 7px 0pt 0pt; + padding: 0pt 10px 10px; + color: rgb(68, 68, 68); + line-height: 1.6em; +} +fieldset.choices { + padding: 7px 5px 10px 10px; +} +fieldset.fieldset { + padding: 3px 0pt 10px; +} +legend { + margin: 0pt 0pt 0pt -10px; + font-weight: bold; +} +#form_properties[id] legend, .choices[class] legend { margin: 0pt 0pt 0pt -5px; } +.fieldset legend { margin: 0pt; } +.fieldset[class] legend { margin: 0pt 0pt 0pt 5px; } +#form_properties fieldset div { + margin-bottom: 7px; +} +fieldset .small { + margin: 4px 20px 0pt 4px; +} +fieldset .small[class] { + margin: 3px 20px 0pt 4px; +} +fieldset p { + margin: 10px; +} +.choices input { + width: 200px; + margin-right: 3px; +} +.choices ol { margin: 10px 0pt 0pt; } +.choices[class] ol { margin: 0pt ! important; } +.choices img { margin: 0pt 0pt -4px; float: none; } +fieldset ol li { + margin: 0pt 5px 2px 3px ! important; + padding: 0pt ! important; + display: list-item ! important; + list-style-type: decimal; + list-style-image: none; + list-style-position: inside; +} + +button { + padding: 4px 10px 3px 7px; overflow: visible; + font-family: "Lucida Grande",Tahoma,Arial,Verdana,sans-serif; + width: auto; font-weight: bold; +} +button[type] { + padding: 5px 10px 5px 7px; + width: auto; + line-height: 17px; +} +button img, .buttons a img { + margin: 0pt 3px -3px 0pt ! important; + width: 16px; + height: 16px; +} +button:hover, .buttons a:hover { + border: 1px solid rgb(194, 225, 239); + background-color: rgb(223, 244, 255); + color: rgb(51, 102, 153); +} +.buttons a:active { + border: 1px solid rgb(98, 153, 197); + background-color: rgb(98, 153, 197); + color: rgb(255, 255, 255); +} +button.positive, .buttons a.positive { + color: rgb(82, 146, 20); +} +.buttons a.positive:hover, button.positive:hover { + border: 1px solid rgb(198, 216, 128); + background-color: rgb(230, 239, 194); + color: rgb(82, 146, 20); +} +.buttons a.positive:active { + border: 1px solid rgb(82, 146, 20); + background-color: rgb(82, 146, 20); + color: rgb(255, 255, 255); +} +.buttons a.negative, button.negative { + color: rgb(209, 47, 25); +} +.buttons a.negative:hover, button.negative:hover { + border: 1px solid rgb(251, 194, 196); + background: rgb(251, 227, 228) none repeat; + color: rgb(209, 47, 25); +} +.buttons a.negative:active { + border: 1px solid rgb(209, 47, 25); + background-color: rgb(209, 47, 25); + color: rgb(255, 255, 255); +} +.info .buttons { + margin: 6px 0pt 0pt; + padding: 0pt; + float: right; +} +.info .export { + margin: 6px 0pt 0pt; + padding: 0pt; + float: right; + +} + +.create_new_form { +float: right; +} + +.export a{ + color:#444444; + cursor:pointer; + font-size:85%; + font-weight:bold; + text-decoration:none; + padding:8px 5pt; +} + + + +.info .buttons a { + margin: 0pt 0pt 0pt 7px; } +.info b { + color: rgb(189, 61, 32); +} +.clearfix:after, #panel:after { + content: "."; + display: block; + height: 0pt; + clear: both; + visibility: hidden; +} +img { + border: medium none ; +} + +#info { + margin: 0pt 0pt 0pt -385px; + cursor: pointer; position: absolute; + left: 50%; z-index: 10000; text-align: left; +} + +#info h2 { + margin: 0pt 0pt 3px; + color: rgb(81, 115, 156); + font-weight: bold; +} +#info li { + margin: 5px 10px; + padding: 0pt; + list-style-type: disc; + list-style-image: none; + list-style-position: inside; + color: rgb(51, 51, 51); +} +.notification { + border: 2px solid #96B6DA; + margin: 10px 10px 0pt; padding: 10px 0px 10px 0pt; + background-color: #F3F7FB; +} +.element_inactive { + margin: 10px 10px 0pt; padding: 10px 0px 10px 0pt; + background-color: #F3F7FB; +} +.click_instruction{ + padding-top: 5px; +} +.notification h2 { + display: block; font-size: 150%; + color: rgb(205, 66, 36) ! important; +} +.notification b { + color: rgb(189, 61, 32); +} +.element_inactive h2 { + display: block; font-size: 150%; + color: rgb(205, 66, 36) ! important; +} +.element_inactive b { + color: rgb(189, 61, 32); +} + +a { + color: blue; + outline-color: invert; + outline-style: none; + outline-width: medium; +} +a:hover { + cursor: pointer; + color: green; +} +a img { + border: 0pt none ; +} +.icon { + width: 16px; height: 16px; +} + +#overlay { + position: absolute; + top: 0pt; left: 0pt; + width: 100%; + height: 100%; + z-index: 5000; + background-color: rgb(51, 51, 51); opacity: 0.8; +} +#overlay[id] { + position: fixed; +} + + +form ul { + margin: 0pt; + padding: 0pt; + list-style-type: none; + width: 100%; +} +form li { margin: 0pt; padding: 4px 5px 2px 9px; position: relative; } +form li:after, .buttons:after { + content: "."; display: block; + height: 0pt; clear: both; + visibility: hidden; +} +* html form li, * html .buttons { height: 1%; } +form li, .buttons { + display: block; +} +form li div, form li span { margin: 0pt 5px 0pt 0pt; padding: 0pt 0pt 8px; color: rgb(68, 68, 68); } +form li span { float: left; } +form li div.left { display: inline; float: left; width: 48%; } +form li div.right { display: inline; float: right; width: 48%; } +form li div.left .medium, form li div.right .medium { width: 100%; } +.clear { clear: both; } +form li div label, form li span label { + margin: 0pt; + padding-top: 3px; + clear: both; + font-size: 9px; + line-height: 9px; + color: rgb(68, 68, 68); + display: block; +} +form li .icon { + margin: 0.1em 5px 0pt 0pt; + padding: 0pt; + float: left; + width: 16px; + height: 16px; +} +.info { + border-bottom: 1px dotted rgb(204, 204, 204); + margin: 0pt 0pt 1em; + clear: both; +} +.info[class] { display: block; } +.info h2 { + margin: 0pt 0pt 3px; + font-weight: normal; + font-size: 160%; + clear: left; +} +.info p { + margin: 0pt 0pt 12px; + font-size: 95%; + line-height: 130%; +} +form hr { + display: none; +} +fieldset.section { + border: 1px dotted rgb(204, 204, 204); + margin: 12px 0pt 15px; + padding: 5px 0pt 0pt; } +fieldset ul { + margin: 0pt 10px 10px; + width: 97%; +} +fieldset.section legend { + margin: 0pt; + padding: 0pt 5px; + background: rgb(255, 255, 255) none repeat; + font-weight: normal; + font-size: 110%; + line-height: 110%; +} +fieldset.section[class] legend { + margin: 0pt 0pt 0pt 8px; + display: block; +} + +fieldset.section { + border-left: medium none; + border-right: medium none; + border-bottom: medium none; + display: block; + position: relative; + margin-bottom: 0pt; +} +fieldset.first { + border-top: medium none ! important; + margin-top: 0px; + padding-top: 1px; +} +fieldset.first h3 { margin-top: 0pt ! important; } +fieldset ul { margin: 0pt; } +fieldset.section legend { display: none ! important; } +form .section h3 { + margin: 9px 0pt 2px 9px; + font-weight: normal; + font-size: 110%; + line-height: 130%; +} +form .section { + margin-left: 9px; + margin-top: 3px; +} + +.buttons { + clear: both; margin-top: 10px; +} +.buttons input { font-size: 120%; margin-right: 5px; } +label.desc { + border: medium none ; + padding: 0pt 4px 1px 0pt; + line-height: 150%; + color: rgb(34, 34, 34); + display: block; + font-size: 95%; + font-weight: bold; +} +input.text, textarea.textarea, select.select { + border-style: solid; + border-color: rgb(124, 124, 124) rgb(195, 195, 195) rgb(221, 221, 221); + border-width: 1px; margin: 0pt; + background: rgb(255, 255, 255) url('images/input_bg.gif') repeat-x scroll center top; + font-size: 100%; + color: rgb(51, 51, 51); +} +input.text { padding: 2px 0pt; } +input.currency { text-align: right; } +input.checkbox, input.radio { + margin: 8px 0pt 0pt 3px; + display: block; + line-height: 1.4em; + width: 13px; + height: 13px; +} +label.choice { + margin: -19px 0pt 0pt 25px; + padding: 4px 0pt 5px; + font-size: 100%; + display: block; + line-height: 1.4em; + color: rgb(68, 68, 68); + width: 90%; +} +textarea.textarea { + margin-top: 1px; + font-family: "Lucida Grande",Tahoma,Arial,Verdana,sans-serif; +} +select.select { + margin: 1px 0pt; + padding: 1px 0pt 0pt; +} +select.select[class] { + margin: 0pt; + padding: 1px 0pt; +} +.third { width: 32% ! important; } +.half { width: 48% ! important; } +.full { width: 100% ! important; } +input.small, select.small { width: 25%; } +input.medium, select.medium { width: 50%; } +input.large, select.large, textarea.textarea { width: 100%; } +textarea.small { height: 5.5em; } +textarea.medium { height: 10em; } +textarea.large { height: 20em; } +#errorLi { + border: 1px dotted red; + background: rgb(255, 255, 255) none repeat; + width: 97%; margin-bottom: 1em; + text-align: center; +} +#errorMsg { + margin: 0pt 0pt 0.8em; + color: rgb(0, 0, 0); + font-size: 100%; +} +#errorMsg strong { + padding: 2px 3px; + background-color: rgb(255, 223, 223); + color: red; +} +form li.error { + border-right: 1px solid rgb(234, 203, 204); + border-bottom: 1px solid rgb(234, 203, 204); + margin: 3px 0pt; + background-color: rgb(255, 223, 223) ! important; +} +form li.error label { + color: rgb(223, 0, 0) ! important; +} +form p.error { + margin: 0pt 0pt 5px; + color: red; + font-weight: bold; + font-size: 10px; + clear: both; +} +form .req { + float: none; + color: red; + font-weight: bold; +} +form li.focused { + background-color: rgb(255, 247, 192); +} +form .instruct { + border: 1px solid rgb(230, 230, 230); + margin: 0pt 0pt 0pt 8px; + padding: 8px 10px 9px; + background: rgb(245, 245, 245) none repeat; + display: none; + position: absolute; + top: 0pt; left: 100%; + z-index: 1000; + width: 42%; + line-height: 130%; + font-size: 80%; + color: rgb(68, 68, 68); +} +form .instruct small { + font-size: 100%; +} +form li.focused .instruct, form li:hover .instruct { + display: block; +} + +ul.protected { + margin: 60px 0pt; + list-style-type: none; + list-style-image: none; + list-style-position: outside; +} +.protected li { + padding: 10px 0pt; + text-align: center; +} +.protected h2 { + margin: 0pt auto 10px; + font-weight: bold; + color: rgb(223, 0, 0); +} +.protected label { + font-size: 120% ! important; + padding-top: 10px; + display: block; +} +.protected input.text { + font-size: 170% ! important; + width: 380px; + text-align: center; +} +.protected .buttons { margin: 0pt; } +.protected #form_save_button { + font-size: 120% ! important; +} + +#form_builder #main { + padding: 0pt 0pt 20px; + float: left; + width: 490px +} +#form_builder #sidebar { + position: relative; + float: left; width: 360px; + height: 500px; + background-color:#FFFFFF; + margin-left:30px; +} +#form_builder #sidebar[id] { + height: auto; + width: 360px; + min-height: 500px; +} +#form_builder #main form { + margin: 10px 0pt 0pt 22px; + width: 466px; +} +#form_builder #main form ul { + width: 100%; +} +#form_builder #main form li { + margin: 0pt 0pt 8px; + width: 100%; +} +#form_result label.desc, #form_result legend { overflow: hidden; width: 100%; } +#sidebar .desc { + padding: 5px 0pt 0pt; font-weight: bold; +} + +#form_password { + padding: 6px 0pt 0pt; +} +fieldset .desc { color: rgb(34, 34, 34) ! important; } +#tabs { + background-color: #FFFFFF; + float: left; + width: 100%; + list-style-type: none; + list-style-image: none; + list-style-position: outside; +} +#tabs li { float: left; font-size: 85%; text-align: center; } +#tabs a { + display: block; + color: rgb(128, 102, 63); + text-decoration: none; + border-bottom: 5px; + border-bottom-style:solid; + border-bottom-color: #144282; + +} +#tabs a:hover { font-weight: bold; color: #1A5BB2; } +#add_field_tab { width: 105px; } +#field_prop_tab { width: 125px; } +#form_prop_tab { width: 130px; } +#add_field_tab a { margin: 4px 0pt 0pt 0px; padding: 4px 0pt 4px 20px; } +#field_prop_tab a { margin: 4px 0pt 0pt 0px; padding: 4px 0pt 4px 20px; } +#form_prop_tab a { margin: 4px 0pt 0pt 0px; padding: 4px 0pt 4px 20px; } +.add_field_tab #add_field_tab a, .field_prop_tab #field_prop_tab a, .form_prop_tab #form_prop_tab a { + background: url('images/icons/asterisk_orange.gif') no-repeat scroll 4px 0pt; + border-bottom: 5px; + border-bottom-style:solid; + border-bottom-color: #4B75B3; + color: #1A5BB2; + font-weight: bold; +} +input[disabled], select[disabled] { color: rgb(102, 102, 102) ! important; } +#add_elements { padding: 15px; clear: both; } +#add_elements[id] { margin: 25px 0pt 0pt; position: fixed; } +#element_buttons ul { float: left; list-style-type: none; list-style-image: none; list-style-position: outside; } +#first_column li { margin: 5px 5px 5px 0pt; text-align:right; padding: 0px } +#second_column li { margin: 5px 0pt 5px 5px; text-align:right; padding: 0px} +#element_buttons a { + border-style: solid; + border-color: rgb(238, 238, 238) rgb(222, 222, 222) rgb(222, 222, 222) rgb(238, 238, 238); + border-width: 1px; + padding: 0px 0pt 0px 25px; + display: block; + width: 128px; + background-color: #ffffff; + text-decoration: none; + font-weight: bold; + color: rgb(86, 86, 86); + background-repeat: no-repeat; + background-position: 6px center; +} +#element_buttons a:hover { + border: 1px solid #4B75B3; + background-color: #DDF0F8; + color: rgb(68, 68, 68); +} +#element_buttons a:active { + border: 1px solid rgb(147, 184, 37); + background-color: rgb(193, 223, 93); + color: rgb(51, 51, 51); +} + +#single_line_text { background-image: url('images/button_icon/single_line_text_bg.gif');} +#paragraph_text { background-image: url('images/button_icon/paragraph_text_bg.gif'); } +#multiple_choice { background-image: url('images/button_icon/multiplechoice_bg.gif'); } +#section_break { background-image: url('images/button_icon/section_break_bg.gif'); } +#checkboxes { background-image: url('images/button_icon/checkbox_bg.gif'); } +#drop_down { background-image: url('images/button_icon/dropdown_bg.gif'); } +#address { background-image: url('images/button_icon/address_bg.gif'); } +#web_site { background-image: url('images/button_icon/website_bg.gif'); } +#file_upload { background-image: url('images/button_icon/file_upload_bg.gif'); } +#number { background-image: url('images/button_icon/number_bg.gif'); } +#name_text { background-image: url('images/button_icon/name_bg.gif'); } +#date { background-image: url('images/button_icon/date_bg.gif'); } +#time { background-image: url('images/button_icon/time_bg.gif'); } +#phone { background-image: url('images/button_icon/phone_bg.gif'); } +#price { background-image: url('images/button_icon/price_bg.gif'); } +#email { background-image: url('images/button_icon/mail_bg.gif'); } +#nofields { cursor: pointer; } +#form_result .notification { margin: 0pt; padding: 15px; } +#add_elements .notification { margin: 0pt 0pt 10px; padding: 10px; text-align: center ! important; } +#add_elements .notification[class] { display: block; width: 308px; } +#element_properties .notification { margin: 20px; padding: 15px; } +#form_result li { + border: 1px solid white; + padding: 0pt; + background-color: rgb(255, 255, 255); +} +#form_result li * { cursor: pointer; } +#form_result li a.hover_ready { border: 1px solid rgb(255, 255, 255); padding: 4px 5px 2px 9px; display: block; text-decoration: none; color: rgb(68, 68, 68); } +#form_result li a.hover_ready:after { content: "."; display: block; height: 0pt; clear: both; visibility: hidden; } +#form_result li a.hover_ready { } +* html #form_result li a.hover_ready { height: 1%; } +#form_result li a.hover_ready { display: block; } +#form_result .info a { color: rgb(0, 0, 0); } +#form_result .info { border-bottom: 1px dotted rgb(204, 204, 204); width: 100% ! important; } +#form_result li a.hover_ready:hover { + border: 1px dotted #5F7EB2 ! important; + background: transparent url('images/icons/pencil.gif') no-repeat scroll 98% 4px; } +#form_result li.info a.hover_ready { padding: 7px 0pt 0pt; } +#form_result li.private { background-image: url('images/icons/locksmall.gif') ! important; background-repeat: no-repeat; background-position: 98% 7px; } +#form_result li.private .hover_ready:hover { + background-color: rgb(255, 255, 255); +} +#form_result li.current_edit { + border: 1px solid #CCCCCC; + background-color: #F3F7FB; +} +#form_result li.current_edit .hover_ready:hover { + background-color: #F3F7FB; +} +#form_result li.current_edit .desc { color: #1A5BB2 ! important; } +.arrow { + margin: 0pt 7px 0pt 0pt; + no-repeat; display: none; + position: absolute; + z-index: 0; right: 100%; +} +#form_result li.current_edit .arrow { + display: block; +} +#form_result .element_actions { + margin: -8px 10px 0px 0pt; + padding: 0pt; + display: none; + position: absolute; + right: 0pt; + line-height: 10px; + +} +#form_result li.current_edit .element_actions { + display: block; } +#sidebar form { + padding: 15px 20px; + clear: left; + border-top-style: solid; + border-top-width: 1px; + border-top-color: #CCCCCC; + border-bottom-style: solid; + border-bottom-width: 1px; + border-bottom-color: #CCCCCC; + background-color: #F3F7FB; +} +#sidebar form ul { font-size: 95%; } +#sidebar form li { padding: 0pt 0pt 7px; position: static; } +#sidebar[id] form li { display: block; } +#sidebar label, #sidebar legend { font-size: 90%; color: #1A5BB2; text-align: left; } +#sidebar .choice { font-size: 90%; color: #1A5BB2; text-align: left; } +#sidebar .choice b { color: #1A5BB2; } +#sidebar .textarea { height: 5em; } +#sidebar .radio, #sidebar .checkbox { margin: 0pt 5px 2px 15px; display: inline; } +#sidebar .radio[class] { margin-bottom: -2px; } +#sidebar .checkbox[class] { margin-bottom: 0pt; } +#sidebar .choice { margin: 0pt; display: inline; } +#sidebar .tooltip { border-bottom: medium none; } +fieldset .left, fieldset .right { margin: 3px 0pt 0pt; padding: 0pt; } +#form_properties { display: none; } +#form_properties li { margin: 4px 0pt; } +#form_properties .password { margin-left: 38px; } +.password img, .email img { margin: 2px 3px -2px 0pt; } +#element_properties { position: relative; display: none; } +#element_properties .num { + border: medium none ; + margin: 0px 15px 0pt 0pt; + padding: 0pt; + background: transparent none repeat; + position: absolute; right: 0pt; font-size: 300%; + text-align: right; width: auto; + color: #144282; } +#sidebar textarea#element_label { width: 70%; height: 3.7em; } +#sidebar .buttons { margin: 6px 0pt; text-align: center; } +#sidebar .buttons .button { margin: 0pt 5px; } + +#element_unique_span{ + margin: 0; + padding: 0; +} +#admin_only_span{ + margin: 0; + padding: 0; +} + +/* Form manager */ + +#form_manager { +margin:0pt 20px; +padding:20px 0px 10px; +} + + + +#form_manager td a { +color:#444444; +cursor:pointer; +font-size:85%; +text-decoration:none; +font-weight: bold; +} + +#grid-panel td a { +color: blue; +cursor:pointer; +font-size:100%; +font-weight: bold; +} + +#form_manager h3 { +font-size:115%; +position:relative; +font-weight: bold; +line-height: 30px; +padding-left: 5px; +} + +#form_manager td a:hover { +background-color: #D9E7FB; + +} + +#grid-panel td a:hover { +text-decoration:underline; +} + +/* Pagination */ +#paging { +clear:both; +margin-top: 0px; +padding-top: 5px; + +} +#paging a { +background-color:#EEEEEE; + +border-style: solid; +border-width: 1px; +padding:3px 6px; +text-align:center; +text-decoration:none; +color:#444444; +font-size:85%; +font-weight:bold; +} + +#paging a:hover { +background-color:#FFFFFF; +color:#350B51; +} +#form_manager .active_page { +font-size:115%; +background-color:#FFFFFF; +} + + + +.export a:hover{ + background:#D9E7FB none repeat scroll 0%; + color:#003366; + padding:8px 5pt; +} + +form li.highlighted +{ + background-color:#F3F7FB; + overflow:hidden; +} + +#error_message +{ + border:1px dashed red; + margin-bottom:1em; + padding-left:0; + padding-right:0; + padding-top:4px; + text-align:center; + width:99%; +} + +#error_message_title +{ + color:#DF0000; + font-size:125%; + margin:5px 0 5px; + padding:0; +} + +#error_message_desc +{ + color:#000; + font-size:100%; + margin:0 0 .8em; +} + +#success_message +{ + border:1px dashed #CF9919; + margin-bottom:1em; + padding-left:0; + padding-right:0; + padding-top:4px; + text-align:center; + width:99%; + background-color: #F3F7FB; +} + +#success_message_title +{ + color:#1A5BB2; + font-size:125%; + margin:5px 0 5px; + padding:0; +} + +#success_message_desc +{ + color:#000; + font-size:100%; + margin:0 0 .8em; +} + + +.global_message { + margin: 0pt; + padding: 0pt; + list-style-type: none; + width: 100%; +} + +.fix_png{ + behavior:url(css/iepngfix.htc); +} + +#appnitro_logos { + padding-left: 10px; + padding-top: 5px; +} + +/* Manage Entries page */ +#manage_entries{ + margin-bottom: 20px; +} +#manage_entries table{ + table-layout: fixed; +} +#manage_entries table div{ + overflow:hidden; + height:1.2em; + white-space: nowrap; + text-overflow:ellipsis; +} + +#manage_entries td{ + text-align: left; + border-bottom:1px solid #DEDEDE; + padding:5px; +} +#manage_entries th{ + background: #3661A1; + color: #fff; + border-right:1px dotted #fff; + padding: 5px; + text-align: left; + height:1.1em; +} +.alt{ + background: #F3F7FB; +} +#columns_preference{ + width: 100%; + margin-bottom: 20px; + overflow:hidden; +} +#columns_preference table{ + table-layout: fixed; +} +#columns_preference table div{ + overflow:hidden; + height:1.2em; + white-space: nowrap; + text-overflow:ellipsis; +} + +#columns_preference td{ + text-align: left; + border-bottom:1px solid #DEDEDE; + padding:5px 10px; +} +#columns_preference th{ + background: #3661A1; + color: #fff; + border-right:1px dotted #fff; + padding: 5px 10px; + text-align: left; +} +#cp_list{ + + float: left; + width: 50%; +} +#tv_list{ + + float: left; + width: 50%; +} +.me_action{ + width: 45px; + padding-right: 0px !important; + padding-left: 5px !important; +} +.me_number{ + width: 35px; + padding-right: 0px !important; + padding-left: 0px !important; + text-align: center !important; +} +.me_center_div{ + width: 100%; + text-align: center !important; +} +.me_right_div{ + width: 100%; + text-align: right !important; +} +#me_choose_col{ + float: right; + padding-bottom: 5px +} +#me_choose_col a{ + text-decoration:none; + border-bottom: 1px dotted #000; +} + +.breadcrumb{ + text-decoration:none; + border-bottom: 1px dotted #000; + color: #3661A1; +} +#view_entry{ + width: 100%; + margin-bottom: 20px; + overflow:hidden; +} + +#view_entry td{ + text-align: left; + border-bottom:1px solid #DEDEDE; + padding:5px 10px; +} +#view_entry th{ + background: #3661A1; + color: #fff; + border-right:1px dotted #fff; + padding: 5px 10px; + text-align: left; +} +#ve_detail{ + width: 70%; + float: left; + padding-bottom: 30px; +} +#ve_action_container{ + width: 25%; + margin-left: 20px; + float: left; +} +#ve_action{ + background-color: #FFFFCC; + overflow: hidden; + padding-bottom: 10px; + padding-left: 5px; +} +#ve_table_info{ + margin-top: 25px; +} +#ve_detail_table tbody tr:hover +{ + background-color: LemonChiffon; +} +.big_dotted_link{ + text-decoration:none; + border-bottom: 1px dotted #000; + color: #3661A1; + font-weight: bold; +} +#ve_action li{ + padding: 5px; + float: left; + width: 40%; + padding-bottom: 10px; +} +#ve_detail .entry_link{ + text-decoration:none; + border-bottom: 1px dotted #000; + color: #3661A1; + font-weight: bold; + font-size: 100%; +} + +/* edit entry */ +#edit_entry{ + width: 100%; + margin-bottom: 20px; + overflow:hidden; +} + +#ee_detail{ + width: 70%; + float: left; + padding-bottom: 30px; +} +#ee_action_container{ + width: 25%; + margin-left: 20px; + float: left; +} +#ee_action{ + background-color: #FFFFCC; + overflow: hidden; + padding-bottom: 10px; + padding-left: 5px; +} +#ee_action li{ + padding: 5px; + float: left; + width: 40%; + padding-bottom: 10px; +} +#list_buttons{ + list-style-type: none; +} + +/* email settings */ +#es_left{ + background-color:#F3F7FB; + margin-right: 20px; +} +#es_right{ + background-color:#F3F7FB; + margin-left: 20px; +} \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..8a08fc2 --- /dev/null +++ b/index.php @@ -0,0 +1,104 @@ + + + + +
    + +
    +

    Admin Panel Login

    +

    Please login below to access Admin Panel

    +
    + +
    +
    +
      + +
    • + +
    • + +
    • + + +
      + +
      + +
    • +
    • + +
      + +
      +
    • +
    • + +
    • +
    +
    +

    + +
    + \ No newline at end of file diff --git a/installer.php b/installer.php new file mode 100644 index 0000000..3557218 --- /dev/null +++ b/installer.php @@ -0,0 +1,345 @@ +Congratulations! You have completed the installation. MachForm is now installed."; + }else{ + $install_message = "An error has occured during installation."; + } + + $state = 'install_report'; + }else{ + + //do a pre installation check + $state = 'show_preinstall_check'; + + //check for PHP version + if(version_compare(PHP_VERSION,"4.3.0",">=")){ + $is_php_version_passed = true; + }else{ + $is_php_version_passed = false; + $pre_install_has_error = true; + } + + //check for MySQL version + if(version_compare(mysql_get_server_info(),"4.1.0",">=")){ + $is_mysql_version_passed = true; + }else{ + $is_mysql_version_passed = false; + $pre_install_has_error = true; + } + + //check for MySQL user,password and database existance + if(empty($mysql_connect_error)){ + $is_mysql_connect_passed = true; + }else{ + $is_mysql_connect_passed = false; + $pre_install_has_error = true; + } + + if(empty($mysql_select_db_error)){ + $is_mysql_select_db_passed = true; + }else{ + $is_mysql_select_db_passed = false; + $pre_install_has_error = true; + } + + //check for data folder permission + if(is_writable(DATA_DIR)){ + $is_data_dir_writable = true; + }else { + $is_data_dir_writable = false; + $pre_install_has_error = true; + $data_dir_writable_error = "MachForm require read and write access to this folder. Please set the correct permission."; + } + + if($pre_install_has_error){ + $pre_install_message = "Your system does not match the minimum requirements necessary. Please take the appropriate actions to correct the errors."; + }else{ + $pre_install_message = "Your system passed the minimum requirements necessary. You can now start the installation process."; + } + } + } + + } + + $hide_nav = true; +?> + + + +
    + + +
    +

    MachForm Installer Error

    +

    Please fix the following error before you can continue the installation process:

    +
    + +
    +
    +
      +
    • + +
      +

      + There doesn't seem to be a config.php file. We need this before we can get started. +

      +

      +

      In the base directory of your installation you'll find a file called config-empty.php. Open this file and fill in the required database information.



      +

      After the details are filled in you must rename the file config.php before continuing.


      +
      +
    • +
    • + +
    • +
    +
    +

    + + + +
    +

    MachForm Pre-Installation Check

    +

    +
    + +
    +
    +
      +
    • + +
    • + +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + + + + + + +
    • +
    +
    +

    + + + +
    +

    Remove Installer File

    +

    Please follow the step below to be able to continue:

    +
    + +
    +
    +
      +
    • + +
      +

      + MachForm is currently installed and ready. +

      +
      +

      Please remove this file (installer.php) before you can start using MachForm.


      +

      After you delete this file, you can login here.


      +
      +
    • +
    +
    +

    + + + + +
    +

    MachForm Installation Report

    +

    +
    + +
    +
    +
      + +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + Important: Please delete this installer file (installer.php) now.

      After deleting this file, you can login to MachForm admin panel +
    • + +
    • + +
    • + + +
    • + +
    • + + + + +
    • + + +
    • + + +
    +
    +

    + + + +
    + \ No newline at end of file diff --git a/js/base.js b/js/base.js new file mode 100644 index 0000000..5a5c816 --- /dev/null +++ b/js/base.js @@ -0,0 +1,2993 @@ +/* Prototype JavaScript framework, version 1.5.0_rc0 + * (c) 2005 Sam Stephenson + * + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://prototype.conio.net/ + * +/*--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.5.0_rc0', + ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)', + + emptyFunction: function() {}, + K: function(x) {return x} +} + +var Class = { + create: function() { + return function() { + this.initialize.apply(this, arguments); + } + } +} + +var Abstract = new Object(); + +Object.extend = function(destination, source) { + for (var property in source) { + destination[property] = source[property]; + } + return destination; +} + +Object.inspect = function(object) { + try { + if (object == undefined) return 'undefined'; + if (object == null) return 'null'; + return object.inspect ? object.inspect() : object.toString(); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } +} + +Function.prototype.bind = function() { + var __method = this, args = $A(arguments), object = args.shift(); + return function() { + return __method.apply(object, args.concat($A(arguments))); + } +} + +Function.prototype.bindAsEventListener = function(object) { + var __method = this; + return function(event) { + return __method.call(object, event || window.event); + } +} + +Object.extend(Number.prototype, { + toColorPart: function() { + var digits = this.toString(16); + if (this < 16) return '0' + digits; + return digits; + }, + + succ: function() { + return this + 1; + }, + + times: function(iterator) { + $R(0, this, true).each(iterator); + return this; + } +}); + +var Try = { + these: function() { + var returnValue; + + for (var i = 0; i < arguments.length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) {} + } + + return returnValue; + } +} + +/*--------------------------------------------------------------------------*/ + +Object.extend(String.prototype, { + gsub: function(pattern, replacement) { + var result = '', source = this, match; + replacement = arguments.callee.prepareReplacement(replacement); + + while (source.length > 0) { + if (match = source.match(pattern)) { + result += source.slice(0, match.index); + result += (replacement(match) || '').toString(); + source = source.slice(match.index + match[0].length); + } else { + result += source, source = ''; + } + } + return result; + }, + + sub: function(pattern, replacement, count) { + replacement = this.gsub.prepareReplacement(replacement); + count = count === undefined ? 1 : count; + + return this.gsub(pattern, function(match) { + if (--count < 0) return match[0]; + return replacement(match); + }); + }, + + scan: function(pattern, iterator) { + this.gsub(pattern, iterator); + return this; + }, + + truncate: function(length, truncation) { + length = length || 30; + truncation = truncation === undefined ? '...' : truncation; + return this.length > length ? + this.slice(0, length - truncation.length) + truncation : this; + }, + + strip: function() { + return this.replace(/^\s+/, '').replace(/\s+$/, ''); + }, + + stripTags: function() { + return this.replace(/<\/?[^>]+>/gi, ''); + }, + + stripScripts: function() { + return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); + }, + + extractScripts: function() { + var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); + var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); + return (this.match(matchAll) || []).map(function(scriptTag) { + return (scriptTag.match(matchOne) || ['', ''])[1]; + }); + }, + + evalScripts: function() { + return this.extractScripts().map(function(script) { return eval(script) }); + }, + + escapeHTML: function() { + var div = document.createElement('div'); + var text = document.createTextNode(this); + div.appendChild(text); + return div.innerHTML; + }, + + unescapeHTML: function() { + var div = document.createElement('div'); + div.innerHTML = this.stripTags(); + return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; + }, + + toQueryParams: function() { + var pairs = this.match(/^\??(.*)$/)[1].split('&'); + return pairs.inject({}, function(params, pairString) { + var pair = pairString.split('='); + params[pair[0]] = pair[1]; + return params; + }); + }, + + toArray: function() { + return this.split(''); + }, + + camelize: function() { + var oStringList = this.split('-'); + if (oStringList.length == 1) return oStringList[0]; + + var camelizedString = this.indexOf('-') == 0 + ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) + : oStringList[0]; + + for (var i = 1, len = oStringList.length; i < len; i++) { + var s = oStringList[i]; + camelizedString += s.charAt(0).toUpperCase() + s.substring(1); + } + + return camelizedString; + }, + + inspect: function() { + return "'" + this.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') + "'"; + } +}); + +String.prototype.gsub.prepareReplacement = function(replacement) { + if (typeof replacement == 'function') return replacement; + var template = new Template(replacement); + return function(match) { return template.evaluate(match) }; +} + +String.prototype.parseQuery = String.prototype.toQueryParams; + +var Template = Class.create(); +Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; +Template.prototype = { + initialize: function(template, pattern) { + this.template = template.toString(); + this.pattern = pattern || Template.Pattern; + }, + + evaluate: function(object) { + return this.template.gsub(this.pattern, function(match) { + var before = match[1]; + if (before == '\\') return match[2]; + return before + (object[match[3]] || '').toString(); + }); + } +} + +var $break = new Object(); +var $continue = new Object(); + +var Enumerable = { + each: function(iterator) { + var index = 0; + try { + this._each(function(value) { + try { + iterator(value, index++); + } catch (e) { + if (e != $continue) throw e; + } + }); + } catch (e) { + if (e != $break) throw e; + } + }, + + all: function(iterator) { + var result = true; + this.each(function(value, index) { + result = result && !!(iterator || Prototype.K)(value, index); + if (!result) throw $break; + }); + return result; + }, + + any: function(iterator) { + var result = true; + this.each(function(value, index) { + if (result = !!(iterator || Prototype.K)(value, index)) + throw $break; + }); + return result; + }, + + collect: function(iterator) { + var results = []; + this.each(function(value, index) { + results.push(iterator(value, index)); + }); + return results; + }, + + detect: function (iterator) { + var result; + this.each(function(value, index) { + if (iterator(value, index)) { + result = value; + throw $break; + } + }); + return result; + }, + + findAll: function(iterator) { + var results = []; + this.each(function(value, index) { + if (iterator(value, index)) + results.push(value); + }); + return results; + }, + + grep: function(pattern, iterator) { + var results = []; + this.each(function(value, index) { + var stringValue = value.toString(); + if (stringValue.match(pattern)) + results.push((iterator || Prototype.K)(value, index)); + }) + return results; + }, + + include: function(object) { + var found = false; + this.each(function(value) { + if (value == object) { + found = true; + throw $break; + } + }); + return found; + }, + + inject: function(memo, iterator) { + this.each(function(value, index) { + memo = iterator(memo, value, index); + }); + return memo; + }, + + invoke: function(method) { + var args = $A(arguments).slice(1); + return this.collect(function(value) { + return value[method].apply(value, args); + }); + }, + + max: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value >= result) + result = value; + }); + return result; + }, + + min: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (result == undefined || value < result) + result = value; + }); + return result; + }, + + partition: function(iterator) { + var trues = [], falses = []; + this.each(function(value, index) { + ((iterator || Prototype.K)(value, index) ? + trues : falses).push(value); + }); + return [trues, falses]; + }, + + pluck: function(property) { + var results = []; + this.each(function(value, index) { + results.push(value[property]); + }); + return results; + }, + + reject: function(iterator) { + var results = []; + this.each(function(value, index) { + if (!iterator(value, index)) + results.push(value); + }); + return results; + }, + + sortBy: function(iterator) { + return this.collect(function(value, index) { + return {value: value, criteria: iterator(value, index)}; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }).pluck('value'); + }, + + toArray: function() { + return this.collect(Prototype.K); + }, + + zip: function() { + var iterator = Prototype.K, args = $A(arguments); + if (typeof args.last() == 'function') + iterator = args.pop(); + + var collections = [this].concat(args).map($A); + return this.map(function(value, index) { + return iterator(collections.pluck(index)); + }); + }, + + inspect: function() { + return '#'; + } +} + +Object.extend(Enumerable, { + map: Enumerable.collect, + find: Enumerable.detect, + select: Enumerable.findAll, + member: Enumerable.include, + entries: Enumerable.toArray +}); +var $A = Array.from = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0; i < iterable.length; i++) + results.push(iterable[i]); + return results; + } +} + +Object.extend(Array.prototype, Enumerable); + +if (!Array.prototype._reverse) + Array.prototype._reverse = Array.prototype.reverse; + +Object.extend(Array.prototype, { + _each: function(iterator) { + for (var i = 0; i < this.length; i++) + iterator(this[i]); + }, + + clear: function() { + this.length = 0; + return this; + }, + + first: function() { + return this[0]; + }, + + last: function() { + return this[this.length - 1]; + }, + + compact: function() { + return this.select(function(value) { + return value != undefined || value != null; + }); + }, + + flatten: function() { + return this.inject([], function(array, value) { + return array.concat(value && value.constructor == Array ? + value.flatten() : [value]); + }); + }, + + without: function() { + var values = $A(arguments); + return this.select(function(value) { + return !values.include(value); + }); + }, + + indexOf: function(object) { + for (var i = 0; i < this.length; i++) + if (this[i] == object) return i; + return -1; + }, + + reverse: function(inline) { + return (inline !== false ? this : this.toArray())._reverse(); + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + } +}); +var Hash = { + _each: function(iterator) { + for (var key in this) { + var value = this[key]; + if (typeof value == 'function') continue; + + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, + + keys: function() { + return this.pluck('key'); + }, + + values: function() { + return this.pluck('value'); + }, + + merge: function(hash) { + return $H(hash).inject($H(this), function(mergedHash, pair) { + mergedHash[pair.key] = pair.value; + return mergedHash; + }); + }, + + toQueryString: function() { + return this.map(function(pair) { + return pair.map(encodeURIComponent).join('='); + }).join('&'); + }, + + inspect: function() { + return '#'; + } +} + +function $H(object) { + var hash = Object.extend({}, object || {}); + Object.extend(hash, Enumerable); + Object.extend(hash, Hash); + return hash; +} +ObjectRange = Class.create(); +Object.extend(ObjectRange.prototype, Enumerable); +Object.extend(ObjectRange.prototype, { + initialize: function(start, end, exclusive) { + this.start = start; + this.end = end; + this.exclusive = exclusive; + }, + + _each: function(iterator) { + var value = this.start; + do { + iterator(value); + value = value.succ(); + } while (this.include(value)); + }, + + include: function(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <= this.end; + } +}); + +var $R = function(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +} + +var Ajax = { + getTransport: function() { + return Try.these( + function() {return new XMLHttpRequest()}, + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')} + ) || false; + }, + + activeRequestCount: 0 +} + +Ajax.Responders = { + responders: [], + + _each: function(iterator) { + this.responders._each(iterator); + }, + + register: function(responderToAdd) { + if (!this.include(responderToAdd)) + this.responders.push(responderToAdd); + }, + + unregister: function(responderToRemove) { + this.responders = this.responders.without(responderToRemove); + }, + + dispatch: function(callback, request, transport, json) { + this.each(function(responder) { + if (responder[callback] && typeof responder[callback] == 'function') { + try { + responder[callback].apply(responder, [request, transport, json]); + } catch (e) {} + } + }); + } +}; + +Object.extend(Ajax.Responders, Enumerable); + +Ajax.Responders.register({ + onCreate: function() { + Ajax.activeRequestCount++; + }, + + onComplete: function() { + Ajax.activeRequestCount--; + } +}); + +Ajax.Base = function() {}; +Ajax.Base.prototype = { + setOptions: function(options) { + this.options = { + method: 'post', + asynchronous: true, + contentType: 'application/x-www-form-urlencoded', + parameters: '' + } + Object.extend(this.options, options || {}); + }, + + responseIsSuccess: function() { + return this.transport.status == undefined + || this.transport.status == 0 + || (this.transport.status >= 200 && this.transport.status < 300); + }, + + responseIsFailure: function() { + return !this.responseIsSuccess(); + } +} + +Ajax.Request = Class.create(); +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Request.prototype = Object.extend(new Ajax.Base(), { + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + this.request(url); + }, + + request: function(url) { + var parameters = this.options.parameters || ''; + if (parameters.length > 0) parameters += '&_='; + + try { + this.url = url; + if (this.options.method == 'get' && parameters.length > 0) + this.url += (this.url.match(/\?/) ? '&' : '?') + parameters; + + Ajax.Responders.dispatch('onCreate', this, this.transport); + + this.transport.open(this.options.method, this.url, + this.options.asynchronous); + + if (this.options.asynchronous) { + this.transport.onreadystatechange = this.onStateChange.bind(this); + setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); + } + + this.setRequestHeaders(); + + var body = this.options.postBody ? this.options.postBody : parameters; + this.transport.send(this.options.method == 'post' ? body : null); + + } catch (e) { + this.dispatchException(e); + } + }, + + setRequestHeaders: function() { + var requestHeaders = + ['X-Requested-With', 'XMLHttpRequest', + 'X-Prototype-Version', Prototype.Version, + 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*']; + + if (this.options.method == 'post') { + requestHeaders.push('Content-type', this.options.contentType); + + /* Force "Connection: close" for Mozilla browsers to work around + * a bug where XMLHttpReqeuest sends an incorrect Content-length + * header. See Mozilla Bugzilla #246651. + */ + if (this.transport.overrideMimeType) + requestHeaders.push('Connection', 'close'); + } + + if (this.options.requestHeaders) + requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); + + for (var i = 0; i < requestHeaders.length; i += 2) + this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState != 1) + this.respondToReadyState(this.transport.readyState); + }, + + header: function(name) { + try { + return this.transport.getResponseHeader(name); + } catch (e) {} + }, + + evalJSON: function() { + try { + return eval('(' + this.header('X-JSON') + ')'); + } catch (e) {} + }, + + evalResponse: function() { + try { + return eval(this.transport.responseText); + } catch (e) { + this.dispatchException(e); + } + }, + + respondToReadyState: function(readyState) { + var event = Ajax.Request.Events[readyState]; + var transport = this.transport, json = this.evalJSON(); + + if (event == 'Complete') { + try { + (this.options['on' + this.transport.status] + || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(transport, json); + } catch (e) { + this.dispatchException(e); + } + + if ((this.header('Content-type') || '').match(/^text\/javascript/i)) + this.evalResponse(); + } + + try { + (this.options['on' + event] || Prototype.emptyFunction)(transport, json); + Ajax.Responders.dispatch('on' + event, this, transport, json); + } catch (e) { + this.dispatchException(e); + } + + /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ + if (event == 'Complete') + this.transport.onreadystatechange = Prototype.emptyFunction; + }, + + dispatchException: function(exception) { + (this.options.onException || Prototype.emptyFunction)(this, exception); + Ajax.Responders.dispatch('onException', this, exception); + } +}); + +Ajax.Updater = Class.create(); + +Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { + initialize: function(container, url, options) { + this.containers = { + success: container.success ? $(container.success) : $(container), + failure: container.failure ? $(container.failure) : + (container.success ? null : $(container)) + } + + this.transport = Ajax.getTransport(); + this.setOptions(options); + + var onComplete = this.options.onComplete || Prototype.emptyFunction; + this.options.onComplete = (function(transport, object) { + this.updateContent(); + onComplete(transport, object); + }).bind(this); + + this.request(url); + }, + + updateContent: function() { + var receiver = this.responseIsSuccess() ? + this.containers.success : this.containers.failure; + var response = this.transport.responseText; + + if (!this.options.evalScripts) + response = response.stripScripts(); + + if (receiver) { + if (this.options.insertion) { + new this.options.insertion(receiver, response); + } else { + Element.update(receiver, response); + } + } + + if (this.responseIsSuccess()) { + if (this.onComplete) + setTimeout(this.onComplete.bind(this), 10); + } + } +}); + +Ajax.PeriodicalUpdater = Class.create(); +Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { + initialize: function(container, url, options) { + this.setOptions(options); + this.onComplete = this.options.onComplete; + + this.frequency = (this.options.frequency || 2); + this.decay = (this.options.decay || 1); + + this.updater = {}; + this.container = container; + this.url = url; + + this.start(); + }, + + start: function() { + this.options.onComplete = this.updateComplete.bind(this); + this.onTimerEvent(); + }, + + stop: function() { + this.updater.onComplete = undefined; + clearTimeout(this.timer); + (this.onComplete || Prototype.emptyFunction).apply(this, arguments); + }, + + updateComplete: function(request) { + if (this.options.decay) { + this.decay = (request.responseText == this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText = request.responseText; + } + this.timer = setTimeout(this.onTimerEvent.bind(this), + this.decay * this.frequency * 1000); + }, + + onTimerEvent: function() { + this.updater = new Ajax.Updater(this.container, this.url, this.options); + } +}); +function $() { + var results = [], element; + for (var i = 0; i < arguments.length; i++) { + element = arguments[i]; + if (typeof element == 'string') + element = document.getElementById(element); + results.push(Element.extend(element)); + } + return results.length < 2 ? results[0] : results; +} + +document.getElementsByClassName = function(className, parentElement) { + var children = ($(parentElement) || document.body).getElementsByTagName('*'); + return $A(children).inject([], function(elements, child) { + if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) + elements.push(Element.extend(child)); + return elements; + }); +} + + + +if (!window.Element) + var Element = new Object(); + +Element.extend = function(element) { + if (!element) return; + if (_nativeExtensions) return element; + + if (!element._extended && element.tagName && element != window) { + var methods = Element.Methods, cache = Element.extend.cache; + for (property in methods) { + var value = methods[property]; + if (typeof value == 'function') + element[property] = cache.findOrStore(value); + } + } + + element._extended = true; + return element; +} + +Element.extend.cache = { + findOrStore: function(value) { + return this[value] = this[value] || function() { + return value.apply(null, [this].concat($A(arguments))); + } + } +} + +Element.Methods = { + visible: function(element) { + return $(element).style.display != 'none'; + }, + + toggle: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + Element[Element.visible(element) ? 'hide' : 'show'](element); + } + }, + + hide: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = 'none'; + } + }, + + show: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = ''; + } + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + }, + + + showTitle: function(element) { + if ($("tooltip")) Element.removeTitle($("tooltip")); + var title = Builder.node('span', {style:'display:none', id:'tooltip', onclick:'Element.removeTitle (this)'}, [ + Builder.node('b',element.title), + Builder.node('em',element.rel) + ]); + element.parentNode.insertBefore(title, element.nextSibling); + Effect.Appear(title, {duration: 0.3}); + }, + + + removeTitle: function(element) { + Effect.Fade(element, {afterFinish:function() {Element.remove(element)},duration:0.3}); + }, + //-------------------------------------- + update: function(element, html) { + $(element).innerHTML = html.stripScripts(); + setTimeout(function() {html.evalScripts()}, 10); + }, + + replace: function(element, html) { + element = $(element); + if (element.outerHTML) { + element.outerHTML = html.stripScripts(); + } else { + var range = element.ownerDocument.createRange(); + range.selectNodeContents(element); + element.parentNode.replaceChild( + range.createContextualFragment(html.stripScripts()), element); + } + setTimeout(function() {html.evalScripts()}, 10); + }, + + getHeight: function(element) { + element = $(element); + return element.offsetHeight; + }, + + classNames: function(element) { + return new Element.ClassNames(element); + }, + + hasClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).include(className); + }, + + addClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).add(className); + }, + + removeClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).remove(className); + }, + + // removes whitespace-only text node children + cleanWhitespace: function(element) { + element = $(element); + for (var i = 0; i < element.childNodes.length; i++) { + var node = element.childNodes[i]; + if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) + Element.remove(node); + } + }, + + empty: function(element) { + return $(element).innerHTML.match(/^\s*$/); + }, + + childOf: function(element, ancestor) { + element = $(element), ancestor = $(ancestor); + while (element = element.parentNode) + if (element == ancestor) return true; + return false; + }, + + scrollTo: function(element) { + element = $(element); + var x = element.x ? element.x : element.offsetLeft, + y = element.y ? element.y : element.offsetTop; + window.scrollTo(x, y); + }, + + getStyle: function(element, style) { + element = $(element); + var value = element.style[style.camelize()]; + if (!value) { + if (document.defaultView && document.defaultView.getComputedStyle) { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css.getPropertyValue(style) : null; + } else if (element.currentStyle) { + value = element.currentStyle[style.camelize()]; + } + } + + if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) + if (Element.getStyle(element, 'position') == 'static') value = 'auto'; + + return value == 'auto' ? null : value; + }, + + setStyle: function(element, style) { + element = $(element); + for (var name in style) + element.style[name.camelize()] = style[name]; + }, + + getDimensions: function(element) { + element = $(element); + if (Element.getStyle(element, 'display') != 'none') + return {width: element.offsetWidth, height: element.offsetHeight}; + + // All *Width and *Height properties give 0 on elements with display none, + // so enable the element temporarily + var els = element.style; + var originalVisibility = els.visibility; + var originalPosition = els.position; + els.visibility = 'hidden'; + els.position = 'absolute'; + els.display = ''; + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + els.display = 'none'; + els.position = originalPosition; + els.visibility = originalVisibility; + return {width: originalWidth, height: originalHeight}; + }, + + makePositioned: function(element) { + element = $(element); + var pos = Element.getStyle(element, 'position'); + if (pos == 'static' || !pos) { + element._madePositioned = true; + element.style.position = 'relative'; + // Opera returns the offset relative to the positioning context, when an + // element is position relative but top and left have not been defined + if (window.opera) { + element.style.top = 0; + element.style.left = 0; + } + } + }, + + undoPositioned: function(element) { + element = $(element); + if (element._madePositioned) { + element._madePositioned = undefined; + element.style.position = + element.style.top = + element.style.left = + element.style.bottom = + element.style.right = ''; + } + }, + + makeClipping: function(element) { + element = $(element); + if (element._overflow) return; + element._overflow = element.style.overflow; + if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') + element.style.overflow = 'hidden'; + }, + + undoClipping: function(element) { + element = $(element); + if (element._overflow) return; + element.style.overflow = element._overflow; + element._overflow = undefined; + } +} + +Object.extend(Element, Element.Methods); + +var _nativeExtensions = false; + +if(!HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) { + var HTMLElement = {} + HTMLElement.prototype = document.createElement('div').__proto__; +} + +Element.addMethods = function(methods) { + Object.extend(Element.Methods, methods || {}); + + if(typeof HTMLElement != 'undefined') { + var methods = Element.Methods, cache = Element.extend.cache; + for (property in methods) { + var value = methods[property]; + if (typeof value == 'function') + HTMLElement.prototype[property] = cache.findOrStore(value); + } + _nativeExtensions = true; + } +} + +Element.addMethods(); + +var Toggle = new Object(); +Toggle.display = Element.toggle; + + +Element.ClassNames = Class.create(); +Element.ClassNames.prototype = { + initialize: function(element) { + this.element = $(element); + }, + + _each: function(iterator) { + this.element.className.split(/\s+/).select(function(name) { + return name.length > 0; + })._each(iterator); + }, + + set: function(className) { + this.element.className = className; + }, + + add: function(classNameToAdd) { + if (this.include(classNameToAdd)) return; + this.set(this.toArray().concat(classNameToAdd).join(' ')); + }, + + remove: function(classNameToRemove) { + if (!this.include(classNameToRemove)) return; + this.set(this.select(function(className) { + return className != classNameToRemove; + }).join(' ')); + }, + + toString: function() { + return this.toArray().join(' '); + } +} + +Object.extend(Element.ClassNames.prototype, Enumerable); +var Selector = Class.create(); +Selector.prototype = { + initialize: function(expression) { + this.params = {classNames: []}; + this.expression = expression.toString().strip(); + this.parseExpression(); + this.compileMatcher(); + }, + + parseExpression: function() { + function abort(message) { throw 'Parse error in selector: ' + message; } + + if (this.expression == '') abort('empty expression'); + + var params = this.params, expr = this.expression, match, modifier, clause, rest; + while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) { + params.attributes = params.attributes || []; + params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''}); + expr = match[1]; + } + + if (expr == '*') return this.params.wildcard = true; + + while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) { + modifier = match[1], clause = match[2], rest = match[3]; + switch (modifier) { + case '#': params.id = clause; break; + case '.': params.classNames.push(clause); break; + case '': + case undefined: params.tagName = clause.toUpperCase(); break; + default: abort(expr.inspect()); + } + expr = rest; + } + + if (expr.length > 0) abort(expr.inspect()); + }, + + buildMatchExpression: function() { + var params = this.params, conditions = [], clause; + + if (params.wildcard) + conditions.push('true'); + if (clause = params.id) + conditions.push('element.id == ' + clause.inspect()); + if (clause = params.tagName) + conditions.push('element.tagName.toUpperCase() == ' + clause.inspect()); + if ((clause = params.classNames).length > 0) + for (var i = 0; i < clause.length; i++) + conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')'); + if (clause = params.attributes) { + clause.each(function(attribute) { + var value = 'element.getAttribute(' + attribute.name.inspect() + ')'; + var splitValueBy = function(delimiter) { + return value + ' && ' + value + '.split(' + delimiter.inspect() + ')'; + } + + switch (attribute.operator) { + case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break; + case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break; + case '|=': conditions.push( + splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect() + ); break; + case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break; + case '': + case undefined: conditions.push(value + ' != null'); break; + default: throw 'Unknown operator ' + attribute.operator + ' in selector'; + } + }); + } + + return conditions.join(' && '); + }, + + compileMatcher: function() { + this.match = new Function('element', 'if (!element.tagName) return false; \ + return ' + this.buildMatchExpression()); + }, + + findElements: function(scope) { + var element; + + if (element = $(this.params.id)) + if (this.match(element)) + if (!scope || Element.childOf(element, scope)) + return [element]; + + scope = (scope || document).getElementsByTagName(this.params.tagName || '*'); + + var results = []; + for (var i = 0; i < scope.length; i++) + if (this.match(element = scope[i])) + results.push(Element.extend(element)); + + return results; + }, + + toString: function() { + return this.expression; + } +} + +function $$() { + return $A(arguments).map(function(expression) { + return expression.strip().split(/\s+/).inject([null], function(results, expr) { + var selector = new Selector(expr); + return results.map(selector.findElements.bind(selector)).flatten(); + }); + }).flatten(); +} +/*--------------------------------------------------------------------------*/ + +Abstract.EventObserver = function() {} +Abstract.EventObserver.prototype = { + initialize: function(element, callback) { + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + if (this.element.tagName.toLowerCase() == 'form') + this.registerFormCallbacks(); + else + this.registerCallback(this.element); + }, + + onElementEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + }, + + registerFormCallbacks: function() { + var elements = Form.getElements(this.element); + for (var i = 0; i < elements.length; i++) + this.registerCallback(elements[i]); + }, + + registerCallback: function(element) { + if (element.type) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + Event.observe(element, 'click', this.onElementEvent.bind(this)); + break; + case 'password': + case 'text': + case 'textarea': + case 'select-one': + case 'select-multiple': + Event.observe(element, 'change', this.onElementEvent.bind(this)); + break; + } + } + } +} + +if (!window.Event) { + var Event = new Object(); +} + +Object.extend(Event, { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + + element: function(event) { + return event.target || event.srcElement; + }, + + isLeftClick: function(event) { + return (((event.which) && (event.which == 1)) || + ((event.button) && (event.button == 1))); + }, + + pointerX: function(event) { + return event.pageX || (event.clientX + + (document.documentElement.scrollLeft || document.body.scrollLeft)); + }, + + pointerY: function(event) { + return event.pageY || (event.clientY + + (document.documentElement.scrollTop || document.body.scrollTop)); + }, + + stop: function(event) { + if (event.preventDefault) { + event.preventDefault(); + event.stopPropagation(); + } else { + event.returnValue = false; + event.cancelBubble = true; + } + }, + + // find the first node with the given tagName, starting from the + // node the event was triggered on; traverses the DOM upwards + findElement: function(event, tagName) { + var element = Event.element(event); + while (element.parentNode && (!element.tagName || + (element.tagName.toUpperCase() != tagName.toUpperCase()))) + element = element.parentNode; + return element; + }, + + observers: false, + + _observeAndCache: function(element, name, observer, useCapture) { + if (!this.observers) this.observers = []; + if (element.addEventListener) { + this.observers.push([element, name, observer, useCapture]); + element.addEventListener(name, observer, useCapture); + } else if (element.attachEvent) { + this.observers.push([element, name, observer, useCapture]); + element.attachEvent('on' + name, observer); + } + }, + + unloadCache: function() { + if (!Event.observers) return; + for (var i = 0; i < Event.observers.length; i++) { + Event.stopObserving.apply(this, Event.observers[i]); + Event.observers[i][0] = null; + } + Event.observers = false; + }, + + observe: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.attachEvent)) + name = 'keydown'; + + this._observeAndCache(element, name, observer, useCapture); + }, + + stopObserving: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.detachEvent)) + name = 'keydown'; + + if (element.removeEventListener) { + element.removeEventListener(name, observer, useCapture); + } else if (element.detachEvent) { + element.detachEvent('on' + name, observer); + } + } +}); + +/* prevent memory leaks in IE */ +if (navigator.appVersion.match(/\bMSIE\b/)) + Event.observe(window, 'unload', Event.unloadCache, false); +var Position = { + // set to true if needed, warning: firefox performance problems + // NOT neeeded for page scrolling, only if draggable contained in + // scrollable elements + includeScrollOffsets: false, + + // must be called before calling withinIncludingScrolloffset, every time the + // page is scrolled + prepare: function() { + this.deltaX = window.pageXOffset + || document.documentElement.scrollLeft + || document.body.scrollLeft + || 0; + this.deltaY = window.pageYOffset + || document.documentElement.scrollTop + || document.body.scrollTop + || 0; + }, + + realOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.scrollTop || 0; + valueL += element.scrollLeft || 0; + element = element.parentNode; + } while (element); + return [valueL, valueT]; + }, + + cumulativeOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return [valueL, valueT]; + }, + + positionedOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + if (element) { + p = Element.getStyle(element, 'position'); + if (p == 'relative' || p == 'absolute') break; + } + } while (element); + return [valueL, valueT]; + }, + + offsetParent: function(element) { + if (element.offsetParent) return element.offsetParent; + if (element == document.body) return element; + + while ((element = element.parentNode) && element != document.body) + if (Element.getStyle(element, 'position') != 'static') + return element; + + return document.body; + }, + + // caches x/y coordinate pair to use with overlap + within: function(element, x, y) { + if (this.includeScrollOffsets) + return this.withinIncludingScrolloffsets(element, x, y); + this.xcomp = x; + this.ycomp = y; + this.offset = this.cumulativeOffset(element); + + return (y >= this.offset[1] && + y < this.offset[1] + element.offsetHeight && + x >= this.offset[0] && + x < this.offset[0] + element.offsetWidth); + }, + + withinIncludingScrolloffsets: function(element, x, y) { + var offsetcache = this.realOffset(element); + + this.xcomp = x + offsetcache[0] - this.deltaX; + this.ycomp = y + offsetcache[1] - this.deltaY; + this.offset = this.cumulativeOffset(element); + + return (this.ycomp >= this.offset[1] && + this.ycomp < this.offset[1] + element.offsetHeight && + this.xcomp >= this.offset[0] && + this.xcomp < this.offset[0] + element.offsetWidth); + }, + + // within must be called directly before + overlap: function(mode, element) { + if (!mode) return 0; + if (mode == 'vertical') + return ((this.offset[1] + element.offsetHeight) - this.ycomp) / + element.offsetHeight; + if (mode == 'horizontal') + return ((this.offset[0] + element.offsetWidth) - this.xcomp) / + element.offsetWidth; + }, + + clone: function(source, target) { + source = $(source); + target = $(target); + target.style.position = 'absolute'; + var offsets = this.cumulativeOffset(source); + target.style.top = offsets[1] + 'px'; + target.style.left = offsets[0] + 'px'; + target.style.width = source.offsetWidth + 'px'; + target.style.height = source.offsetHeight + 'px'; + }, + + page: function(forElement) { + var valueT = 0, valueL = 0; + + var element = forElement; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + + // Safari fix + if (element.offsetParent==document.body) + if (Element.getStyle(element,'position')=='absolute') break; + + } while (element = element.offsetParent); + + element = forElement; + do { + valueT -= element.scrollTop || 0; + valueL -= element.scrollLeft || 0; + } while (element = element.parentNode); + + return [valueL, valueT]; + }, + + clone: function(source, target) { + var options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || {}) + + // find page position of source + source = $(source); + var p = Position.page(source); + + // find coordinate system to use + target = $(target); + var delta = [0, 0]; + var parent = null; + // delta [0,0] will do fine with position: fixed elements, + // position:absolute needs offsetParent deltas + if (Element.getStyle(target,'position') == 'absolute') { + parent = Position.offsetParent(target); + delta = Position.page(parent); + } + + // correct by body offsets (fixes Safari) + if (parent == document.body) { + delta[0] -= document.body.offsetLeft; + delta[1] -= document.body.offsetTop; + } + + // set position + if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + if(options.setWidth) target.style.width = source.offsetWidth + 'px'; + if(options.setHeight) target.style.height = source.offsetHeight + 'px'; + }, + + absolutize: function(element) { + element = $(element); + if (element.style.position == 'absolute') return; + Position.prepare(); + + var offsets = Position.positionedOffset(element); + var top = offsets[1]; + var left = offsets[0]; + var width = element.clientWidth; + var height = element.clientHeight; + + element._originalLeft = left - parseFloat(element.style.left || 0); + element._originalTop = top - parseFloat(element.style.top || 0); + element._originalWidth = element.style.width; + element._originalHeight = element.style.height; + + element.style.position = 'absolute'; + element.style.top = top + 'px';; + element.style.left = left + 'px';; + element.style.width = width + 'px';; + element.style.height = height + 'px';; + }, + + relativize: function(element) { + element = $(element); + if (element.style.position == 'relative') return; + Position.prepare(); + + element.style.position = 'relative'; + var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); + var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); + + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.height = element._originalHeight; + element.style.width = element._originalWidth; + } +} + +// Safari returns margins on body which is incorrect if the child is absolutely +// positioned. For performance reasons, redefine Position.cumulativeOffset for +// KHTML/WebKit only. +if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { + Position.cumulativeOffset = function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + if (element.offsetParent == document.body) + if (Element.getStyle(element, 'position') == 'absolute') break; + + element = element.offsetParent; + } while (element); + + return [valueL, valueT]; + } +} + +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// Contributors: +// Justin Palmer (http://encytemedia.com/) +// Mark Pilgrim (http://diveintomark.org/) +// Martin Bialasinki +// +// See scriptaculous.js for full license. + +// converts rgb() and #xxx to #xxxxxx format, +// returns self (or first argument) if not convertable +String.prototype.parseColor = function() { + var color = '#'; + if(this.slice(0,4) == 'rgb(') { + var cols = this.slice(4,this.length-1).split(','); + var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); + } else { + if(this.slice(0,1) == '#') { + if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); + if(this.length==7) color = this.toLowerCase(); + } + } + return(color.length==7 ? color : (arguments[0] || this)); +} + +/*--------------------------------------------------------------------------*/ + +Element.collectTextNodes = function(element) { + return $A($(element).childNodes).collect( function(node) { + return (node.nodeType==3 ? node.nodeValue : + (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); + }).flatten().join(''); +} + +Element.collectTextNodesIgnoreClass = function(element, className) { + return $A($(element).childNodes).collect( function(node) { + return (node.nodeType==3 ? node.nodeValue : + ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? + Element.collectTextNodesIgnoreClass(node, className) : '')); + }).flatten().join(''); +} + +Element.setContentZoom = function(element, percent) { + element = $(element); + Element.setStyle(element, {fontSize: (percent/100) + 'em'}); + if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); +} + +Element.getOpacity = function(element){ + var opacity; + if (opacity = Element.getStyle(element, 'opacity')) + return parseFloat(opacity); + if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/)) + if(opacity[1]) return parseFloat(opacity[1]) / 100; + return 1.0; +} + +Element.setOpacity = function(element, value){ + element= $(element); + if (value == 1){ + Element.setStyle(element, { opacity: + (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? + 0.999999 : null }); + if(/MSIE/.test(navigator.userAgent)) + Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')}); + } else { + if(value < 0.00001) value = 0; + Element.setStyle(element, {opacity: value}); + if(/MSIE/.test(navigator.userAgent)) + Element.setStyle(element, + { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') + + 'alpha(opacity='+value*100+')' }); + } +} + +Element.getInlineOpacity = function(element){ + return $(element).style.opacity || ''; +} + +Element.childrenWithClassName = function(element, className, findFirst) { + var classNameRegExp = new RegExp("(^|\\s)" + className + "(\\s|$)"); + var results = $A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select']( function(c) { + return (c.className && c.className.match(classNameRegExp)); + }); + if(!results) results = []; + return results; +} + +Element.forceRerendering = function(element) { + try { + element = $(element); + var n = document.createTextNode(' '); + element.appendChild(n); + element.removeChild(n); + } catch(e) { } +}; + + + +/*--------------------------------------------------------------------------*/ + +var Effect = { + tagifyText: function(element) { + if(typeof Builder == 'undefined') + throw("Effect.tagifyText requires including script.aculo.us' builder.js library"); + + var tagifyStyle = 'position:relative'; + if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1'; + element = $(element); + $A(element.childNodes).each( function(child) { + if(child.nodeType==3) { + child.nodeValue.toArray().each( function(character) { + element.insertBefore( + Builder.node('span',{style: tagifyStyle}, + character == ' ' ? String.fromCharCode(160) : character), + child); + }); + Element.remove(child); + } + }); + }, + multiple: function(element, effect) { + var elements; + if(((typeof element == 'object') || + (typeof element == 'function')) && + (element.length)) + elements = element; + else + elements = $(element).childNodes; + + var options = Object.extend({ + speed: 0.1, + delay: 0.0 + }, arguments[2] || {}); + var masterDelay = options.delay; + + $A(elements).each( function(element, index) { + new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay })); + }); + }, + PAIRS: { + 'slide': ['SlideDown','SlideUp'], + 'blind': ['BlindDown','BlindUp'], + 'appear': ['Appear','Fade'] + }, + toggle: function(element, effect) { + element = $(element); + effect = (effect || 'appear').toLowerCase(); + var options = Object.extend({ + queue: { position:'end', scope:(element.id || 'global'), limit: 1 } + }, arguments[2] || {}); + Effect[element.visible() ? + Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); + } +}; + +var Effect2 = Effect; // deprecated + +/* ------------- transitions ------------- */ + +Effect.Transitions = {} + +Effect.Transitions.linear = Prototype.K; + +Effect.Transitions.sinoidal = function(pos) { + return (-Math.cos(pos*Math.PI)/2) + 0.5; +} +Effect.Transitions.reverse = function(pos) { + return 1-pos; +} +Effect.Transitions.flicker = function(pos) { + return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; +} +Effect.Transitions.wobble = function(pos) { + return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; +} +Effect.Transitions.pulse = function(pos) { + return (Math.floor(pos*10) % 2 == 0 ? + (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10))); +} +Effect.Transitions.none = function(pos) { + return 0; +} +Effect.Transitions.full = function(pos) { + return 1; +} + +/* ------------- core effects ------------- */ + +Effect.ScopedQueue = Class.create(); +Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), { + initialize: function() { + this.effects = []; + this.interval = null; + }, + _each: function(iterator) { + this.effects._each(iterator); + }, + add: function(effect) { + var timestamp = new Date().getTime(); + + var position = (typeof effect.options.queue == 'string') ? + effect.options.queue : effect.options.queue.position; + + switch(position) { + case 'front': + // move unstarted effects after this effect + this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { + e.startOn += effect.finishOn; + e.finishOn += effect.finishOn; + }); + break; + case 'end': + // start effect after last queued effect has finished + timestamp = this.effects.pluck('finishOn').max() || timestamp; + break; + } + + effect.startOn += timestamp; + effect.finishOn += timestamp; + + if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) + this.effects.push(effect); + + if(!this.interval) + this.interval = setInterval(this.loop.bind(this), 40); + }, + remove: function(effect) { + this.effects = this.effects.reject(function(e) { return e==effect }); + if(this.effects.length == 0) { + clearInterval(this.interval); + this.interval = null; + } + }, + loop: function() { + var timePos = new Date().getTime(); + this.effects.invoke('loop', timePos); + } +}); + +Effect.Queues = { + instances: $H(), + get: function(queueName) { + if(typeof queueName != 'string') return queueName; + + if(!this.instances[queueName]) + this.instances[queueName] = new Effect.ScopedQueue(); + + return this.instances[queueName]; + } +} +Effect.Queue = Effect.Queues.get('global'); + +Effect.DefaultOptions = { + transition: Effect.Transitions.sinoidal, + duration: 1.0, // seconds + fps: 25.0, // max. 25fps due to Effect.Queue implementation + sync: false, // true for combining + from: 0.0, + to: 1.0, + delay: 0.0, + queue: 'parallel' +} + +Effect.Base = function() {}; +Effect.Base.prototype = { + position: null, + start: function(options) { + this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {}); + this.currentFrame = 0; + this.state = 'idle'; + this.startOn = this.options.delay*1000; + this.finishOn = this.startOn + (this.options.duration*1000); + this.event('beforeStart'); + if(!this.options.sync) + Effect.Queues.get(typeof this.options.queue == 'string' ? + 'global' : this.options.queue.scope).add(this); + }, + loop: function(timePos) { + if(timePos >= this.startOn) { + if(timePos >= this.finishOn) { + this.render(1.0); + this.cancel(); + this.event('beforeFinish'); + if(this.finish) this.finish(); + this.event('afterFinish'); + return; + } + var pos = (timePos - this.startOn) / (this.finishOn - this.startOn); + var frame = Math.round(pos * this.options.fps * this.options.duration); + if(frame > this.currentFrame) { + this.render(pos); + this.currentFrame = frame; + } + } + }, + render: function(pos) { + if(this.state == 'idle') { + this.state = 'running'; + this.event('beforeSetup'); + if(this.setup) this.setup(); + this.event('afterSetup'); + } + if(this.state == 'running') { + if(this.options.transition) pos = this.options.transition(pos); + pos *= (this.options.to-this.options.from); + pos += this.options.from; + this.position = pos; + this.event('beforeUpdate'); + if(this.update) this.update(pos); + this.event('afterUpdate'); + } + }, + cancel: function() { + if(!this.options.sync) + Effect.Queues.get(typeof this.options.queue == 'string' ? + 'global' : this.options.queue.scope).remove(this); + this.state = 'finished'; + }, + event: function(eventName) { + if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); + if(this.options[eventName]) this.options[eventName](this); + }, + inspect: function() { + return '#'; + } +} + + + +Effect.Opacity = Class.create(); +Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { + initialize: function(element) { + this.element = $(element); + // make this work on IE on elements without 'layout' + if(/MSIE/.test(navigator.userAgent) && (!this.element.currentStyle.hasLayout)) + this.element.setStyle({zoom: 1}); + var options = Object.extend({ + from: this.element.getOpacity() || 0.0, + to: 1.0 + }, arguments[1] || {}); + this.start(options); + }, + update: function(position) { + this.element.setOpacity(position); + } +}); + +Effect.Move = Class.create(); +Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), { + initialize: function(element) { + this.element = $(element); + var options = Object.extend({ + x: 0, + y: 0, + mode: 'relative' + }, arguments[1] || {}); + this.start(options); + }, + setup: function() { + // Bug in Opera: Opera returns the "real" position of a static element or + // relative element that does not have top/left explicitly set. + // ==> Always set top and left for position relative elements in your stylesheets + // (to 0 if you do not need them) + this.element.makePositioned(); + this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); + this.originalTop = parseFloat(this.element.getStyle('top') || '0'); + if(this.options.mode == 'absolute') { + // absolute movement, so we need to calc deltaX and deltaY + this.options.x = this.options.x - this.originalLeft; + this.options.y = this.options.y - this.originalTop; + } + }, + update: function(position) { + this.element.setStyle({ + left: Math.round(this.options.x * position + this.originalLeft) + 'px', + top: Math.round(this.options.y * position + this.originalTop) + 'px' + }); + } +}); + +// for backwards compatibility +Effect.MoveBy = function(element, toTop, toLeft) { + return new Effect.Move(element, + Object.extend({ x: toLeft, y: toTop }, arguments[3] || {})); +}; + + + + +['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom', + 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each( + function(f) { Element.Methods[f] = Element[f]; } +); + +Element.Methods.visualEffect = function(element, effect, options) { + s = effect.gsub(/_/, '-').camelize(); + effect_class = s.charAt(0).toUpperCase() + s.substring(1); + new Effect[effect_class](element, options); + return $(element); +}; + +Element.addMethods(); + +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// (c) 2005 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) +// +// See scriptaculous.js for full license. + +/*--------------------------------------------------------------------------*/ + +if(typeof Effect == 'undefined') + throw("dragdrop.js requires including script.aculo.us' effects.js library"); + +var Droppables = { + drops: [], + + remove: function(element) { + this.drops = this.drops.reject(function(d) { return d.element==$(element) }); + }, + + add: function(element) { + element = $(element); + var options = Object.extend({ + greedy: true, + hoverclass: null, + tree: false + }, arguments[1] || {}); + + // cache containers + if(options.containment) { + options._containers = []; + var containment = options.containment; + if((typeof containment == 'object') && + (containment.constructor == Array)) { + containment.each( function(c) { options._containers.push($(c)) }); + } else { + options._containers.push($(containment)); + } + } + + if(options.accept) options.accept = [options.accept].flatten(); + + Element.makePositioned(element); // fix IE + options.element = element; + + this.drops.push(options); + }, + + findDeepestChild: function(drops) { + deepest = drops[0]; + + for (i = 1; i < drops.length; ++i) + if (Element.isParent(drops[i].element, deepest.element)) + deepest = drops[i]; + + return deepest; + }, + + isContained: function(element, drop) { + var containmentNode; + if(drop.tree) { + containmentNode = element.treeNode; + } else { + containmentNode = element.parentNode; + } + return drop._containers.detect(function(c) { return containmentNode == c }); + }, + + isAffected: function(point, element, drop) { + return ( + (drop.element!=element) && + ((!drop._containers) || + this.isContained(element, drop)) && + ((!drop.accept) || + (Element.classNames(element).detect( + function(v) { return drop.accept.include(v) } ) )) && + Position.within(drop.element, point[0], point[1]) ); + }, + + deactivate: function(drop) { + if(drop.hoverclass) + Element.removeClassName(drop.element, drop.hoverclass); + this.last_active = null; + }, + + activate: function(drop) { + if(drop.hoverclass) + Element.addClassName(drop.element, drop.hoverclass); + this.last_active = drop; + }, + + show: function(point, element) { + if(!this.drops.length) return; + var affected = []; + + if(this.last_active) this.deactivate(this.last_active); + this.drops.each( function(drop) { + if(Droppables.isAffected(point, element, drop)) + affected.push(drop); + }); + + if(affected.length>0) { + drop = Droppables.findDeepestChild(affected); + Position.within(drop.element, point[0], point[1]); + if(drop.onHover) + drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); + + Droppables.activate(drop); + } + }, + + fire: function(event, element) { + if(!this.last_active) return; + Position.prepare(); + + if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) + if (this.last_active.onDrop) + this.last_active.onDrop(element, this.last_active.element, event); + }, + + reset: function() { + if(this.last_active) + this.deactivate(this.last_active); + } +} + +var Draggables = { + drags: [], + observers: [], + + register: function(draggable) { + if(this.drags.length == 0) { + this.eventMouseUp = this.endDrag.bindAsEventListener(this); + this.eventMouseMove = this.updateDrag.bindAsEventListener(this); + this.eventKeypress = this.keyPress.bindAsEventListener(this); + + Event.observe(document, "mouseup", this.eventMouseUp); + Event.observe(document, "mousemove", this.eventMouseMove); + Event.observe(document, "keypress", this.eventKeypress); + } + this.drags.push(draggable); + }, + + unregister: function(draggable) { + this.drags = this.drags.reject(function(d) { return d==draggable }); + if(this.drags.length == 0) { + Event.stopObserving(document, "mouseup", this.eventMouseUp); + Event.stopObserving(document, "mousemove", this.eventMouseMove); + Event.stopObserving(document, "keypress", this.eventKeypress); + } + }, + + activate: function(draggable) { + window.focus(); // allows keypress events if window isn't currently focused, fails for Safari + this.activeDraggable = draggable; + }, + + deactivate: function() { + this.activeDraggable = null; + }, + + updateDrag: function(event) { + if(!this.activeDraggable) return; + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + // Mozilla-based browsers fire successive mousemove events with + // the same coordinates, prevent needless redrawing (moz bug?) + if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; + this._lastPointer = pointer; + this.activeDraggable.updateDrag(event, pointer); + }, + + endDrag: function(event) { + if(!this.activeDraggable) return; + this._lastPointer = null; + this.activeDraggable.endDrag(event); + this.activeDraggable = null; + }, + + keyPress: function(event) { + if(this.activeDraggable) + this.activeDraggable.keyPress(event); + }, + + addObserver: function(observer) { + this.observers.push(observer); + this._cacheObserverCallbacks(); + }, + + removeObserver: function(element) { // element instead of observer fixes mem leaks + this.observers = this.observers.reject( function(o) { return o.element==element }); + this._cacheObserverCallbacks(); + }, + + notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag' + if(this[eventName+'Count'] > 0) + this.observers.each( function(o) { + if(o[eventName]) o[eventName](eventName, draggable, event); + }); + }, + + _cacheObserverCallbacks: function() { + ['onStart','onEnd','onDrag'].each( function(eventName) { + Draggables[eventName+'Count'] = Draggables.observers.select( + function(o) { return o[eventName]; } + ).length; + }); + } +} + + + +var Draggable = Class.create(); +Draggable._revertCache = {}; +Draggable._dragging = {}; + +Draggable.prototype = { + initialize: function(element) { + var options = Object.extend({ + handle: false, + starteffect: function(element) { + element._opacity = Element.getOpacity(element); + Draggable._dragging[element] = true; + new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); + }, + reverteffect: function(element, top_offset, left_offset) { + var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; + Draggable._revertCache[element] = + new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur, + queue: {scope:'_draggable', position:'end'} + }); + }, + endeffect: function(element) { + var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0; + new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, + queue: {scope:'_draggable', position:'end'}, + afterFinish: function(){ Draggable._dragging[element] = false } + }); + }, + zindex: 1000, + revert: false, + scroll: false, + scrollSensitivity: 20, + scrollSpeed: 15, + snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] } + }, arguments[1] || {}); + + this.element = $(element); + + if(options.handle && (typeof options.handle == 'string')) { + var h = Element.childrenWithClassName(this.element, options.handle, true); + if(h.length>0) this.handle = h[0]; + } + if(!this.handle) this.handle = $(options.handle); + if(!this.handle) this.handle = this.element; + + if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) + options.scroll = $(options.scroll); + + Element.makePositioned(this.element); // fix IE + + this.delta = this.currentDelta(); + this.options = options; + this.dragging = false; + + this.eventMouseDown = this.initDrag.bindAsEventListener(this); + Event.observe(this.handle, "mousedown", this.eventMouseDown); + + Draggables.register(this); + }, + + destroy: function() { + Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); + Draggables.unregister(this); + }, + + currentDelta: function() { + return([ + parseInt(Element.getStyle(this.element,'left') || '0'), + parseInt(Element.getStyle(this.element,'top') || '0')]); + }, + + initDrag: function(event) { + if(typeof Draggable._dragging[this.element] != undefined && + Draggable._dragging[this.element]) return; + if(Event.isLeftClick(event)) { + // abort on form elements, fixes a Firefox issue + var src = Event.element(event); + if(src.tagName && ( + src.tagName=='INPUT' || + src.tagName=='SELECT' || + src.tagName=='OPTION' || + src.tagName=='BUTTON' || + src.tagName=='TEXTAREA')) return; + + if(Draggable._revertCache[this.element]) { + Draggable._revertCache[this.element].cancel(); + Draggable._revertCache[this.element] = null; + } + + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + var pos = Position.cumulativeOffset(this.element); + this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); + + Draggables.activate(this); + Event.stop(event); + } + }, + + startDrag: function(event) { + this.dragging = true; + + if(this.options.zindex) { + this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); + this.element.style.zIndex = this.options.zindex; + } + + if(this.options.ghosting) { + this._clone = this.element.cloneNode(true); + Position.absolutize(this.element); + this.element.parentNode.insertBefore(this._clone, this.element); + } + + if(this.options.scroll) { + if (this.options.scroll == window) { + var where = this._getWindowScroll(this.options.scroll); + this.originalScrollLeft = where.left; + this.originalScrollTop = where.top; + } else { + this.originalScrollLeft = this.options.scroll.scrollLeft; + this.originalScrollTop = this.options.scroll.scrollTop; + } + } + + Draggables.notify('onStart', this, event); + if(this.options.starteffect) this.options.starteffect(this.element); + }, + + updateDrag: function(event, pointer) { + if(!this.dragging) this.startDrag(event); + Position.prepare(); + Droppables.show(pointer, this.element); + Draggables.notify('onDrag', this, event); + this.draw(pointer); + if(this.options.change) this.options.change(this); + + if(this.options.scroll) { + this.stopScrolling(); + + var p; + if (this.options.scroll == window) { + with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; } + } else { + p = Position.page(this.options.scroll); + p[0] += this.options.scroll.scrollLeft; + p[1] += this.options.scroll.scrollTop; + p.push(p[0]+this.options.scroll.offsetWidth); + p.push(p[1]+this.options.scroll.offsetHeight); + } + var speed = [0,0]; + if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity); + if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity); + if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity); + if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity); + this.startScrolling(speed); + } + + // fix AppleWebKit rendering + if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); + + Event.stop(event); + }, + + finishDrag: function(event, success) { + this.dragging = false; + + if(this.options.ghosting) { + Position.relativize(this.element); + Element.remove(this._clone); + this._clone = null; + } + + if(success) Droppables.fire(event, this.element); + Draggables.notify('onEnd', this, event); + + var revert = this.options.revert; + if(revert && typeof revert == 'function') revert = revert(this.element); + + var d = this.currentDelta(); + if(revert && this.options.reverteffect) { + this.options.reverteffect(this.element, + d[1]-this.delta[1], d[0]-this.delta[0]); + } else { + this.delta = d; + } + + if(this.options.zindex) + this.element.style.zIndex = this.originalZ; + + if(this.options.endeffect) + this.options.endeffect(this.element); + + Draggables.deactivate(this); + Droppables.reset(); + }, + + keyPress: function(event) { + if(event.keyCode!=Event.KEY_ESC) return; + this.finishDrag(event, false); + Event.stop(event); + }, + + endDrag: function(event) { + if(!this.dragging) return; + this.stopScrolling(); + this.finishDrag(event, true); + Event.stop(event); + }, + + draw: function(point) { + var pos = Position.cumulativeOffset(this.element); + var d = this.currentDelta(); + pos[0] -= d[0]; pos[1] -= d[1]; + + if(this.options.scroll && (this.options.scroll != window)) { + pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; + pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; + } + + var p = [0,1].map(function(i){ + return (point[i]-pos[i]-this.offset[i]) + }.bind(this)); + + if(this.options.snap) { + if(typeof this.options.snap == 'function') { + p = this.options.snap(p[0],p[1],this); + } else { + if(this.options.snap instanceof Array) { + p = p.map( function(v, i) { + return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this)) + } else { + p = p.map( function(v) { + return Math.round(v/this.options.snap)*this.options.snap }.bind(this)) + } + }} + + var style = this.element.style; + if((!this.options.constraint) || (this.options.constraint=='horizontal')) + style.left = p[0] + "px"; + if((!this.options.constraint) || (this.options.constraint=='vertical')) + style.top = p[1] + "px"; + if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering + }, + + stopScrolling: function() { + if(this.scrollInterval) { + clearInterval(this.scrollInterval); + this.scrollInterval = null; + Draggables._lastScrollPointer = null; + } + }, + + startScrolling: function(speed) { + if(!(speed[0] || speed[1])) return; + this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed]; + this.lastScrolled = new Date(); + this.scrollInterval = setInterval(this.scroll.bind(this), 10); + }, + + scroll: function() { + var current = new Date(); + var delta = current - this.lastScrolled; + this.lastScrolled = current; + if(this.options.scroll == window) { + with (this._getWindowScroll(this.options.scroll)) { + if (this.scrollSpeed[0] || this.scrollSpeed[1]) { + var d = delta / 1000; + this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] ); + } + } + } else { + this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000; + this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000; + } + + Position.prepare(); + Droppables.show(Draggables._lastPointer, this.element); + Draggables.notify('onDrag', this); + Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer); + Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000; + Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000; + if (Draggables._lastScrollPointer[0] < 0) + Draggables._lastScrollPointer[0] = 0; + if (Draggables._lastScrollPointer[1] < 0) + Draggables._lastScrollPointer[1] = 0; + this.draw(Draggables._lastScrollPointer); + + if(this.options.change) this.options.change(this); + }, + + _getWindowScroll: function(w) { + var T, L, W, H; + with (w.document) { + if (w.document.documentElement && documentElement.scrollTop) { + T = documentElement.scrollTop; + L = documentElement.scrollLeft; + } else if (w.document.body) { + T = body.scrollTop; + L = body.scrollLeft; + } + if (w.innerWidth) { + W = w.innerWidth; + H = w.innerHeight; + } else if (w.document.documentElement && documentElement.clientWidth) { + W = documentElement.clientWidth; + H = documentElement.clientHeight; + } else { + W = body.offsetWidth; + H = body.offsetHeight + } + } + return { top: T, left: L, width: W, height: H }; + } +} + +/*--------------------------------------------------------------------------*/ + +var SortableObserver = Class.create(); +SortableObserver.prototype = { + initialize: function(element, observer) { + this.element = $(element); + this.observer = observer; + this.lastValue = Sortable.serialize(this.element); + }, + + onStart: function() { + this.lastValue = Sortable.serialize(this.element); + }, + + onEnd: function() { + Sortable.unmark(); + if(this.lastValue != Sortable.serialize(this.element)) + this.observer(this.element) + } +} + +var Sortable = { + sortables: {}, + + _findRootElement: function(element) { + while (element.tagName != "BODY") { + if(element.id && Sortable.sortables[element.id]) return element; + element = element.parentNode; + } + }, + + options: function(element) { + element = Sortable._findRootElement($(element)); + if(!element) return; + return Sortable.sortables[element.id]; + }, + + destroy: function(element){ + var s = Sortable.options(element); + + if(s) { + Draggables.removeObserver(s.element); + s.droppables.each(function(d){ Droppables.remove(d) }); + s.draggables.invoke('destroy'); + + delete Sortable.sortables[s.element.id]; + } + }, + + create: function(element) { + element = $(element); + var options = Object.extend({ + element: element, + tag: 'li', // assumes li children, override with tag: 'tagname' + dropOnEmpty: false, + tree: false, + treeTag: 'ul', + overlap: 'vertical', // one of 'vertical', 'horizontal' + constraint: 'vertical', // one of 'vertical', 'horizontal', false + containment: element, // also takes array of elements (or id's); or false + handle: false, // or a CSS class + only: false, + hoverclass: null, + ghosting: false, + scroll: false, + scrollSensitivity: 20, + scrollSpeed: 15, + format: /^[^_]*_(.*)$/, + onChange: Prototype.emptyFunction, + onUpdate: Prototype.emptyFunction + }, arguments[1] || {}); + + // clear any old sortable with same element + this.destroy(element); + + // build options for the draggables + var options_for_draggable = { + revert: true, + scroll: options.scroll, + scrollSpeed: options.scrollSpeed, + scrollSensitivity: options.scrollSensitivity, + ghosting: options.ghosting, + constraint: options.constraint, + handle: options.handle }; + + if(options.starteffect) + options_for_draggable.starteffect = options.starteffect; + + if(options.reverteffect) + options_for_draggable.reverteffect = options.reverteffect; + else + if(options.ghosting) options_for_draggable.reverteffect = function(element) { + element.style.top = 0; + element.style.left = 0; + }; + + if(options.endeffect) + options_for_draggable.endeffect = options.endeffect; + + if(options.zindex) + options_for_draggable.zindex = options.zindex; + + // build options for the droppables + var options_for_droppable = { + overlap: options.overlap, + containment: options.containment, + tree: options.tree, + hoverclass: options.hoverclass, + onHover: Sortable.onHover + //greedy: !options.dropOnEmpty + } + + var options_for_tree = { + onHover: Sortable.onEmptyHover, + overlap: options.overlap, + containment: options.containment, + hoverclass: options.hoverclass + } + + // fix for gecko engine + Element.cleanWhitespace(element); + + options.draggables = []; + options.droppables = []; + + // drop on empty handling + if(options.dropOnEmpty || options.tree) { + Droppables.add(element, options_for_tree); + options.droppables.push(element); + } + + (this.findElements(element, options) || []).each( function(e) { + // handles are per-draggable + var handle = options.handle ? + Element.childrenWithClassName(e, options.handle)[0] : e; + options.draggables.push( + new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); + Droppables.add(e, options_for_droppable); + if(options.tree) e.treeNode = element; + options.droppables.push(e); + }); + + if(options.tree) { + (Sortable.findTreeElements(element, options) || []).each( function(e) { + Droppables.add(e, options_for_tree); + e.treeNode = element; + options.droppables.push(e); + }); + } + + // keep reference + this.sortables[element.id] = options; + + // for onupdate + Draggables.addObserver(new SortableObserver(element, options.onUpdate)); + + }, + + // return all suitable-for-sortable elements in a guaranteed order + findElements: function(element, options) { + return Element.findChildren( + element, options.only, options.tree ? true : false, options.tag); + }, + + findTreeElements: function(element, options) { + return Element.findChildren( + element, options.only, options.tree ? true : false, options.treeTag); + }, + + onHover: function(element, dropon, overlap) { + if(Element.isParent(dropon, element)) return; + + if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) { + return; + } else if(overlap>0.5) { + Sortable.mark(dropon, 'before'); + if(dropon.previousSibling != element) { + var oldParentNode = element.parentNode; + element.style.visibility = "hidden"; // fix gecko rendering + dropon.parentNode.insertBefore(element, dropon); + if(dropon.parentNode!=oldParentNode) + Sortable.options(oldParentNode).onChange(element); + Sortable.options(dropon.parentNode).onChange(element); + } + } else { + Sortable.mark(dropon, 'after'); + var nextElement = dropon.nextSibling || null; + if(nextElement != element) { + var oldParentNode = element.parentNode; + element.style.visibility = "hidden"; // fix gecko rendering + dropon.parentNode.insertBefore(element, nextElement); + if(dropon.parentNode!=oldParentNode) + Sortable.options(oldParentNode).onChange(element); + Sortable.options(dropon.parentNode).onChange(element); + } + } + }, + + onEmptyHover: function(element, dropon, overlap) { + var oldParentNode = element.parentNode; + var droponOptions = Sortable.options(dropon); + + if(!Element.isParent(dropon, element)) { + var index; + + var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only}); + var child = null; + + if(children) { + var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap); + + for (index = 0; index < children.length; index += 1) { + if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) { + offset -= Element.offsetSize (children[index], droponOptions.overlap); + } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) { + child = index + 1 < children.length ? children[index + 1] : null; + break; + } else { + child = children[index]; + break; + } + } + } + + dropon.insertBefore(element, child); + + Sortable.options(oldParentNode).onChange(element); + droponOptions.onChange(element); + } + }, + + unmark: function() { + if(Sortable._marker) Element.hide(Sortable._marker); + }, + + mark: function(dropon, position) { + // mark on ghosting only + var sortable = Sortable.options(dropon.parentNode); + if(sortable && !sortable.ghosting) return; + + if(!Sortable._marker) { + Sortable._marker = $('dropmarker') || document.createElement('DIV'); + Element.hide(Sortable._marker); + Element.addClassName(Sortable._marker, 'dropmarker'); + Sortable._marker.style.position = 'absolute'; + document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); + } + var offsets = Position.cumulativeOffset(dropon); + Sortable._marker.style.left = offsets[0] + 'px'; + Sortable._marker.style.top = offsets[1] + 'px'; + + if(position=='after') + if(sortable.overlap == 'horizontal') + Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px'; + else + Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px'; + + Element.show(Sortable._marker); + }, + + _tree: function(element, options, parent) { + var children = Sortable.findElements(element, options) || []; + + for (var i = 0; i < children.length; ++i) { + var match = children[i].id.match(options.format); + + if (!match) continue; + + var child = { + id: encodeURIComponent(match ? match[1] : null), + element: element, + parent: parent, + children: new Array, + position: parent.children.length, + container: Sortable._findChildrenElement(children[i], options.treeTag.toUpperCase()) + } + + /* Get the element containing the children and recurse over it */ + if (child.container) + this._tree(child.container, options, child) + + parent.children.push (child); + } + + return parent; + }, + + /* Finds the first element of the given tag type within a parent element. + Used for finding the first LI[ST] within a L[IST]I[TEM].*/ + _findChildrenElement: function (element, containerTag) { + if (element && element.hasChildNodes) + for (var i = 0; i < element.childNodes.length; ++i) + if (element.childNodes[i].tagName == containerTag) + return element.childNodes[i]; + + return null; + }, + + tree: function(element) { + element = $(element); + var sortableOptions = this.options(element); + var options = Object.extend({ + tag: sortableOptions.tag, + treeTag: sortableOptions.treeTag, + only: sortableOptions.only, + name: element.id, + format: sortableOptions.format + }, arguments[1] || {}); + + var root = { + id: null, + parent: null, + children: new Array, + container: element, + position: 0 + } + + return Sortable._tree (element, options, root); + }, + + /* Construct a [i] index for a particular node */ + _constructIndex: function(node) { + var index = ''; + do { + if (node.id) index = '[' + node.position + ']' + index; + } while ((node = node.parent) != null); + return index; + }, + + sequence: function(element) { + element = $(element); + var options = Object.extend(this.options(element), arguments[1] || {}); + + return $(this.findElements(element, options) || []).map( function(item) { + return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; + }); + }, + + setSequence: function(element, new_sequence) { + element = $(element); + var options = Object.extend(this.options(element), arguments[2] || {}); + + var nodeMap = {}; + this.findElements(element, options).each( function(n) { + if (n.id.match(options.format)) + nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; + n.parentNode.removeChild(n); + }); + + new_sequence.each(function(ident) { + var n = nodeMap[ident]; + if (n) { + n[1].appendChild(n[0]); + delete nodeMap[ident]; + } + }); + }, + + serialize: function(element) { + element = $(element); + var options = Object.extend(Sortable.options(element), arguments[1] || {}); + var name = encodeURIComponent( + (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); + + if (options.tree) { + return Sortable.tree(element, arguments[1]).children.map( function (item) { + return [name + Sortable._constructIndex(item) + "[id]=" + + encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); + }).flatten().join('&'); + } else { + return Sortable.sequence(element, arguments[1]).map( function(item) { + return name + "[]=" + encodeURIComponent(item); + }).join('&'); + } + } +} + +/* Returns true if child is contained within element */ +Element.isParent = function(child, element) { + if (!child.parentNode || child == element) return false; + + if (child.parentNode == element) return true; + + return Element.isParent(child.parentNode, element); +} + +Element.findChildren = function(element, only, recursive, tagName) { + if(!element.hasChildNodes()) return null; + tagName = tagName.toUpperCase(); + if(only) only = [only].flatten(); + var elements = []; + $A(element.childNodes).each( function(e) { + if(e.tagName && e.tagName.toUpperCase()==tagName && + (!only || (Element.classNames(e).detect(function(v) { return only.include(v) })))) + elements.push(e); + if(recursive) { + var grandchildren = Element.findChildren(e, only, recursive, tagName); + if(grandchildren) elements.push(grandchildren); + } + }); + + return (elements.length>0 ? elements.flatten() : []); +} + +Element.offsetSize = function (element, type) { + if (type == 'vertical' || type == 'height') + return element.offsetHeight; + else + return element.offsetWidth; +} diff --git a/js/calendar.js b/js/calendar.js new file mode 100644 index 0000000..9a69936 --- /dev/null +++ b/js/calendar.js @@ -0,0 +1,2058 @@ +/* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo + * ----------------------------------------------------------- + * + * The DHTML Calendar, version 1.0 "It is happening again" + * + * Details and latest version at: + * www.dynarch.com/projects/calendar + * + * This script is developed by Dynarch.com. Visit us at www.dynarch.com. + * + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html + */ + +// $Id: calendar.js,v 1.51 2005/03/07 16:44:31 mishoo Exp $ + +/** The Calendar object constructor. */ +Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) { + // member variables + this.activeDiv = null; + this.currentDateEl = null; + this.getDateStatus = null; + this.getDateToolTip = null; + this.getDateText = null; + this.timeout = null; + this.onSelected = onSelected || null; + this.onClose = onClose || null; + this.dragging = false; + this.hidden = false; + this.minYear = 1970; + this.maxYear = 2050; + this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"]; + this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"]; + this.isPopup = true; + this.weekNumbers = true; + this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : Calendar._FD; // 0 for Sunday, 1 for Monday, etc. + this.showsOtherMonths = false; + this.dateStr = dateStr; + this.ar_days = null; + this.showsTime = false; + this.time24 = true; + this.yearStep = 2; + this.hiliteToday = true; + this.multiple = null; + // HTML elements + this.table = null; + this.element = null; + this.tbody = null; + this.firstdayname = null; + // Combo boxes + this.monthsCombo = null; + this.yearsCombo = null; + this.hilitedMonth = null; + this.activeMonth = null; + this.hilitedYear = null; + this.activeYear = null; + // Information + this.dateClicked = false; + + // one-time initializations + if (typeof Calendar._SDN == "undefined") { + // table of short day names + if (typeof Calendar._SDN_len == "undefined") + Calendar._SDN_len = 3; + var ar = new Array(); + for (var i = 8; i > 0;) { + ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len); + } + Calendar._SDN = ar; + // table of short month names + if (typeof Calendar._SMN_len == "undefined") + Calendar._SMN_len = 3; + ar = new Array(); + for (var i = 12; i > 0;) { + ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len); + } + Calendar._SMN = ar; + } +}; + +// ** constants + +/// "static", needed for event handlers. +Calendar._C = null; + +/// detect a special case of "web browser" +Calendar.is_ie = ( /msie/i.test(navigator.userAgent) && + !/opera/i.test(navigator.userAgent) ); + +Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) ); + +/// detect Opera browser +Calendar.is_opera = /opera/i.test(navigator.userAgent); + +/// detect KHTML-based browsers +Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent); + +// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate +// library, at some point. + +Calendar.getAbsolutePos = function(el) { + var SL = 0, ST = 0; + var is_div = /^div$/i.test(el.tagName); + if (is_div && el.scrollLeft) + SL = el.scrollLeft; + if (is_div && el.scrollTop) + ST = el.scrollTop; + var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST }; + if (el.offsetParent) { + var tmp = this.getAbsolutePos(el.offsetParent); + r.x += tmp.x; + r.y += tmp.y; + } + return r; +}; + +Calendar.isRelated = function (el, evt) { + var related = evt.relatedTarget; + if (!related) { + var type = evt.type; + if (type == "mouseover") { + related = evt.fromElement; + } else if (type == "mouseout") { + related = evt.toElement; + } + } + while (related) { + if (related == el) { + return true; + } + related = related.parentNode; + } + return false; +}; + +Calendar.removeClass = function(el, className) { + if (!(el && el.className)) { + return; + } + var cls = el.className.split(" "); + var ar = new Array(); + for (var i = cls.length; i > 0;) { + if (cls[--i] != className) { + ar[ar.length] = cls[i]; + } + } + el.className = ar.join(" "); +}; + +Calendar.addClass = function(el, className) { + Calendar.removeClass(el, className); + el.className += " " + className; +}; + +// FIXME: the following 2 functions totally suck, are useless and should be replaced immediately. +Calendar.getElement = function(ev) { + var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget; + while (f.nodeType != 1 || /^div$/i.test(f.tagName)) + f = f.parentNode; + return f; +}; + +Calendar.getTargetElement = function(ev) { + var f = Calendar.is_ie ? window.event.srcElement : ev.target; + while (f.nodeType != 1) + f = f.parentNode; + return f; +}; + +Calendar.stopEvent = function(ev) { + ev || (ev = window.event); + if (Calendar.is_ie) { + ev.cancelBubble = true; + ev.returnValue = false; + } else { + ev.preventDefault(); + ev.stopPropagation(); + } + return false; +}; + +Calendar.addEvent = function(el, evname, func) { + if (el.attachEvent) { // IE + el.attachEvent("on" + evname, func); + } else if (el.addEventListener) { // Gecko / W3C + el.addEventListener(evname, func, true); + } else { + el["on" + evname] = func; + } +}; + +Calendar.removeEvent = function(el, evname, func) { + if (el.detachEvent) { // IE + el.detachEvent("on" + evname, func); + } else if (el.removeEventListener) { // Gecko / W3C + el.removeEventListener(evname, func, true); + } else { + el["on" + evname] = null; + } +}; + +Calendar.createElement = function(type, parent) { + var el = null; + if (document.createElementNS) { + // use the XHTML namespace; IE won't normally get here unless + // _they_ "fix" the DOM2 implementation. + el = document.createElementNS("http://www.w3.org/1999/xhtml", type); + } else { + el = document.createElement(type); + } + if (typeof parent != "undefined") { + parent.appendChild(el); + } + return el; +}; + +// END: UTILITY FUNCTIONS + +// BEGIN: CALENDAR STATIC FUNCTIONS + +/** Internal -- adds a set of events to make some element behave like a button. */ +Calendar._add_evs = function(el) { + with (Calendar) { + addEvent(el, "mouseover", dayMouseOver); + addEvent(el, "mousedown", dayMouseDown); + addEvent(el, "mouseout", dayMouseOut); + if (is_ie) { + addEvent(el, "dblclick", dayMouseDblClick); + el.setAttribute("unselectable", true); + } + } +}; + +Calendar.findMonth = function(el) { + if (typeof el.month != "undefined") { + return el; + } else if (typeof el.parentNode.month != "undefined") { + return el.parentNode; + } + return null; +}; + +Calendar.findYear = function(el) { + if (typeof el.year != "undefined") { + return el; + } else if (typeof el.parentNode.year != "undefined") { + return el.parentNode; + } + return null; +}; + +Calendar.showMonthsCombo = function () { + var cal = Calendar._C; + if (!cal) { + return false; + } + var cal = cal; + var cd = cal.activeDiv; + var mc = cal.monthsCombo; + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + if (cal.activeMonth) { + Calendar.removeClass(cal.activeMonth, "active"); + } + var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()]; + Calendar.addClass(mon, "active"); + cal.activeMonth = mon; + var s = mc.style; + s.display = "block"; + if (cd.navtype < 0) + s.left = cd.offsetLeft + "px"; + else { + var mcw = mc.offsetWidth; + if (typeof mcw == "undefined") + // Konqueror brain-dead techniques + mcw = 50; + s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px"; + } + s.top = (cd.offsetTop + cd.offsetHeight) + "px"; +}; + +Calendar.showYearsCombo = function (fwd) { + var cal = Calendar._C; + if (!cal) { + return false; + } + var cal = cal; + var cd = cal.activeDiv; + var yc = cal.yearsCombo; + if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + if (cal.activeYear) { + Calendar.removeClass(cal.activeYear, "active"); + } + cal.activeYear = null; + var Y = cal.date.getFullYear() + (fwd ? 1 : -1); + var yr = yc.firstChild; + var show = false; + for (var i = 12; i > 0; --i) { + if (Y >= cal.minYear && Y <= cal.maxYear) { + yr.innerHTML = Y; + yr.year = Y; + yr.style.display = "block"; + show = true; + } else { + yr.style.display = "none"; + } + yr = yr.nextSibling; + Y += fwd ? cal.yearStep : -cal.yearStep; + } + if (show) { + var s = yc.style; + s.display = "block"; + if (cd.navtype < 0) + s.left = cd.offsetLeft + "px"; + else { + var ycw = yc.offsetWidth; + if (typeof ycw == "undefined") + // Konqueror brain-dead techniques + ycw = 50; + s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px"; + } + s.top = (cd.offsetTop + cd.offsetHeight) + "px"; + } +}; + +// event handlers + +Calendar.tableMouseUp = function(ev) { + var cal = Calendar._C; + if (!cal) { + return false; + } + if (cal.timeout) { + clearTimeout(cal.timeout); + } + var el = cal.activeDiv; + if (!el) { + return false; + } + var target = Calendar.getTargetElement(ev); + ev || (ev = window.event); + Calendar.removeClass(el, "active"); + if (target == el || target.parentNode == el) { + Calendar.cellClick(el, ev); + } + var mon = Calendar.findMonth(target); + var date = null; + if (mon) { + date = new Date(cal.date); + if (mon.month != date.getMonth()) { + date.setMonth(mon.month); + cal.setDate(date); + cal.dateClicked = false; + cal.callHandler(); + } + } else { + var year = Calendar.findYear(target); + if (year) { + date = new Date(cal.date); + if (year.year != date.getFullYear()) { + date.setFullYear(year.year); + cal.setDate(date); + cal.dateClicked = false; + cal.callHandler(); + } + } + } + with (Calendar) { + removeEvent(document, "mouseup", tableMouseUp); + removeEvent(document, "mouseover", tableMouseOver); + removeEvent(document, "mousemove", tableMouseOver); + cal._hideCombos(); + _C = null; + return stopEvent(ev); + } +}; + +Calendar.tableMouseOver = function (ev) { + var cal = Calendar._C; + if (!cal) { + return; + } + var el = cal.activeDiv; + var target = Calendar.getTargetElement(ev); + if (target == el || target.parentNode == el) { + Calendar.addClass(el, "hilite active"); + Calendar.addClass(el.parentNode, "rowhilite"); + } else { + if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2))) + Calendar.removeClass(el, "active"); + Calendar.removeClass(el, "hilite"); + Calendar.removeClass(el.parentNode, "rowhilite"); + } + ev || (ev = window.event); + if (el.navtype == 50 && target != el) { + var pos = Calendar.getAbsolutePos(el); + var w = el.offsetWidth; + var x = ev.clientX; + var dx; + var decrease = true; + if (x > pos.x + w) { + dx = x - pos.x - w; + decrease = false; + } else + dx = pos.x - x; + + if (dx < 0) dx = 0; + var range = el._range; + var current = el._current; + var count = Math.floor(dx / 10) % range.length; + for (var i = range.length; --i >= 0;) + if (range[i] == current) + break; + while (count-- > 0) + if (decrease) { + if (--i < 0) + i = range.length - 1; + } else if ( ++i >= range.length ) + i = 0; + var newval = range[i]; + el.innerHTML = newval; + + cal.onUpdateTime(); + } + var mon = Calendar.findMonth(target); + if (mon) { + if (mon.month != cal.date.getMonth()) { + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + Calendar.addClass(mon, "hilite"); + cal.hilitedMonth = mon; + } else if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + } else { + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + var year = Calendar.findYear(target); + if (year) { + if (year.year != cal.date.getFullYear()) { + if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + Calendar.addClass(year, "hilite"); + cal.hilitedYear = year; + } else if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + } else if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + } + return Calendar.stopEvent(ev); +}; + +Calendar.tableMouseDown = function (ev) { + if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) { + return Calendar.stopEvent(ev); + } +}; + +Calendar.calDragIt = function (ev) { + var cal = Calendar._C; + if (!(cal && cal.dragging)) { + return false; + } + var posX; + var posY; + if (Calendar.is_ie) { + posY = window.event.clientY + document.body.scrollTop; + posX = window.event.clientX + document.body.scrollLeft; + } else { + posX = ev.pageX; + posY = ev.pageY; + } + cal.hideShowCovered(); + var st = cal.element.style; + st.left = (posX - cal.xOffs) + "px"; + st.top = (posY - cal.yOffs) + "px"; + return Calendar.stopEvent(ev); +}; + +Calendar.calDragEnd = function (ev) { + var cal = Calendar._C; + if (!cal) { + return false; + } + cal.dragging = false; + with (Calendar) { + removeEvent(document, "mousemove", calDragIt); + removeEvent(document, "mouseup", calDragEnd); + tableMouseUp(ev); + } + cal.hideShowCovered(); +}; + +Calendar.dayMouseDown = function(ev) { + var el = Calendar.getElement(ev); + if (el.disabled) { + return false; + } + var cal = el.calendar; + cal.activeDiv = el; + Calendar._C = cal; + if (el.navtype != 300) with (Calendar) { + if (el.navtype == 50) { + el._current = el.innerHTML; + addEvent(document, "mousemove", tableMouseOver); + } else + addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver); + addClass(el, "hilite active"); + addEvent(document, "mouseup", tableMouseUp); + } else if (cal.isPopup) { + cal._dragStart(ev); + } + if (el.navtype == -1 || el.navtype == 1) { + if (cal.timeout) clearTimeout(cal.timeout); + cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250); + } else if (el.navtype == -2 || el.navtype == 2) { + if (cal.timeout) clearTimeout(cal.timeout); + cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250); + } else { + cal.timeout = null; + } + return Calendar.stopEvent(ev); +}; + +Calendar.dayMouseDblClick = function(ev) { + Calendar.cellClick(Calendar.getElement(ev), ev || window.event); + if (Calendar.is_ie) { + document.selection.empty(); + } +}; + +Calendar.dayMouseOver = function(ev) { + var el = Calendar.getElement(ev); + if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) { + return false; + } + if (el.ttip) { + if (el.ttip.substr(0, 1) == "_") { + el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1); + } + el.calendar.tooltips.innerHTML = el.ttip; + } + if (el.navtype != 300) { + Calendar.addClass(el, "hilite"); + if (el.caldate) { + Calendar.addClass(el.parentNode, "rowhilite"); + } + } + return Calendar.stopEvent(ev); +}; + +Calendar.dayMouseOut = function(ev) { + with (Calendar) { + var el = getElement(ev); + if (isRelated(el, ev) || _C || el.disabled) + return false; + removeClass(el, "hilite"); + if (el.caldate) + removeClass(el.parentNode, "rowhilite"); + if (el.calendar) + el.calendar.tooltips.innerHTML = _TT["SEL_DATE"]; + return stopEvent(ev); + } +}; + +/** + * A generic "click" handler :) handles all types of buttons defined in this + * calendar. + */ +Calendar.cellClick = function(el, ev) { + var cal = el.calendar; + var closing = false; + var newdate = false; + var date = null; + if (typeof el.navtype == "undefined") { + if (cal.currentDateEl) { + Calendar.removeClass(cal.currentDateEl, "selected"); + Calendar.addClass(el, "selected"); + closing = (cal.currentDateEl == el); + if (!closing) { + cal.currentDateEl = el; + } + } + cal.date.setDateOnly(el.caldate); + date = cal.date; + var other_month = !(cal.dateClicked = !el.otherMonth); + if (!other_month && !cal.currentDateEl) + cal._toggleMultipleDate(new Date(date)); + else + newdate = !el.disabled; + // a date was clicked + if (other_month) + cal._init(cal.firstDayOfWeek, date); + } else { + if (el.navtype == 200) { + Calendar.removeClass(el, "hilite"); + cal.callCloseHandler(); + return; + } + date = new Date(cal.date); + if (el.navtype == 0) + date.setDateOnly(new Date()); // TODAY + // unless "today" was clicked, we assume no date was clicked so + // the selected handler will know not to close the calenar when + // in single-click mode. + // cal.dateClicked = (el.navtype == 0); + cal.dateClicked = false; + var year = date.getFullYear(); + var mon = date.getMonth(); + function setMonth(m) { + var day = date.getDate(); + var max = date.getMonthDays(m); + if (day > max) { + date.setDate(max); + } + date.setMonth(m); + }; + switch (el.navtype) { + case 400: + Calendar.removeClass(el, "hilite"); + var text = Calendar._TT["ABOUT"]; + if (typeof text != "undefined") { + text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : ""; + } else { + // FIXME: this should be removed as soon as lang files get updated! + text = "Help and about box text is not translated into this language.\n" + + "If you know this language and you feel generous please update\n" + + "the corresponding file in \"lang\" subdir to match calendar-en.js\n" + + "and send it back to to get it into the distribution ;-)\n\n" + + "Thank you!\n" + + "http://dynarch.com/mishoo/calendar.epl\n"; + } + alert(text); + return; + case -2: + if (year > cal.minYear) { + date.setFullYear(year - 1); + } + break; + case -1: + if (mon > 0) { + setMonth(mon - 1); + } else if (year-- > cal.minYear) { + date.setFullYear(year); + setMonth(11); + } + break; + case 1: + if (mon < 11) { + setMonth(mon + 1); + } else if (year < cal.maxYear) { + date.setFullYear(year + 1); + setMonth(0); + } + break; + case 2: + if (year < cal.maxYear) { + date.setFullYear(year + 1); + } + break; + case 100: + cal.setFirstDayOfWeek(el.fdow); + return; + case 50: + var range = el._range; + var current = el.innerHTML; + for (var i = range.length; --i >= 0;) + if (range[i] == current) + break; + if (ev && ev.shiftKey) { + if (--i < 0) + i = range.length - 1; + } else if ( ++i >= range.length ) + i = 0; + var newval = range[i]; + el.innerHTML = newval; + cal.onUpdateTime(); + return; + case 0: + // TODAY will bring us here + if ((typeof cal.getDateStatus == "function") && + cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) { + return false; + } + break; + } + if (!date.equalsTo(cal.date)) { + cal.setDate(date); + newdate = true; + } else if (el.navtype == 0) + newdate = closing = true; + } + if (newdate) { + ev && cal.callHandler(); + } + if (closing) { + Calendar.removeClass(el, "hilite"); + ev && cal.callCloseHandler(); + } +}; + +// END: CALENDAR STATIC FUNCTIONS + +// BEGIN: CALENDAR OBJECT FUNCTIONS + +/** + * This function creates the calendar inside the given parent. If _par is + * null than it creates a popup calendar inside the BODY element. If _par is + * an element, be it BODY, then it creates a non-popup calendar (still + * hidden). Some properties need to be set before calling this function. + */ +Calendar.prototype.create = function (_par) { + var parent = null; + if (! _par) { + // default parent is the document body, in which case we create + // a popup calendar. + parent = document.getElementsByTagName("body")[0]; + this.isPopup = true; + } else { + parent = _par; + this.isPopup = false; + } + this.date = this.dateStr ? new Date(this.dateStr) : new Date(); + + var table = Calendar.createElement("table"); + this.table = table; + table.cellSpacing = 0; + table.cellPadding = 0; + table.calendar = this; + Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown); + + var div = Calendar.createElement("div"); + this.element = div; + div.className = "calendar"; + if (this.isPopup) { + div.style.position = "absolute"; + div.style.display = "none"; + } + div.appendChild(table); + + var thead = Calendar.createElement("thead", table); + var cell = null; + var row = null; + + var cal = this; + var hh = function (text, cs, navtype) { + cell = Calendar.createElement("td", row); + cell.colSpan = cs; + cell.className = "button"; + if (navtype != 0 && Math.abs(navtype) <= 2) + cell.className += " nav"; + Calendar._add_evs(cell); + cell.calendar = cal; + cell.navtype = navtype; + cell.innerHTML = "
    " + text + "
    "; + return cell; + }; + + row = Calendar.createElement("tr", thead); + var title_length = 6; + (this.isPopup) && --title_length; + (this.weekNumbers) && ++title_length; + + hh("?", 1, 400).ttip = Calendar._TT["INFO"]; + this.title = hh("", title_length, 300); + this.title.className = "title"; + if (this.isPopup) { + this.title.ttip = Calendar._TT["DRAG_TO_MOVE"]; + this.title.style.cursor = "move"; + hh("×", 1, 200).ttip = Calendar._TT["CLOSE"]; + } + + row = Calendar.createElement("tr", thead); + row.className = "headrow"; + + this._nav_py = hh("«", 1, -2); + this._nav_py.ttip = Calendar._TT["PREV_YEAR"]; + + this._nav_pm = hh("‹", 1, -1); + this._nav_pm.ttip = Calendar._TT["PREV_MONTH"]; + + this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0); + this._nav_now.ttip = Calendar._TT["GO_TODAY"]; + + this._nav_nm = hh("›", 1, 1); + this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"]; + + this._nav_ny = hh("»", 1, 2); + this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"]; + + // day names + row = Calendar.createElement("tr", thead); + row.className = "daynames"; + if (this.weekNumbers) { + cell = Calendar.createElement("td", row); + cell.className = "name wn"; + cell.innerHTML = Calendar._TT["WK"]; + } + for (var i = 7; i > 0; --i) { + cell = Calendar.createElement("td", row); + if (!i) { + cell.navtype = 100; + cell.calendar = this; + Calendar._add_evs(cell); + } + } + this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild; + this._displayWeekdays(); + + var tbody = Calendar.createElement("tbody", table); + this.tbody = tbody; + + for (i = 6; i > 0; --i) { + row = Calendar.createElement("tr", tbody); + if (this.weekNumbers) { + cell = Calendar.createElement("td", row); + } + for (var j = 7; j > 0; --j) { + cell = Calendar.createElement("td", row); + cell.calendar = this; + Calendar._add_evs(cell); + } + } + + if (this.showsTime) { + row = Calendar.createElement("tr", tbody); + row.className = "time"; + + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = 2; + cell.innerHTML = Calendar._TT["TIME"] || " "; + + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = this.weekNumbers ? 4 : 3; + + (function(){ + function makeTimePart(className, init, range_start, range_end) { + var part = Calendar.createElement("span", cell); + part.className = className; + part.innerHTML = init; + part.calendar = cal; + part.ttip = Calendar._TT["TIME_PART"]; + part.navtype = 50; + part._range = []; + if (typeof range_start != "number") + part._range = range_start; + else { + for (var i = range_start; i <= range_end; ++i) { + var txt; + if (i < 10 && range_end >= 10) txt = '0' + i; + else txt = '' + i; + part._range[part._range.length] = txt; + } + } + Calendar._add_evs(part); + return part; + }; + var hrs = cal.date.getHours(); + var mins = cal.date.getMinutes(); + var t12 = !cal.time24; + var pm = (hrs > 12); + if (t12 && pm) hrs -= 12; + var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23); + var span = Calendar.createElement("span", cell); + span.innerHTML = ":"; + span.className = "colon"; + var M = makeTimePart("minute", mins, 0, 59); + var AP = null; + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = 2; + if (t12) + AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]); + else + cell.innerHTML = " "; + + cal.onSetTime = function() { + var pm, hrs = this.date.getHours(), + mins = this.date.getMinutes(); + if (t12) { + pm = (hrs >= 12); + if (pm) hrs -= 12; + if (hrs == 0) hrs = 12; + AP.innerHTML = pm ? "pm" : "am"; + } + H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs; + M.innerHTML = (mins < 10) ? ("0" + mins) : mins; + }; + + cal.onUpdateTime = function() { + var date = this.date; + var h = parseInt(H.innerHTML, 10); + if (t12) { + if (/pm/i.test(AP.innerHTML) && h < 12) + h += 12; + else if (/am/i.test(AP.innerHTML) && h == 12) + h = 0; + } + var d = date.getDate(); + var m = date.getMonth(); + var y = date.getFullYear(); + date.setHours(h); + date.setMinutes(parseInt(M.innerHTML, 10)); + date.setFullYear(y); + date.setMonth(m); + date.setDate(d); + this.dateClicked = false; + this.callHandler(); + }; + })(); + } else { + this.onSetTime = this.onUpdateTime = function() {}; + } + + var tfoot = Calendar.createElement("tfoot", table); + + row = Calendar.createElement("tr", tfoot); + row.className = "footrow"; + + cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300); + cell.className = "ttip"; + if (this.isPopup) { + cell.ttip = Calendar._TT["DRAG_TO_MOVE"]; + cell.style.cursor = "move"; + } + this.tooltips = cell; + + div = Calendar.createElement("div", this.element); + this.monthsCombo = div; + div.className = "combo"; + for (i = 0; i < Calendar._MN.length; ++i) { + var mn = Calendar.createElement("div"); + mn.className = Calendar.is_ie ? "label-IEfix" : "label"; + mn.month = i; + mn.innerHTML = Calendar._SMN[i]; + div.appendChild(mn); + } + + div = Calendar.createElement("div", this.element); + this.yearsCombo = div; + div.className = "combo"; + for (i = 12; i > 0; --i) { + var yr = Calendar.createElement("div"); + yr.className = Calendar.is_ie ? "label-IEfix" : "label"; + div.appendChild(yr); + } + + this._init(this.firstDayOfWeek, this.date); + parent.appendChild(this.element); +}; + +/** keyboard navigation, only for popup calendars */ +Calendar._keyEvent = function(ev) { + var cal = window._dynarch_popupCalendar; + if (!cal || cal.multiple) + return false; + (Calendar.is_ie) && (ev = window.event); + var act = (Calendar.is_ie || ev.type == "keypress"), + K = ev.keyCode; + if (ev.ctrlKey) { + switch (K) { + case 37: // KEY left + act && Calendar.cellClick(cal._nav_pm); + break; + case 38: // KEY up + act && Calendar.cellClick(cal._nav_py); + break; + case 39: // KEY right + act && Calendar.cellClick(cal._nav_nm); + break; + case 40: // KEY down + act && Calendar.cellClick(cal._nav_ny); + break; + default: + return false; + } + } else switch (K) { + case 32: // KEY space (now) + Calendar.cellClick(cal._nav_now); + break; + case 27: // KEY esc + act && cal.callCloseHandler(); + break; + case 37: // KEY left + case 38: // KEY up + case 39: // KEY right + case 40: // KEY down + if (act) { + var prev, x, y, ne, el, step; + prev = K == 37 || K == 38; + step = (K == 37 || K == 39) ? 1 : 7; + function setVars() { + el = cal.currentDateEl; + var p = el.pos; + x = p & 15; + y = p >> 4; + ne = cal.ar_days[y][x]; + };setVars(); + function prevMonth() { + var date = new Date(cal.date); + date.setDate(date.getDate() - step); + cal.setDate(date); + }; + function nextMonth() { + var date = new Date(cal.date); + date.setDate(date.getDate() + step); + cal.setDate(date); + }; + while (1) { + switch (K) { + case 37: // KEY left + if (--x >= 0) + ne = cal.ar_days[y][x]; + else { + x = 6; + K = 38; + continue; + } + break; + case 38: // KEY up + if (--y >= 0) + ne = cal.ar_days[y][x]; + else { + prevMonth(); + setVars(); + } + break; + case 39: // KEY right + if (++x < 7) + ne = cal.ar_days[y][x]; + else { + x = 0; + K = 40; + continue; + } + break; + case 40: // KEY down + if (++y < cal.ar_days.length) + ne = cal.ar_days[y][x]; + else { + nextMonth(); + setVars(); + } + break; + } + break; + } + if (ne) { + if (!ne.disabled) + Calendar.cellClick(ne); + else if (prev) + prevMonth(); + else + nextMonth(); + } + } + break; + case 13: // KEY enter + if (act) + Calendar.cellClick(cal.currentDateEl, ev); + break; + default: + return false; + } + return Calendar.stopEvent(ev); +}; + +/** + * (RE)Initializes the calendar to the given date and firstDayOfWeek + */ +Calendar.prototype._init = function (firstDayOfWeek, date) { + var today = new Date(), + TY = today.getFullYear(), + TM = today.getMonth(), + TD = today.getDate(); + this.table.style.visibility = "hidden"; + var year = date.getFullYear(); + if (year < this.minYear) { + year = this.minYear; + date.setFullYear(year); + } else if (year > this.maxYear) { + year = this.maxYear; + date.setFullYear(year); + } + this.firstDayOfWeek = firstDayOfWeek; + this.date = new Date(date); + var month = date.getMonth(); + var mday = date.getDate(); + var no_days = date.getMonthDays(); + + // calendar voodoo for computing the first day that would actually be + // displayed in the calendar, even if it's from the previous month. + // WARNING: this is magic. ;-) + date.setDate(1); + var day1 = (date.getDay() - this.firstDayOfWeek) % 7; + if (day1 < 0) + day1 += 7; + date.setDate(-day1); + date.setDate(date.getDate() + 1); + + var row = this.tbody.firstChild; + var MN = Calendar._SMN[month]; + var ar_days = this.ar_days = new Array(); + var weekend = Calendar._TT["WEEKEND"]; + var dates = this.multiple ? (this.datesCells = {}) : null; + for (var i = 0; i < 6; ++i, row = row.nextSibling) { + var cell = row.firstChild; + if (this.weekNumbers) { + cell.className = "day wn"; + cell.innerHTML = date.getWeekNumber(); + cell = cell.nextSibling; + } + row.className = "daysrow"; + var hasdays = false, iday, dpos = ar_days[i] = []; + for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) { + iday = date.getDate(); + var wday = date.getDay(); + cell.className = "day"; + cell.pos = i << 4 | j; + dpos[j] = cell; + var current_month = (date.getMonth() == month); + if (!current_month) { + if (this.showsOtherMonths) { + cell.className += " othermonth"; + cell.otherMonth = true; + } else { + cell.className = "emptycell"; + cell.innerHTML = " "; + cell.disabled = true; + continue; + } + } else { + cell.otherMonth = false; + hasdays = true; + } + cell.disabled = false; + cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday; + if (dates) + dates[date.print("%Y%m%d")] = cell; + if (this.getDateStatus) { + var status = this.getDateStatus(date, year, month, iday); + if (this.getDateToolTip) { + var toolTip = this.getDateToolTip(date, year, month, iday); + if (toolTip) + cell.title = toolTip; + } + if (status === true) { + cell.className += " disabled"; + cell.disabled = true; + } else { + if (/disabled/i.test(status)) + cell.disabled = true; + cell.className += " " + status; + } + } + if (!cell.disabled) { + cell.caldate = new Date(date); + cell.ttip = "_"; + if (!this.multiple && current_month + && iday == mday && this.hiliteToday) { + cell.className += " selected"; + this.currentDateEl = cell; + } + if (date.getFullYear() == TY && + date.getMonth() == TM && + iday == TD) { + cell.className += " today"; + cell.ttip += Calendar._TT["PART_TODAY"]; + } + if (weekend.indexOf(wday.toString()) != -1) + cell.className += cell.otherMonth ? " oweekend" : " weekend"; + } + } + if (!(hasdays || this.showsOtherMonths)) + row.className = "emptyrow"; + } + this.title.innerHTML = Calendar._MN[month] + ", " + year; + this.onSetTime(); + this.table.style.visibility = "visible"; + this._initMultipleDates(); + // PROFILE + // this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms"; +}; + +Calendar.prototype._initMultipleDates = function() { + if (this.multiple) { + for (var i in this.multiple) { + var cell = this.datesCells[i]; + var d = this.multiple[i]; + if (!d) + continue; + if (cell) + cell.className += " selected"; + } + } +}; + +Calendar.prototype._toggleMultipleDate = function(date) { + if (this.multiple) { + var ds = date.print("%Y%m%d"); + var cell = this.datesCells[ds]; + if (cell) { + var d = this.multiple[ds]; + if (!d) { + Calendar.addClass(cell, "selected"); + this.multiple[ds] = date; + } else { + Calendar.removeClass(cell, "selected"); + delete this.multiple[ds]; + } + } + } +}; + +Calendar.prototype.setDateToolTipHandler = function (unaryFunction) { + this.getDateToolTip = unaryFunction; +}; + +/** + * Calls _init function above for going to a certain date (but only if the + * date is different than the currently selected one). + */ +Calendar.prototype.setDate = function (date) { + if (!date.equalsTo(this.date)) { + this._init(this.firstDayOfWeek, date); + } +}; + +/** + * Refreshes the calendar. Useful if the "disabledHandler" function is + * dynamic, meaning that the list of disabled date can change at runtime. + * Just * call this function if you think that the list of disabled dates + * should * change. + */ +Calendar.prototype.refresh = function () { + this._init(this.firstDayOfWeek, this.date); +}; + +/** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */ +Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) { + this._init(firstDayOfWeek, this.date); + this._displayWeekdays(); +}; + +/** + * Allows customization of what dates are enabled. The "unaryFunction" + * parameter must be a function object that receives the date (as a JS Date + * object) and returns a boolean value. If the returned value is true then + * the passed date will be marked as disabled. + */ +Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) { + this.getDateStatus = unaryFunction; +}; + +/** Customization of allowed year range for the calendar. */ +Calendar.prototype.setRange = function (a, z) { + this.minYear = a; + this.maxYear = z; +}; + +/** Calls the first user handler (selectedHandler). */ +Calendar.prototype.callHandler = function () { + if (this.onSelected) { + this.onSelected(this, this.date.print(this.dateFormat)); + } +}; + +/** Calls the second user handler (closeHandler). */ +Calendar.prototype.callCloseHandler = function () { + if (this.onClose) { + this.onClose(this); + } + this.hideShowCovered(); +}; + +/** Removes the calendar object from the DOM tree and destroys it. */ +Calendar.prototype.destroy = function () { + var el = this.element.parentNode; + el.removeChild(this.element); + Calendar._C = null; + window._dynarch_popupCalendar = null; +}; + +/** + * Moves the calendar element to a different section in the DOM tree (changes + * its parent). + */ +Calendar.prototype.reparent = function (new_parent) { + var el = this.element; + el.parentNode.removeChild(el); + new_parent.appendChild(el); +}; + +// This gets called when the user presses a mouse button anywhere in the +// document, if the calendar is shown. If the click was outside the open +// calendar this function closes it. +Calendar._checkCalendar = function(ev) { + var calendar = window._dynarch_popupCalendar; + if (!calendar) { + return false; + } + var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev); + for (; el != null && el != calendar.element; el = el.parentNode); + if (el == null) { + // calls closeHandler which should hide the calendar. + window._dynarch_popupCalendar.callCloseHandler(); + return Calendar.stopEvent(ev); + } +}; + +/** Shows the calendar. */ +Calendar.prototype.show = function () { + var rows = this.table.getElementsByTagName("tr"); + for (var i = rows.length; i > 0;) { + var row = rows[--i]; + Calendar.removeClass(row, "rowhilite"); + var cells = row.getElementsByTagName("td"); + for (var j = cells.length; j > 0;) { + var cell = cells[--j]; + Calendar.removeClass(cell, "hilite"); + Calendar.removeClass(cell, "active"); + } + } + this.element.style.display = "block"; + this.hidden = false; + if (this.isPopup) { + window._dynarch_popupCalendar = this; + Calendar.addEvent(document, "keydown", Calendar._keyEvent); + Calendar.addEvent(document, "keypress", Calendar._keyEvent); + Calendar.addEvent(document, "mousedown", Calendar._checkCalendar); + } + this.hideShowCovered(); +}; + +/** + * Hides the calendar. Also removes any "hilite" from the class of any TD + * element. + */ +Calendar.prototype.hide = function () { + if (this.isPopup) { + Calendar.removeEvent(document, "keydown", Calendar._keyEvent); + Calendar.removeEvent(document, "keypress", Calendar._keyEvent); + Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar); + } + this.element.style.display = "none"; + this.hidden = true; + this.hideShowCovered(); +}; + +/** + * Shows the calendar at a given absolute position (beware that, depending on + * the calendar element style -- position property -- this might be relative + * to the parent's containing rectangle). + */ +Calendar.prototype.showAt = function (x, y) { + var s = this.element.style; + s.left = x + "px"; + s.top = y + "px"; + this.show(); +}; + +/** Shows the calendar near a given element. */ +Calendar.prototype.showAtElement = function (el, opts) { + var self = this; + var p = Calendar.getAbsolutePos(el); + if (!opts || typeof opts != "string") { + this.showAt(p.x, p.y + el.offsetHeight); + return true; + } + function fixPosition(box) { + if (box.x < 0) + box.x = 0; + if (box.y < 0) + box.y = 0; + var cp = document.createElement("div"); + var s = cp.style; + s.position = "absolute"; + s.right = s.bottom = s.width = s.height = "0px"; + document.body.appendChild(cp); + var br = Calendar.getAbsolutePos(cp); + document.body.removeChild(cp); + br.y += window.scrollY; + br.x += window.scrollX; + var tmp = box.x + box.width - br.x; + if (tmp > 0) box.x -= tmp; + tmp = box.y + box.height - br.y; + if (tmp > 0) box.y -= tmp; + }; + this.element.style.display = "block"; + Calendar.continuation_for_khtml_browser = function() { + var w = self.element.offsetWidth; + var h = self.element.offsetHeight; + self.element.style.display = "none"; + var valign = opts.substr(0, 1); + var halign = "l"; + if (opts.length > 1) { + halign = opts.substr(1, 1); + } + // vertical alignment + switch (valign) { + case "T": p.y -= h; break; + case "B": p.y += el.offsetHeight; break; + case "C": p.y += (el.offsetHeight - h) / 2; break; + case "t": p.y += el.offsetHeight - h; break; + case "b": break; // already there + } + // horizontal alignment + switch (halign) { + case "L": p.x -= w; break; + case "R": p.x += el.offsetWidth; break; + case "C": p.x += (el.offsetWidth - w) / 2; break; + case "l": p.x += el.offsetWidth - w; break; + case "r": break; // already there + } + p.width = w; + p.height = h + 40; + self.monthsCombo.style.display = "none"; + fixPosition(p); + self.showAt(p.x, p.y); + }; + if (Calendar.is_khtml) + setTimeout("Calendar.continuation_for_khtml_browser()", 10); + else + Calendar.continuation_for_khtml_browser(); +}; + +/** Customizes the date format. */ +Calendar.prototype.setDateFormat = function (str) { + this.dateFormat = str; +}; + +/** Customizes the tooltip date format. */ +Calendar.prototype.setTtDateFormat = function (str) { + this.ttDateFormat = str; +}; + +/** + * Tries to identify the date represented in a string. If successful it also + * calls this.setDate which moves the calendar to the given date. + */ +Calendar.prototype.parseDate = function(str, fmt) { + if (!fmt) + fmt = this.dateFormat; + this.setDate(Date.parseDate(str, fmt)); +}; + +Calendar.prototype.hideShowCovered = function () { + if (!Calendar.is_ie && !Calendar.is_opera) + return; + function getVisib(obj){ + var value = obj.style.visibility; + if (!value) { + if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C + if (!Calendar.is_khtml) + value = document.defaultView. + getComputedStyle(obj, "").getPropertyValue("visibility"); + else + value = ''; + } else if (obj.currentStyle) { // IE + value = obj.currentStyle.visibility; + } else + value = ''; + } + return value; + }; + + var tags = new Array("applet", "iframe", "select"); + var el = this.element; + + var p = Calendar.getAbsolutePos(el); + var EX1 = p.x; + var EX2 = el.offsetWidth + EX1; + var EY1 = p.y; + var EY2 = el.offsetHeight + EY1; + + for (var k = tags.length; k > 0; ) { + var ar = document.getElementsByTagName(tags[--k]); + var cc = null; + + for (var i = ar.length; i > 0;) { + cc = ar[--i]; + + p = Calendar.getAbsolutePos(cc); + var CX1 = p.x; + var CX2 = cc.offsetWidth + CX1; + var CY1 = p.y; + var CY2 = cc.offsetHeight + CY1; + + if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) { + if (!cc.__msh_save_visibility) { + cc.__msh_save_visibility = getVisib(cc); + } + cc.style.visibility = cc.__msh_save_visibility; + } else { + if (!cc.__msh_save_visibility) { + cc.__msh_save_visibility = getVisib(cc); + } + cc.style.visibility = "hidden"; + } + } + } +}; + +/** Internal function; it displays the bar with the names of the weekday. */ +Calendar.prototype._displayWeekdays = function () { + var fdow = this.firstDayOfWeek; + var cell = this.firstdayname; + var weekend = Calendar._TT["WEEKEND"]; + for (var i = 0; i < 7; ++i) { + cell.className = "day name"; + var realday = (i + fdow) % 7; + if (i) { + cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]); + cell.navtype = 100; + cell.calendar = this; + cell.fdow = realday; + Calendar._add_evs(cell); + } + if (weekend.indexOf(realday.toString()) != -1) { + Calendar.addClass(cell, "weekend"); + } + cell.innerHTML = Calendar._SDN[(i + fdow) % 7]; + cell = cell.nextSibling; + } +}; + +/** Internal function. Hides all combo boxes that might be displayed. */ +Calendar.prototype._hideCombos = function () { + this.monthsCombo.style.display = "none"; + this.yearsCombo.style.display = "none"; +}; + +/** Internal function. Starts dragging the element. */ +Calendar.prototype._dragStart = function (ev) { + if (this.dragging) { + return; + } + this.dragging = true; + var posX; + var posY; + if (Calendar.is_ie) { + posY = window.event.clientY + document.body.scrollTop; + posX = window.event.clientX + document.body.scrollLeft; + } else { + posY = ev.clientY + window.scrollY; + posX = ev.clientX + window.scrollX; + } + var st = this.element.style; + this.xOffs = posX - parseInt(st.left); + this.yOffs = posY - parseInt(st.top); + with (Calendar) { + addEvent(document, "mousemove", calDragIt); + addEvent(document, "mouseup", calDragEnd); + } +}; + +// BEGIN: DATE OBJECT PATCHES + +/** Adds the number of days array to the Date object. */ +Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31); + +/** Constants used for time computations */ +Date.SECOND = 1000 /* milliseconds */; +Date.MINUTE = 60 * Date.SECOND; +Date.HOUR = 60 * Date.MINUTE; +Date.DAY = 24 * Date.HOUR; +Date.WEEK = 7 * Date.DAY; + +Date.parseDate = function(str, fmt) { + var today = new Date(); + var y = 0; + var m = -1; + var d = 0; + var a = str.split(/\W+/); + var b = fmt.match(/%./g); + var i = 0, j = 0; + var hr = 0; + var min = 0; + for (i = 0; i < a.length; ++i) { + if (!a[i]) + continue; + switch (b[i]) { + case "%d": + case "%e": + d = parseInt(a[i], 10); + break; + + case "%m": + m = parseInt(a[i], 10) - 1; + break; + + case "%Y": + case "%y": + y = parseInt(a[i], 10); + (y < 100) && (y += (y > 29) ? 1900 : 2000); + break; + + case "%b": + case "%B": + for (j = 0; j < 12; ++j) { + if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; } + } + break; + + case "%H": + case "%I": + case "%k": + case "%l": + hr = parseInt(a[i], 10); + break; + + case "%P": + case "%p": + if (/pm/i.test(a[i]) && hr < 12) + hr += 12; + else if (/am/i.test(a[i]) && hr >= 12) + hr -= 12; + break; + + case "%M": + min = parseInt(a[i], 10); + break; + } + } + if (isNaN(y)) y = today.getFullYear(); + if (isNaN(m)) m = today.getMonth(); + if (isNaN(d)) d = today.getDate(); + if (isNaN(hr)) hr = today.getHours(); + if (isNaN(min)) min = today.getMinutes(); + if (y != 0 && m != -1 && d != 0) + return new Date(y, m, d, hr, min, 0); + y = 0; m = -1; d = 0; + for (i = 0; i < a.length; ++i) { + if (a[i].search(/[a-zA-Z]+/) != -1) { + var t = -1; + for (j = 0; j < 12; ++j) { + if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; } + } + if (t != -1) { + if (m != -1) { + d = m+1; + } + m = t; + } + } else if (parseInt(a[i], 10) <= 12 && m == -1) { + m = a[i]-1; + } else if (parseInt(a[i], 10) > 31 && y == 0) { + y = parseInt(a[i], 10); + (y < 100) && (y += (y > 29) ? 1900 : 2000); + } else if (d == 0) { + d = a[i]; + } + } + if (y == 0) + y = today.getFullYear(); + if (m != -1 && d != 0) + return new Date(y, m, d, hr, min, 0); + return today; +}; + +/** Returns the number of days in the current month */ +Date.prototype.getMonthDays = function(month) { + var year = this.getFullYear(); + if (typeof month == "undefined") { + month = this.getMonth(); + } + if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) { + return 29; + } else { + return Date._MD[month]; + } +}; + +/** Returns the number of day in the year. */ +Date.prototype.getDayOfYear = function() { + var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); + var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0); + var time = now - then; + return Math.floor(time / Date.DAY); +}; + +/** Returns the number of the week in year, as defined in ISO 8601. */ +Date.prototype.getWeekNumber = function() { + var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); + var DoW = d.getDay(); + d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu + var ms = d.valueOf(); // GMT + d.setMonth(0); + d.setDate(4); // Thu in Week 1 + return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1; +}; + +/** Checks date and time equality */ +Date.prototype.equalsTo = function(date) { + return ((this.getFullYear() == date.getFullYear()) && + (this.getMonth() == date.getMonth()) && + (this.getDate() == date.getDate()) && + (this.getHours() == date.getHours()) && + (this.getMinutes() == date.getMinutes())); +}; + +/** Set only the year, month, date parts (keep existing time) */ +Date.prototype.setDateOnly = function(date) { + var tmp = new Date(date); + this.setDate(1); + this.setFullYear(tmp.getFullYear()); + this.setMonth(tmp.getMonth()); + this.setDate(tmp.getDate()); +}; + +/** Prints the date in a string according to the given format. */ +Date.prototype.print = function (str) { + var m = this.getMonth(); + var d = this.getDate(); + var y = this.getFullYear(); + var wn = this.getWeekNumber(); + var w = this.getDay(); + var s = {}; + var hr = this.getHours(); + var pm = (hr >= 12); + var ir = (pm) ? (hr - 12) : hr; + var dy = this.getDayOfYear(); + if (ir == 0) + ir = 12; + var min = this.getMinutes(); + var sec = this.getSeconds(); + s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N] + s["%A"] = Calendar._DN[w]; // full weekday name + s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N] + s["%B"] = Calendar._MN[m]; // full month name + // FIXME: %c : preferred date and time representation for the current locale + s["%C"] = 1 + Math.floor(y / 100); // the century number + s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31) + s["%e"] = d; // the day of the month (range 1 to 31) + // FIXME: %D : american date style: %m/%d/%y + // FIXME: %E, %F, %G, %g, %h (man strftime) + s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format) + s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format) + s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366) + s["%k"] = hr; // hour, range 0 to 23 (24h format) + s["%l"] = ir; // hour, range 1 to 12 (12h format) + s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12 + s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59 + s["%n"] = "\n"; // a newline character + s["%p"] = pm ? "PM" : "AM"; + s["%P"] = pm ? "pm" : "am"; + // FIXME: %r : the time in am/pm notation %I:%M:%S %p + // FIXME: %R : the time in 24-hour notation %H:%M + s["%s"] = Math.floor(this.getTime() / 1000); + s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59 + s["%t"] = "\t"; // a tab character + // FIXME: %T : the time in 24-hour notation (%H:%M:%S) + s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn; + s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON) + s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN) + // FIXME: %x : preferred date representation for the current locale without the time + // FIXME: %X : preferred time representation for the current locale without the date + s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99) + s["%Y"] = y; // year with the century + s["%%"] = "%"; // a literal '%' character + + var re = /%./g; + if (!Calendar.is_ie5 && !Calendar.is_khtml) + return str.replace(re, function (par) { return s[par] || par; }); + + var a = str.match(re); + for (var i = 0; i < a.length; i++) { + var tmp = s[a[i]]; + if (tmp) { + re = new RegExp(a[i], 'g'); + str = str.replace(re, tmp); + } + } + + return str; +}; + +Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear; +Date.prototype.setFullYear = function(y) { + var d = new Date(this); + d.__msh_oldSetFullYear(y); + if (d.getMonth() != this.getMonth()) + this.setDate(28); + this.__msh_oldSetFullYear(y); +}; + +// END: DATE OBJECT PATCHES + + +// global object that remembers the calendar +window._dynarch_popupCalendar = null; + + +function selectDate(cal) { + var p = cal.params; + var update = (cal.dateClicked || p.electric); + year = p.inputField.id; + + day = p.baseField + '_2'; + month = p.baseField + '_1'; + + document.getElementById(month).value = cal.date.print('%m'); + document.getElementById(day).value = cal.date.print('%e'); + document.getElementById(year).value = cal.date.print('%Y'); +} + +function selectEuropeDate(cal) { + var p = cal.params; + var update = (cal.dateClicked || p.electric); + year = p.inputField.id; + + day = p.baseField + '_1'; + month = p.baseField + '_2'; + + document.getElementById(month).value = cal.date.print('%m'); + document.getElementById(day).value = cal.date.print('%e'); + document.getElementById(year).value = cal.date.print('%Y'); +} + +// ** I18N + +// Calendar EN language +// Author: Mihai Bazon, +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// full day names +Calendar._DN = new Array +("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"); + +// short day names +Calendar._SDN = new Array +("S", "M", "T", "W", "T", "F", "S", "S"); + +// First day of the week. "0" means display Sunday first, "1" means display +// Monday first, etc. +Calendar._FD = 0; + +// full month names +Calendar._MN = new Array +("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); + +// short month names +Calendar._SMN = new Array +("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "About the Calendar"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Date selection:\n" + +"- Use the \xab, \xbb buttons to select year\n" + +"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" + +"- Hold mouse button on any of the above buttons for faster selection."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Time selection:\n" + +"- Click on any of the time parts to increase it\n" + +"- or Shift-click to decrease it\n" + +"- or click and drag for faster selection."; + +Calendar._TT["PREV_YEAR"] = "Prev. Year (Hold for Menu)"; +Calendar._TT["PREV_MONTH"] = "Prev. Month (Hold for Menu)"; +Calendar._TT["GO_TODAY"] = "Go to Today"; +Calendar._TT["NEXT_MONTH"] = "Next Month (Hold for Menu)"; +Calendar._TT["NEXT_YEAR"] = "Next Year (Hold for Menu)"; +Calendar._TT["SEL_DATE"] = "Select Date"; +Calendar._TT["DRAG_TO_MOVE"] = "Drag to Move"; +Calendar._TT["PART_TODAY"] = " (Today)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Display %ss first"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Close Calendar"; +Calendar._TT["TODAY"] = "Today"; +Calendar._TT["TIME_PART"] = "(Shift-)Click or Drag to Change Value"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%b %e, %Y"; + +Calendar._TT["WK"] = "wk"; +Calendar._TT["TIME"] = "Time:"; +/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ + * --------------------------------------------------------------------------- + * + * The DHTML Calendar + * + * Details and latest version at: + * http://dynarch.com/mishoo/calendar.epl + * + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html + * + */ + +// $Id: calendar-setup.js,v 1.25 2005/03/07 09:51:33 mishoo Exp $ + +Calendar.setup = function (params) { + function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } }; + + param_default("inputField", null); + param_default("displayArea", null); + param_default("button", null); + param_default("eventName", "click"); + param_default("ifFormat", "%Y/%m/%d"); + param_default("daFormat", "%Y/%m/%d"); + param_default("singleClick", true); + param_default("disableFunc", null); + param_default("dateStatusFunc", params["disableFunc"]); // takes precedence if both are defined + param_default("dateText", null); + param_default("firstDay", null); + param_default("align", "BR"); + param_default("range", [1900, 2999]); + param_default("weekNumbers", false); + param_default("flat", null); + param_default("flatCallback", null); + param_default("onSelect", null); + param_default("onClose", null); + param_default("onUpdate", null); + param_default("date", null); + param_default("showsTime", false); + param_default("timeFormat", "24"); + param_default("electric", true); + param_default("step", 2); + param_default("position", null); + param_default("cache", false); + param_default("showOthers", false); + param_default("multiple", null); + + var tmp = ["inputField", "displayArea", "button"]; + for (var i in tmp) { + if (typeof params[tmp[i]] == "string") { + params[tmp[i]] = document.getElementById(params[tmp[i]]); + } + } + if (!(params.flat || params.multiple || params.inputField || params.displayArea || params.button)) { + alert("Calendar.setup:\n Nothing to setup (no fields found). Please check your code"); + return false; + } + + function onSelect(cal) { + var p = cal.params; + var update = (cal.dateClicked || p.electric); + if (update && p.inputField) { + p.inputField.value = cal.date.print(p.ifFormat); + if (typeof p.inputField.onchange == "function") + p.inputField.onchange(); + } + if (update && p.displayArea) + p.displayArea.innerHTML = cal.date.print(p.daFormat); + if (update && typeof p.onUpdate == "function") + p.onUpdate(cal); + if (update && p.flat) { + if (typeof p.flatCallback == "function") + p.flatCallback(cal); + } + if (update && p.singleClick && cal.dateClicked) + cal.callCloseHandler(); + }; + + if (params.flat != null) { + if (typeof params.flat == "string") + params.flat = document.getElementById(params.flat); + if (!params.flat) { + alert("Calendar.setup:\n Flat specified but can't find parent."); + return false; + } + var cal = new Calendar(params.firstDay, params.date, params.onSelect || onSelect); + cal.showsOtherMonths = params.showOthers; + cal.showsTime = params.showsTime; + cal.time24 = (params.timeFormat == "24"); + cal.params = params; + cal.weekNumbers = params.weekNumbers; + cal.setRange(params.range[0], params.range[1]); + cal.setDateStatusHandler(params.dateStatusFunc); + cal.getDateText = params.dateText; + if (params.ifFormat) { + cal.setDateFormat(params.ifFormat); + } + if (params.inputField && typeof params.inputField.value == "string") { + cal.parseDate(params.inputField.value); + } + cal.create(params.flat); + cal.show(); + return false; + } + + var triggerEl = params.button || params.displayArea || params.inputField; + triggerEl["on" + params.eventName] = function() { + var dateEl = params.inputField || params.displayArea; + var dateFmt = params.inputField ? params.ifFormat : params.daFormat; + var mustCreate = false; + var cal = window.calendar; + if (dateEl) + params.date = Date.parseDate(dateEl.value || dateEl.innerHTML, dateFmt); + if (!(cal && params.cache)) { + window.calendar = cal = new Calendar(params.firstDay, + params.date, + params.onSelect || onSelect, + params.onClose || function(cal) { cal.hide(); }); + cal.showsTime = params.showsTime; + cal.time24 = (params.timeFormat == "24"); + cal.weekNumbers = params.weekNumbers; + mustCreate = true; + } else { + if (params.date) + cal.setDate(params.date); + cal.hide(); + } + if (params.multiple) { + cal.multiple = {}; + for (var i = params.multiple.length; --i >= 0;) { + var d = params.multiple[i]; + var ds = d.print("%Y%m%d"); + cal.multiple[ds] = d; + } + } + cal.showsOtherMonths = params.showOthers; + cal.yearStep = params.step; + cal.setRange(params.range[0], params.range[1]); + cal.params = params; + cal.setDateStatusHandler(params.dateStatusFunc); + cal.getDateText = params.dateText; + cal.setDateFormat(dateFmt); + if (mustCreate) + cal.create(); + cal.refresh(); + if (!params.position) + cal.showAtElement(params.button || params.displayArea || params.inputField, params.align); + else + cal.showAt(params.position[0], params.position[1]); + return false; + }; + + return cal; +}; \ No newline at end of file diff --git a/js/email_entry.js b/js/email_entry.js new file mode 100644 index 0000000..89e939e --- /dev/null +++ b/js/email_entry.js @@ -0,0 +1,305 @@ +/* + * SimpleModal Contact Form + * http://www.ericmmartin.com/projects/simplemodal/ + * http://code.google.com/p/simplemodal/ + * + * Copyright (c) 2007 Eric Martin - http://ericmmartin.com + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * Revision: $Id: contact.js 113 2008-03-15 15:36:21Z emartin24 $ + * + */ +function email_entry(i_form_id,i_entry_id){ + // load the contact form using ajax + $.get("email_entry.php",{form_id: i_form_id, entry_id: i_entry_id}, function(data){ + // create a modal dialog with the data + $(data).modal({ + close: false, + overlayId: 'contact-overlay', + containerId: 'contact-container', + onOpen: contact.open, + onShow: contact.show, + onClose: contact.close + }); + }); +} + +$(document).ready(function () { + $('#ve_detail_table').columnHover(); + + + // preload images + var img = ['cancel.png','form_bottom.gif','form_top.gif','form_top_ie.gif','ajax-loader.gif','send.png']; + $(img).each(function () { + var i = new Image(); + i.src = 'images/simple_modal/' + this; + }); +}); + +function explode( delimiter, string ) { + // http://kevin.vanzonneveld.net + // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + improved by: kenneth + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // * example 1: explode(' ', 'Kevin van Zonneveld'); + // * returns 1: {0: 'Kevin', 1: 'van', 2: 'Zonneveld'} + + var emptyArray = { 0: '' }; + + if ( arguments.length != 2 + || typeof arguments[0] == 'undefined' + || typeof arguments[1] == 'undefined' ) + { + return null; + } + + if ( delimiter === '' + || delimiter === false + || delimiter === null ) + { + return false; + } + + if ( typeof delimiter == 'function' + || typeof delimiter == 'object' + || typeof string == 'function' + || typeof string == 'object' ) + { + return emptyArray; + } + + if ( delimiter === true ) { + delimiter = '1'; + } + + return string.toString().split ( delimiter.toString() ); +} + +function trim( str, charlist ) { + // http://kevin.vanzonneveld.net + // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + improved by: mdsjack (http://www.mdsjack.bo.it) + // + improved by: Alexander Ermolaev (http://snippets.dzone.com/user/AlexanderErmolaev) + // + input by: Erkekjetter + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + input by: DxGx + // + improved by: Steven Levithan (http://blog.stevenlevithan.com) + // * example 1: trim(' Kevin van Zonneveld '); + // * returns 1: 'Kevin van Zonneveld' + // * example 2: trim('Hello World', 'Hdle'); + // * returns 2: 'o Wor' + + var whitespace; + + if(!charlist){ + whitespace = ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000'; + } else{ + whitespace = charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '\$1'); + } + + for (var i = 0; i < str.length; i++) { + if (whitespace.indexOf(str.charAt(i)) === -1) { + str = str.substring(i); + break; + } + } + for (i = str.length - 1; i >= 0; i--) { + if (whitespace.indexOf(str.charAt(i)) === -1) { + str = str.substring(0, i + 1); + break; + } + } + return whitespace.indexOf(str.charAt(0)) === -1 ? str : ''; +} + +var contact = { + message: null, + open: function (dialog) { + // add padding to the buttons in firefox/mozilla + if ($.browser.mozilla) { + $('#contact-container .contact-button').css({ + 'padding-bottom': '2px' + }); + } + // input field font size + if ($.browser.safari) { + $('#contact-container .contact-input').css({ + 'font-size': '.9em' + }); + } + + var title = $('#contact-container .contact-title').html(); + $('#contact-container .contact-title').html('Loading...'); + dialog.overlay.fadeIn(200, function () { + dialog.container.fadeIn(200, function () { + dialog.data.fadeIn(200, function () { + $('#contact-container .contact-content').animate({ + height: 205 + }, function () { + $('#contact-container .contact-title').html(title); + $('#contact-container form').fadeIn(200, function () { + $('#contact-container #contact-name').focus(); + + // fix png's for IE 6 + if ($.browser.msie && $.browser.version < 7) { + $('#contact-container .contact-button').each(function () { + if ($(this).css('backgroundImage').match(/^url[("']+(.*\.png)[)"']+$/i)) { + var src = RegExp.$1; + $(this).css({ + backgroundImage: 'none', + filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + src + '", sizingMethod="crop")' + }); + } + }); + } + }); + }); + }); + }); + }); + }, + show: function (dialog) { + $('#contact-container .contact-send').click(function (e) { + e.preventDefault(); + // validate form + if (contact.validate()) { + $('#contact-container .contact-message').fadeOut(function () { + $('#contact-container .contact-message').removeClass('contact-error').empty(); + }); + $('#contact-container .contact-title').html('Sending...'); + $('#contact-container form').fadeOut(200); + $('#contact-container .contact-content').animate({ + height: '110px' + }, function () { + if ($.browser.msie){ + $('#contact-container .contact-loading').css("margin-left","-40px"); + } + $('#contact-container .contact-loading').fadeIn(200, function () { + $.ajax({ + url: 'email_entry.php', + data: $('#contact-container form').serialize() + '&action=send', + type: 'post', + cache: false, + dataType: 'html', + complete: function (xhr) { + $('#contact-container .contact-loading').fadeOut(200, function () { + $('#contact-container .contact-title').html('Email sent.'); + $('#contact-container .contact-message').html(xhr.responseText).fadeIn(200); + }); + }, + error: contact.error + }); + }); + }); + } + else { + if ($('#contact-container .contact-message:visible').length > 0) { + var msg = $('#contact-container .contact-message div'); + msg.fadeOut(200, function () { + msg.empty(); + contact.showError(); + msg.fadeIn(200); + }); + } + else { + $('#contact-container .contact-message').animate({ + height: '30px' + }, contact.showError); + } + + } + }); + }, + close: function (dialog) { + $('#contact-container .contact-message').fadeOut(); + $('#contact-container .contact-title').html(' '); + $('#contact-container form').fadeOut(200); + $('#contact-container .contact-content').animate({ + height: 40 + }, function () { + dialog.data.fadeOut(200, function () { + dialog.container.fadeOut(200, function () { + dialog.overlay.fadeOut(200, function () { + $.modal.close(); + }); + }); + }); + }); + }, + error: function (xhr) { + alert(xhr.statusText); + }, + validate: function () { + contact.message = ''; + + var email = $('#contact-container #contact-email').val(); + if (!email) { + contact.message += 'Email is required. '; + } + else { + email_array = explode(',',email); + var arLen=email_array.length; + for ( var i=0; i 0) { + return false; + } + else { + return true; + } + }, + validateEmail: function (email) { + var at = email.lastIndexOf("@"); + + // Make sure the at (@) sybmol exists and + // it is not the first or last character + if (at < 1 || (at + 1) === email.length) + return false; + + // Make sure there aren't multiple periods together + if (/(\.{2,})/.test(email)) + return false; + + // Break up the local and domain portions + var local = email.substring(0, at); + var domain = email.substring(at + 1); + + // Check lengths + if (local.length < 1 || local.length > 64 || domain.length < 4 || domain.length > 255) + return false; + + // Make sure local and domain don't start with or end with a period + if (/(^\.|\.$)/.test(local) || /(^\.|\.$)/.test(domain)) + return false; + + // Check for quoted-string addresses + // Since almost anything is allowed in a quoted-string address, + // we're just going to let them go through + if (!/^"(.+)"$/.test(local)) { + // It's a dot-string address...check for valid characters + if (!/^[-a-zA-Z0-9!#$%*\/?|^{}`~&'+=_\.]*$/.test(local)) + return false; + } + + // Make sure domain contains only valid characters and at least one period + if (!/^[-a-zA-Z0-9\.]*$/.test(domain) || domain.indexOf(".") === -1) + return false; + + return true; + }, + showError: function () { + $('#contact-container .contact-message') + .html($('
    ').append(contact.message)) + .fadeIn(200); + } +}; \ No newline at end of file diff --git a/js/jquery/jquery-columnhover.js b/js/jquery/jquery-columnhover.js new file mode 100644 index 0000000..3d650bd --- /dev/null +++ b/js/jquery/jquery-columnhover.js @@ -0,0 +1,200 @@ +/* + * jQuery columnHover plugin + * Version: 0.1.1 + * + * Copyright (c) 2007 Roman Weich + * http://p.sohei.org + * + * Dual licensed under the MIT and GPL licenses + * (This means that you can choose the license that best suits your project, and use it accordingly): + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Changelog: + * v 0.1.1 - 2007-08-05 + * -change: included new option "ignoreCols", through which columns can be excluded from the highlighting process + * v 0.1.0 - 2007-05-25 + */ + +(function($) +{ + /** + * Calculates the actual cellIndex value of all cells in the table and stores it in the realCell property of each cell. + * Thats done because the cellIndex value isn't correct when colspans or rowspans are used. + * Originally created by Matt Kruse for his table library - Big Thanks! (see http://www.javascripttoolbox.com/) + * @param {element} table The table element. + */ + var fixCellIndexes = function(table) + { + var rows = table.rows; + var len = rows.length; + var matrix = []; + for ( var i = 0; i < len; i++ ) + { + var cells = rows[i].cells; + var clen = cells.length; + for ( var j = 0; j < clen; j++ ) + { + var c = cells[j]; + var rowSpan = c.rowSpan || 1; + var colSpan = c.colSpan || 1; + var firstAvailCol = -1; + if ( !matrix[i] ) + { + matrix[i] = []; + } + var m = matrix[i]; + // Find first available column in the first row + while ( m[++firstAvailCol] ) {} + c.realIndex = firstAvailCol; + for ( var k = i; k < i + rowSpan; k++ ) + { + if ( !matrix[k] ) + { + matrix[k] = []; + } + var matrixrow = matrix[k]; + for ( var l = firstAvailCol; l < firstAvailCol + colSpan; l++ ) + { + matrixrow[l] = 1; + } + } + } + } + }; + + /** + * Highlight whole table columns when hovering over a table. + * Works on tables with rowspans and colspans. + * + * @param {map} options An object for optional settings (options described below). + * + * @option {string} hoverClass A CSS class that is set on the cells in the column with the mouse over. + * Default value: 'hover' + * @option {boolean} eachCell Allows highlighting the column while hovering over the table body or table footer. When disabled, highlighting is allowed only through the table header. + * Default value: false + * @option {boolean} includeSpans Includes columns with the colspan attribute set in the hover and highlight process. + * Default value: true + * @option {array} ignoreCols An array of numbers. Each column with the matching column index won't be included in the highlighting process. + * Index starting at 1! + * Default value: [] (empty array) + * + * @example $('#table').columnHover(); + * @desc Allow column hovering/highlighting for the table using the default settings. + * + * @example $('#table').columnHover({eachCell:true, hoverClass:'someclass'}); + * @desc Allow column hovering/highlighting for the whole table (including the body and footer). Set the class "someclass" to the cells in the column with the mouse over. + * + * @type jQuery + * + * @name columnHover + * @cat Plugins/columnHover + * @author Roman Weich (http://p.sohei.org) + */ + $.fn.columnHover = function(options) + { + var settings = $.extend({ + hoverClass: 'hover', + eachCell: false, + includeSpans : true, + ignoreCols : [] + }, options); + + /** + * Adds or removes the hover style on the column. + * @param {element} cell The cell with the mouseover/mouseout event. + * @param {array} colIndex The index with the stored columns. + * @param {boolean} on Defines whether the style will be set or removed. + */ + var hover = function(cell, colIndex, on) + { + var a = colIndex[cell.realIndex]; + var i = 0; + if ( $(settings.ignoreCols).index(cell.realIndex + 1) != -1 ) + { + return; //dont highlight the columns in the ignoreCols array + } + while ( ++i < cell.colSpan ) + { + a = a.concat(colIndex[cell.realIndex + i]); + } + if ( on ) + { + $(a).addClass(settings.hoverClass); + } + else + { + $(a).removeClass(settings.hoverClass); + } + }; + + /** + * Adds the hover events to the cell. + * @param {jQuery result array} $s The elements to add the events to. + * @param {array} colIndex The index with the stored columns. + */ + var addHover = function($s, colIndex) + { + $s.bind('mouseover', function(){ + hover(this, colIndex, true); + }).bind('mouseout', function(){ + hover(this, colIndex, false); + }); + }; + + return this.each(function() + { + var colIndex = []; + var tbl = this; + var body, row, c, tboI, rowI, cI, rI, s; + + if ( !tbl.tBodies || !tbl.tBodies.length || !tbl.tHead || !settings.hoverClass.length ) + { + return; + } + fixCellIndexes(tbl); + //create index - loop through the bodies + for ( tboI = 0; tboI < tbl.tBodies.length; tboI++ ) + { + body = tbl.tBodies[tboI]; + //loop through the rows + for ( rowI = 0; rowI < body.rows.length; rowI++ ) + { + row = body.rows[rowI]; + //each cell + for ( cI = 0; cI < row.cells.length; cI++ ) + { + c = row.cells[cI]; + //ignore cells with colspan? + if ( !settings.includeSpans && c.colSpan > 1 ) + { + continue; + } + s = (settings.includeSpans) ? c.colSpan : 1; + while ( --s >= 0 ) + { + rI = c.realIndex + s; + if ( !colIndex[rI] ) + { + colIndex[rI] = []; + } + colIndex[rI].push(c); + } + //add hover event? + if ( settings.eachCell ) + { + addHover($(c), colIndex); + } + } + } + } + //events + addHover($('td, th', tbl.tHead), colIndex); + //add hover event to footer? + if ( settings.eachCell && tbl.tFoot ) + { + addHover($('td, th', tbl.tFoot), colIndex); + } + }); + }; +})(jQuery); diff --git a/js/jquery/jquery-core.js b/js/jquery/jquery-core.js new file mode 100644 index 0000000..3747929 --- /dev/null +++ b/js/jquery/jquery-core.js @@ -0,0 +1,32 @@ +/* + * jQuery 1.2.3 - New Wave Javascript + * + * Copyright (c) 2008 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $ + * $Rev: 4663 $ + */ +(function(){if(window.jQuery)var _jQuery=window.jQuery;var jQuery=window.jQuery=function(selector,context){return new jQuery.prototype.init(selector,context);};if(window.$)var _$=window.$;window.$=jQuery;var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;var isSimple=/^.[^:#\[\.]*$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}else if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem)if(elem.id!=match[3])return jQuery().find(selector);else{this[0]=elem;this.length=1;return this;}else +selector=[];}}else +return new jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return new jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(selector.constructor==Array&&selector||(selector.jquery||selector.length&&selector!=window&&!selector.nodeType&&selector[0]!=undefined&&selector[0].nodeType)&&jQuery.makeArray(selector)||[selector]);},jquery:"1.2.3",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;this.each(function(i){if(this==elem)ret=i;});return ret;},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value==undefined)return this.length&&jQuery[type||"attr"](this[0],name)||undefined;else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else +return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else +selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return!selector?this:this.pushStack(jQuery.merge(this.get(),selector.constructor==String?jQuery(selector).get():selector.length!=undefined&&(!selector.nodeName||jQuery.nodeName(selector,"form"))?selector:[selector]));},is:function(selector){return selector?jQuery.multiFilter(selector,this).length>0:false;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=value.constructor==Array?value:[value];jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else +this.value=value;});},html:function(value){return value==undefined?(this.length?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value==null){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data==undefined&&this.length)data=jQuery.data(this[0],key);return data==null&&parts[1]?this.data(parts[0]):data;}else +return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script")){scripts=scripts.add(elem);}else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.prototype.init.prototype=jQuery.prototype;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else +jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==1){target=this;i=0;}for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else +jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret;function color(elem){if(!jQuery.browser.safari)return false;var ret=document.defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(elem.style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=elem.style.outline;elem.style.outline="0 solid black";elem.style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&elem.style&&elem.style[name])ret=elem.style[name];else if(document.defaultView&&document.defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var getComputedStyle=document.defaultView.getComputedStyle(elem,null);if(getComputedStyle&&!color(elem))ret=getComputedStyle.getPropertyValue(name);else{var swap=[],stack=[];for(var a=elem;a&&color(a);a=a.parentNode)stack.unshift(a);for(var i=0;i]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
    "]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||jQuery.browser.msie&&[1,"div
    ","
    "]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf(""&&tags.indexOf("=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else +ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var fix=jQuery.isXMLDoc(elem)?{}:jQuery.props;if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(fix[name]){if(value!=undefined)elem[fix[name]]=value;return elem[fix[name]];}else if(jQuery.browser.msie&&name=="style")return jQuery.attr(elem.style,"cssText",value);else if(value==undefined&&jQuery.browser.msie&&jQuery.nodeName(elem,"form")&&(name=="action"||name=="method"))return elem.getAttributeNode(name).nodeValue;else if(elem.tagName){if(value!=undefined){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem.setAttribute(name,""+value);}if(jQuery.browser.msie&&/href|src/.test(name)&&!jQuery.isXMLDoc(elem))return elem.getAttribute(name,2);return elem.getAttribute(name);}else{if(name=="opacity"&&jQuery.browser.msie){if(value!=undefined){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseFloat(value).toString()=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100).toString():"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(value!=undefined)elem[name]=value;return elem[name];}},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(typeof array!="array")for(var i=0,length=array.length;i*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return im[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false;var re=quickChild;var m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[];var cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&(!elem||n!=elem))r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval!=undefined)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=function(){return fn.apply(this,arguments);};handler.data=data;handler.guid=fn.guid;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){var val;if(typeof jQuery=="undefined"||jQuery.event.triggered)return val;val=jQuery.event.handle.apply(arguments.callee.elem,arguments);return val;});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else +for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data||[]);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event)data.unshift(this.fix({type:type,target:elem}));data[0].type=type;if(exclusive)data[0].exclusive=true;if(jQuery.isFunction(jQuery.data(elem,"handle")))val=jQuery.data(elem,"handle").apply(elem,data);if(!fn&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val;event=jQuery.event.fix(event||window.event||{});var parts=event.type.split(".");event.type=parts[0];var handlers=jQuery.data(this,"events")&&jQuery.data(this,"events")[event.type],args=Array.prototype.slice.call(arguments,1);args.unshift(event);for(var j in handlers){var handler=handlers[j];args[0].handler=handler;args[0].data=handler.data;if(!parts[1]&&!event.exclusive||handler.type==parts[1]){var ret=handler.apply(this,args);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}if(jQuery.browser.msie)event.target=event.preventDefault=event.stopPropagation=event.handler=event.data=null;return val;},fix:function(event){var originalEvent=event;event=jQuery.extend({},originalEvent);event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=originalEvent.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;arguments[0].type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;arguments[0].type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){return this.each(function(){jQuery.event.add(this,type,function(event){jQuery(this).unbind(event);return(fn||data).apply(this,arguments);},fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){if(this[0])return jQuery.event.trigger(type,data,this[0],false,fn);return undefined;},toggle:function(){var args=arguments;return this.click(function(event){this.lastToggle=0==this.lastToggle?1:0;event.preventDefault();return args[this.lastToggle].apply(this,arguments)||false;});},hover:function(fnOver,fnOut){return this.bind('mouseenter',fnOver).bind('mouseleave',fnOut);},ready:function(fn){bindReady();if(jQuery.isReady)fn.call(document,jQuery);else +jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.apply(document);});jQuery.readyList=null;}jQuery(document).triggerHandler("ready");}}});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(document.addEventListener&&!jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);if(jQuery.browser.msie&&window==top)(function(){if(jQuery.isReady)return;try{document.documentElement.doScroll("left");}catch(error){setTimeout(arguments.callee,0);return;}jQuery.ready();})();if(jQuery.browser.opera)document.addEventListener("DOMContentLoaded",function(){if(jQuery.isReady)return;for(var i=0;i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
    ").append(res.responseText.replace(//g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=(new Date).getTime();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){var jsonp,jsre=/=\?(&|$)/g,status,data;s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(s.type.toLowerCase()=="get"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&s.type.toLowerCase()=="get"){var ts=(new Date()).getTime();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&s.type.toLowerCase()=="get"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");if((!s.url.indexOf("http")||!s.url.indexOf("//"))&&s.dataType=="script"&&s.type.toLowerCase()=="get"){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xml=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();xml.open(s.type,s.url,s.async,s.username,s.password);try{if(s.data)xml.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xml.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xml.setRequestHeader("X-Requested-With","XMLHttpRequest");xml.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend)s.beforeSend(xml);if(s.global)jQuery.event.trigger("ajaxSend",[xml,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xml&&(xml.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xml)&&"error"||s.ifModified&&jQuery.httpNotModified(xml,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xml,s.dataType);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xml.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else +jQuery.handleError(s,xml,status);complete();if(s.async)xml=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xml){xml.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xml.send(s.data);}catch(e){jQuery.handleError(s,xml,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s]);}function complete(){if(s.complete)s.complete(xml,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xml;},handleError:function(s,xml,status,e){if(s.error)s.error(xml,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xml,s,e]);},active:0,httpSuccess:function(r){try{return!r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||r.status==1223||jQuery.browser.safari&&r.status==undefined;}catch(e){}return false;},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined;}catch(e){}return false;},httpData:function(r,type){var ct=r.getResponseHeader("content-type");var xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0;var data=xml?r.responseXML:r.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else +for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else +s.push(encodeURIComponent(j)+"="+encodeURIComponent(a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall);var hidden=jQuery(this).is(":hidden"),self=this;for(var p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return jQuery.isFunction(opt.complete)&&opt.complete.apply(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else +e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.apply(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(!elem)return undefined;type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",array?jQuery.makeArray(array):[]);return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].apply(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:{slow:600,fast:200}[opt.duration])||400;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.apply(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.apply(this.elem,[this.now,this]);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done&&jQuery.isFunction(this.options.complete))this.options.complete.apply(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}};jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),fixed=jQuery.css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&jQuery.css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||jQuery.css(offsetChild,"position")=="absolute"))||(mozilla&&jQuery.css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}return results;};})(); \ No newline at end of file diff --git a/js/jquery/jquery-simplemodal.js b/js/jquery/jquery-simplemodal.js new file mode 100644 index 0000000..84f4dd0 --- /dev/null +++ b/js/jquery/jquery-simplemodal.js @@ -0,0 +1,16 @@ +/* + * SimpleModal 1.1.1 - jQuery Plugin + * http://www.ericmmartin.com/projects/simplemodal/ + * http://plugins.jquery.com/project/SimpleModal + * http://code.google.com/p/simplemodal/ + * + * Copyright (c) 2007 Eric Martin - http://ericmmartin.com + * + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * Revision: $Id: jquery.simplemodal.js 93 2008-01-15 16:14:20Z emartin24 $ + * + */ +(function($){$.modal=function(data,options){return $.modal.impl.init(data,options);};$.modal.close=function(){$.modal.impl.close(true);};$.fn.modal=function(options){return $.modal.impl.init(this,options);};$.modal.defaults={overlay:50,overlayId:'modalOverlay',overlayCss:{},containerId:'modalContainer',containerCss:{},close:true,closeTitle:'Close',closeClass:'modalClose',persist:false,onOpen:null,onShow:null,onClose:null};$.modal.impl={opts:null,dialog:{},init:function(data,options){if(this.dialog.data){return false;}this.opts=$.extend({},$.modal.defaults,options);if(typeof data=='object'){data=data instanceof jQuery?data:$(data);if(data.parent().parent().size()>0){this.dialog.parentNode=data.parent();if(!this.opts.persist){this.dialog.original=data.clone(true);}}}else if(typeof data=='string'||typeof data=='number'){data=$('
    ').html(data);}else{if(console){console.log('SimpleModal Error: Unsupported data type: '+typeof data);}return false;}this.dialog.data=data.addClass('modalData');data=null;this.create();this.open();if($.isFunction(this.opts.onShow)){this.opts.onShow.apply(this,[this.dialog]);}return this;},create:function(){this.dialog.overlay=$('
    ').attr('id',this.opts.overlayId).addClass('modalOverlay').css($.extend(this.opts.overlayCss,{opacity:this.opts.overlay/100,height:'100%',width:'100%',position:'fixed',left:0,top:0,zIndex:3000})).hide().appendTo('body');this.dialog.container=$('
    ').attr('id',this.opts.containerId).addClass('modalContainer').css($.extend(this.opts.containerCss,{position:'fixed',zIndex:3100})).append(this.opts.close?'':'').hide().appendTo('body');if($.browser.msie&&($.browser.version<7)){this.fixIE();}this.dialog.container.append(this.dialog.data.hide());},bindEvents:function(){var modal=this;$('.'+this.opts.closeClass).click(function(e){e.preventDefault();modal.close();});},unbindEvents:function(){$('.'+this.opts.closeClass).unbind('click');},fixIE:function(){var wHeight=$(document.body).height()+'px';var wWidth=$(document.body).width()+'px';this.dialog.overlay.css({position:'absolute',height:wHeight,width:wWidth});this.dialog.container.css({position:'absolute'});this.dialog.iframe=$('
    + + + '; +} + + + + +/** + * A ReCaptchaResponse is returned from recaptcha_check_answer() + */ +class ReCaptchaResponse { + var $is_valid; + var $error; +} + + +/** + * Calls an HTTP POST function to verify if the user's guess was correct + * @param string $privkey + * @param string $remoteip + * @param string $challenge + * @param string $response + * @return ReCaptchaResponse + */ +function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response) +{ + if ($privkey == null || $privkey == '') { + die ("To use reCAPTCHA you must get an API key from http://recaptcha.net/api/getkey"); + } + + if ($remoteip == null || $remoteip == '') { + die ("For security reasons, you must pass the remote ip to reCAPTCHA"); + } + + + + //discard spam submissions + if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) { + $recaptcha_response = new ReCaptchaResponse(); + $recaptcha_response->is_valid = false; + $recaptcha_response->error = 'incorrect-captcha-sol'; + return $recaptcha_response; + } + + $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/verify", + array ( + 'privatekey' => $privkey, + 'remoteip' => $remoteip, + 'challenge' => $challenge, + 'response' => $response + ) + ); + + if($response === false){ + return false; + } + + $answers = explode ("\n", $response [1]); + $recaptcha_response = new ReCaptchaResponse(); + + if (trim ($answers [0]) == 'true') { + $recaptcha_response->is_valid = true; + } + else { + $recaptcha_response->is_valid = false; + $recaptcha_response->error = $answers [1]; + } + return $recaptcha_response; + +} + +/** + * gets a URL where the user can sign up for reCAPTCHA. If your application + * has a configuration page where you enter a key, you should provide a link + * using this function. + * @param string $domain The domain where the page is hosted + * @param string $appname The name of your application + */ +function recaptcha_get_signup_url ($domain = null, $appname = null) { + return "http://recaptcha.net/api/getkey?" . _recaptcha_qsencode (array ('domain' => $domain, 'app' => $appname)); +} + +function _recaptcha_aes_pad($val) { + $block_size = 16; + $numpad = $block_size - (strlen ($val) % $block_size); + return str_pad($val, strlen ($val) + $numpad, chr($numpad)); +} + +/* Mailhide related code */ + +function _recaptcha_aes_encrypt($val,$ky) { + if (! function_exists ("mcrypt_encrypt")) { + die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed."); + } + $mode=MCRYPT_MODE_CBC; + $enc=MCRYPT_RIJNDAEL_128; + $val=_recaptcha_aes_pad($val); + return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); +} + + +function _recaptcha_mailhide_urlbase64 ($x) { + return strtr(base64_encode ($x), '+/', '-_'); +} + +/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */ +function recaptcha_mailhide_url($pubkey, $privkey, $email) { + if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) { + die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " . + "you can do so at http://mailhide.recaptcha.net/apikey"); + } + + + $ky = pack('H*', $privkey); + $cryptmail = _recaptcha_aes_encrypt ($email, $ky); + + return "http://mailhide.recaptcha.net/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail); +} + +/** + * gets the parts of the email to expose to the user. + * eg, given johndoe@example,com return ["john", "example.com"]. + * the email is then displayed as john...@example.com + */ +function _recaptcha_mailhide_email_parts ($email) { + $arr = preg_split("/@/", $email ); + + if (strlen ($arr[0]) <= 4) { + $arr[0] = substr ($arr[0], 0, 1); + } else if (strlen ($arr[0]) <= 6) { + $arr[0] = substr ($arr[0], 0, 3); + } else { + $arr[0] = substr ($arr[0], 0, 4); + } + return $arr; +} + +/** + * Gets html to display an email address given a public an private key. + * to get a key, go to: + * + * http://mailhide.recaptcha.net/apikey + */ +function recaptcha_mailhide_html($pubkey, $privkey, $email) { + $emailparts = _recaptcha_mailhide_email_parts ($email); + $url = recaptcha_mailhide_url ($pubkey, $privkey, $email); + + return htmlentities($emailparts[0]) . "...@" . htmlentities ($emailparts [1]); + +} + + +?> diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..d212ee2 --- /dev/null +++ b/license.txt @@ -0,0 +1 @@ +APPNITRO SOFTWARE LICENSE TERMS AND CONDITIONS This End User License Agreement (the "Agreement") is a binding legal agreement between you and Appnitro Software (the "Author"). By installing or using MachForm (the "Software"), you agree to be bound by the terms of this Agreement. If you do not agree to the Agreement, do not download, install, or use the Software. Installation or use of the Software signifies that you have read, understood, and agreed to be bound by the Agreement. The Author reserves the right to alter this agreement at any time, for any reason, without notice. Usage This Agreement grants a non-exclusive, non-transferable license to install and use the Software on a single Website. Additional Software licenses must be purchased in order to install and use the Software on additional Websites. The Author reserves the right to determine whether use of the Software qualifies under this Agreement. The Author owns all rights, title and interest to the Software (including all intellectual property rights) and reserves all rights to the Software that are not expressly granted in this Agreement. Backups You may make copies of the Software in any machine readable form solely for back-up purposes, provided that you reproduce the Software in its original form and with all proprietary notices on the back-up copy. All rights to the Software not expressly granted herein are reserved by the Author. Restrictions You understand and agree that you shall only use the Software in a manner that complies with any and all applicable laws in the jurisdictions in which you use the Software. Your use shall be in accordance with applicable restrictions concerning privacy and intellectual property rights. You may not: * Use the Software to provide services to others; such as the basis of a hosted form-building service, or any other services which is a direct competition against The Author; * Distribute derivative works based on the Software; * Reproduce the Software except as described in this Agreement; * Sell, assign, license, disclose, distribute, or otherwise transfer or make available the Software or its Source Code, in whole or in part, in any form to any third parties; * Remove or alter any copyright notices on the Software; * Use the Software in any site which endorse unlawful manner or for any unlawful purpose (such as Pornography & Adult Content site, Gambling Transactions or Sports Gambling Prognostication, etc). Support If you purchased a support contract, The Author will respond to your requests for technical support during the term of your support contract. To reach customer support services, please contact Appnitro Software by e-mail at customer.service@appnitro.com. A valid Customer ID is required for support. We generally respond to e-mails within one business day. Support contracts run from year to year. You may purchase a support contract only for a full one-year term.We reserve the right to increase the price of our support contracts from year to year. You acknowledge that the Software is inherently complex, that not all errors will be identifiable or be corrected and that the time it might take to correct errors may not be commercially reasonable. The Author provides support on a "best efforts" basis only and does not represent or warrant that it will be able to resolve every technical support request. THE SOFTWARE IS OFFERED ON AN "AS-IS" BASIS AND NO WARRANTY, EITHER EXPRESSED OR IMPLIED, IS GIVEN. THE AUTHOR EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. YOU ASSUME ALL RISK ASSOCIATED WITH THE QUALITY, PERFORMANCE, INSTALLATION AND USE OF THE SOFTWARE INCLUDING, BUT NOT LIMITED TO, THE RISKS OF PROGRAM ERRORS, DAMAGE TO EQUIPMENT, LOSS OF DATA OR SOFTWARE PROGRAMS, OR UNAVAILABILITY OR INTERRUPTION OF OPERATIONS. YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USE THE SOFTWARE AND ASSUME ALL RISKS ASSOCIATED WITH ITS USE. Term, Termination, and Modification. You may use the Software under this Agreement until either party terminates this Agreement as set forth in this paragraph. Either party may terminate the Agreement at any time, upon written notice to the other party. Upon termination, all licenses granted to you will terminate, and you will immediately uninstall and cease all use of the Software. The Sections entitled "No Warranty," "Indemnification," and "Limitation of Liability" will survive any termination of this Agreement. The Author may modify the Software with notice to you either in email or by publishing content on the Software website, including but not limited to changing the functionality or appearance of the Software, and such modification will become binding on you unless you terminate this Agreement. The Software source code may be altered (at your own risk). However, modifying your source code may void the technical support portion of your support contract Indemnification. By accepting the Agreement, you agree to indemnify and otherwise hold harmless the Author, its officers, employers, agents, subsidiaries, affiliates and other partners from any direct, indirect, incidental, special, consequential or exemplary damages arising out of, relating to, or resulting from your use of the Software or any other matter relating to the Software. Limitation of Liability. YOU EXPRESSLY UNDERSTAND AND AGREE THAT THE AUTHOR SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES, INCLUDING BUT NOT LIMITED TO, DAMAGES FOR LOSS OF PROFITS, GOODWILL, USE, DATA OR OTHER INTANGIBLE LOSSES (EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES). SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF THE LIMITATION OR EXCLUSION OF LIABILITY FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES. ACCORDINGLY, SOME OF THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU. IN NO EVENT WILL THE AUTHORS'S TOTAL CUMULATIVE DAMAGES EXCEED THE FEES YOU PAID TO THE AUTHOR UNDER THIS AGREEMENT IN THE MOST RECENT TWELVE-MONTH PERIOD. Definitions Definition of Website A "Website" is defined as a single domain including sub-domains that operate as a single entity. What constitutes a single entity shall be at the sole discretion of the Author. Definition of Source Code The "Source Code" is defined as the contents of all HTML, CSS, JavaScript, and PHP files provided with the Software and includes all related image files and database schemas. FURTHER INFORMATION For further Information about Appnitro Software's licensing policies or products, contact Appnitro Software at: E-mail: customer.service@appnitro.com Web: http://www.appnitro.com \ No newline at end of file diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..dfacaea --- /dev/null +++ b/logout.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/machform.php b/machform.php new file mode 100644 index 0000000..9850115 --- /dev/null +++ b/machform.php @@ -0,0 +1,242 @@ +top.location = '{$_SERVER['REQUEST_URI']}?done=1'"; + }else{ + header("Location: {$_SERVER['REQUEST_URI']}?done=1"); + } + exit; + }else{ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$_SERVER['REQUEST_URI']}&done=1"); + } + exit; + } + }else{ + + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$submit_result['form_redirect']}"); + } + exit; + } + }else{ + $old_values = $submit_result['old_values']; + $custom_error = $submit_result['custom_error']; + $error_elements = $submit_result['error_elements']; + + $markup = display_integrated_form($input_array['form_id'],$old_values,$error_elements,$custom_error,0,$machform_path); + } + }else{ //if password form submitted + if($submit_result['status'] === true){ //on success, display the form + $markup = display_integrated_form($input_array['form_id'],null,null,'',0,$machform_path); + }else{ + $custom_error = $submit_result['custom_error']; //error, display the pasword form again + $markup = display_integrated_form($input_array['form_id'],null,null,$custom_error,0,$machform_path); + } + } + }elseif(!empty($_POST['submit_continue'])){ //if form with continue (review) button submitted + unset($_POST['submit_continue']); + + $input_array = ap_sanitize_input($_POST); + + $input_array['machform_data_path'] = $machform_data_path; + $submit_result = process_form($input_array); + + + if($submit_result['status'] === true){ + + if(empty($submit_result['review_id'])){ + if(empty($submit_result['form_redirect'])){ + + if(strpos($_SERVER['REQUEST_URI'],'?') === false){ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$_SERVER['REQUEST_URI']}?done=1"); + } + exit; + }else{ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$_SERVER['REQUEST_URI']}&done=1"); + } + exit; + } + + }else{ + + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$submit_result['form_redirect']}"); + } + exit; + } + }else{ //redirect to review page + + $_SESSION['review_id'] = $submit_result['review_id']; + + if(strpos($_SERVER['REQUEST_URI'],'?') === false){ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$_SERVER['REQUEST_URI']}?show_review=1"); + } + }else{ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$_SERVER['REQUEST_URI']}&show_review=1"); + } + } + + exit; + } + + }else{ + $old_values = $submit_result['old_values']; + $custom_error = $submit_result['custom_error']; + $error_elements = $submit_result['error_elements']; + + $markup = display_integrated_form($input_array['form_id'],$old_values,$error_elements,$custom_error,0,$machform_path); + } + + }elseif(!empty($_POST['review_submit'])){ //if review page submitted + //commit data from review table to actual table + $record_id = $_SESSION['review_id']; + $param['machform_data_path'] = $machform_data_path; + $param['machform_base_path'] = $machform_path; + + $commit_result = commit_form_review($form_id,$record_id,$param); + + unset($_SESSION['review_id']); + + if(empty($commit_result['form_redirect'])){ + $url = str_replace(array("&show_review=1","?show_review=1"),"",$_SERVER['REQUEST_URI']); + if(strpos($url,'?') === false){ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$url}?done=1"); + } + }else{ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$url}&done=1"); + } + } + exit; + }else{ + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$commit_result['form_redirect']}"); + } + exit; + } + }elseif (!empty($_GET['show_review'])){ //show review page + if(empty($_SESSION['review_id'])){ + die("Your session has been expired. Please start again."); + }else{ + $record_id = $_SESSION['review_id']; + } + $markup = display_integrated_form_review($form_id,$record_id,$machform_path); + }elseif (!empty($_POST['review_back'])){ //go back to form + $url = str_replace(array("&show_review=1","?show_review=1"),"",$_SERVER['REQUEST_URI']); + + if($use_javascript_redirect){ + echo ""; + }else{ + header("Location: {$url}"); + } + + exit; + }else{ + + if(empty($form_id)){ + die('ID required.'); + } + + //check for delete file option + //this is available for form with review enabled + if(!empty($_GET['delete_file']) && !empty($_SESSION['review_id'])){ + $element_id = (int) trim($_GET['delete_file']); + $param['machform_data_path'] = $machform_data_path; + delete_review_file_entry($form_id,$_SESSION['review_id'],$element_id,$param); + } + + if(!empty($_GET['done'])){ + $markup = display_integrated_success($form_id,$machform_path); + }else{ + $markup = display_integrated_form($form_id,null,null,'',0,$machform_path); + } + } + + echo $markup; + + } + +?> \ No newline at end of file diff --git a/manage_entries.php b/manage_entries.php new file mode 100644 index 0000000..6564634 --- /dev/null +++ b/manage_entries.php @@ -0,0 +1,628 @@ + $lastpage){ + $pageno = $lastpage; + } + + //construct the LIMIT clause for the sql SELECT statement + if(!empty($numrows)){ + $limit = 'LIMIT ' .($pageno - 1) * $rows_per_page .',' .$rows_per_page; + } + /*****End Pagination code *******/ + + + //get form name + $query = "select form_name from `ap_forms` where form_id='$form_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + $form_name = $row['form_name']; + + + $max_data_length = 80; //maximum length of column header and content + + //get form element options + $query = "select element_id,option_id,`option` from ap_element_options where form_id='$form_id' and live=1 order by element_id,option_id asc"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $element_id = $row['element_id']; + $option_id = $row['option_id']; + + //limit the data length + if(strlen($row['option']) > $max_data_length){ + $element_option_lookup[$element_id][$option_id] = htmlspecialchars(substr($row['option'],0,$max_data_length).'...',ENT_QUOTES); + }else{ + $element_option_lookup[$element_id][$option_id] = htmlspecialchars($row['option'],ENT_QUOTES); + } + } + + /******************************************************************************************/ + //prepare column header names lookup + $query = "select element_id,element_title,element_type,element_constraint from `ap_form_elements` where form_id='$form_id' order by element_position asc"; + $result = do_query($query); + + while($row = do_fetch_result($result)){ + $element_type = $row['element_type']; + $element_constraint = $row['element_constraint']; + + //limit the title length + if(strlen($row['element_title']) > $max_data_length){ + $row['element_title'] = substr($row['element_title'],0,$max_data_length).'...'; + } + + $row['element_title'] = htmlspecialchars($row['element_title']); + + if('address' == $element_type){ //address has 6 fields + $column_name_lookup['element_'.$row['element_id'].'_1'] = $row['element_title'].' - Street Address'; + $column_name_lookup['element_'.$row['element_id'].'_2'] = 'Address Line 2'; + $column_name_lookup['element_'.$row['element_id'].'_3'] = 'City'; + $column_name_lookup['element_'.$row['element_id'].'_4'] = 'State/Province/Region'; + $column_name_lookup['element_'.$row['element_id'].'_5'] = 'Zip/Postal Code'; + $column_name_lookup['element_'.$row['element_id'].'_6'] = 'Country'; + + $column_type_lookup['element_'.$row['element_id'].'_1'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_2'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_3'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_4'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_5'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_6'] = $row['element_type']; + + }elseif ('simple_name' == $element_type){ //simple name has 2 fields + $column_name_lookup['element_'.$row['element_id'].'_1'] = $row['element_title'].' - First'; + $column_name_lookup['element_'.$row['element_id'].'_2'] = $row['element_title'].' - Last'; + + $column_type_lookup['element_'.$row['element_id'].'_1'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_2'] = $row['element_type']; + + }elseif ('name' == $element_type){ //name has 4 fields + $column_name_lookup['element_'.$row['element_id'].'_1'] = $row['element_title'].' - Title'; + $column_name_lookup['element_'.$row['element_id'].'_2'] = $row['element_title'].' - First'; + $column_name_lookup['element_'.$row['element_id'].'_3'] = $row['element_title'].' - Last'; + $column_name_lookup['element_'.$row['element_id'].'_4'] = $row['element_title'].' - Suffix'; + + $column_type_lookup['element_'.$row['element_id'].'_1'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_2'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_3'] = $row['element_type']; + $column_type_lookup['element_'.$row['element_id'].'_4'] = $row['element_type']; + + }elseif('money' == $element_type){//money format + $column_name_lookup['element_'.$row['element_id']] = $row['element_title']; + if(!empty($element_constraint)){ + $column_type_lookup['element_'.$row['element_id']] = $element_constraint; //euro, pound, yen + }else{ + $column_type_lookup['element_'.$row['element_id']] = 'dollar'; //default is dollar + } + }elseif('checkbox' == $element_type){ //checkboxes, get childs elements + + $this_checkbox_options = $element_option_lookup[$row['element_id']]; + foreach ($this_checkbox_options as $option_id=>$option){ + $column_name_lookup['element_'.$row['element_id'].'_'.$option_id] = $option; + $column_type_lookup['element_'.$row['element_id'].'_'.$option_id] = $row['element_type']; + } + }elseif ('time' == $element_type){ + if($element_constraint == 'show_seconds'){ + $column_type_lookup['element_'.$row['element_id']] = $row['element_type']; + }else{ + $column_type_lookup['element_'.$row['element_id']] = 'time_noseconds'; + } + + $column_name_lookup['element_'.$row['element_id']] = $row['element_title']; + }else{ //for other elements with only 1 field + $column_name_lookup['element_'.$row['element_id']] = $row['element_title']; + $column_type_lookup['element_'.$row['element_id']] = $row['element_type']; + } + } + /******************************************************************************************/ + + + //set column properties for basic fields + $column_name_lookup['id'] = ''; + $column_name_lookup['row_num'] = '#'; + $column_name_lookup['date_created'] = 'Date Created'; + $column_name_lookup['date_updated'] = 'Date Updated'; + $column_name_lookup['ip_address'] = 'IP Address'; + + $column_type_lookup['id'] = 'number'; + $column_type_lookup['row_num'] = 'number'; + $column_type_lookup['date_created'] = 'text'; + $column_type_lookup['date_updated'] = 'text'; + $column_type_lookup['ip_address'] = 'text'; + + /******************************************************************************************/ + //get columns preference + $query = "select element_name from ap_column_preferences where form_id='{$form_id}' order by position asc"; + $result = do_query($query); + while($row = do_fetch_result($result)){ + $column_prefs[] = $row['element_name']; + } + + //if empty display 6 first columns + if(empty($column_prefs)){ + $query = "select * from `ap_form_{$form_id}` limit 1"; + $result = do_query($query); + + $i = 0; + $j = 0; + $fields_num = mysql_num_fields($result); + while(($i < $fields_num) && ($j <= 5)){ + $meta = mysql_fetch_field($result, $i); + + if(!in_array($i,array(0,2,3))){ //don't display id (0), date_updated (2) and ip_address (3) as default + $column_prefs[$j] = $meta->name; + $j++; + } + + $i++; + } + } + + $field_list = implode(',',$column_prefs); + $query = "select id,id as row_num,{$field_list} from `ap_form_{$form_id}` order by id desc $limit"; + $result = do_query($query); + + //get actual field name from selected table + $i = 0; + $fields_num = mysql_num_fields($result); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + $columns[$i] = $meta->name; + $i++; + } + + $i=0; + $c=0; + $column_label = array(); + $first_row_number = ($pageno -1) * $rows_per_page + 1; + $last_row_number = $first_row_number; + + + while($row = do_fetch_result($result)){ + + for($j=0;$j<$fields_num;$j++){ + + + $column_name = $columns[$j]; + + + $form_data[$i][$j] = ''; + + //limit the data length, unless for file element + if($column_type_lookup[$column_name] != 'file'){ + if(strlen($row[$column_name]) > $max_data_length){ + $row[$column_name] = substr($row[$column_name],0,$max_data_length).'...'; + } + } + + if($column_type_lookup[$column_name] == 'time'){ + if(!empty($row[$column_name])){ + $form_data[$i][$j] = date("h:i:s A",strtotime($row[$column_name])); + }else { + $form_data[$i][$j] = ''; + } + }elseif($column_type_lookup[$column_name] == 'time_noseconds'){ + if(!empty($row[$column_name])){ + $form_data[$i][$j] = date("h:i A",strtotime($row[$column_name])); + }else { + $form_data[$i][$j] = ''; + } + }elseif(in_array($column_type_lookup[$column_name],array('dollar','euro','pound','yen'))){ //set column formatting for money fields + $column_type = $column_type_lookup[$column_name]; + + switch ($column_type){ + case 'dollar' : $currency = '$';break; + case 'pound' : $currency = '£';break; + case 'euro' : $currency = '€';break; + case 'yen' : $currency = '¥';break; + } + + if(!empty($row[$column_name])){ + $form_data[$i][$j] = '
    '.$currency.$row[$column_name].'
    '; + }else{ + $form_data[$i][$j] = ''; + } + }elseif($column_type_lookup[$column_name] == 'date'){ //date with format MM/DD/YYYY + if(!empty($row[$column_name]) && ($row[$column_name] != '0000-00-00')){ + $exploded_value = array(); + $exploded_value = explode("-",$row[$column_name]); + $form_data[$i][$j] = "{$exploded_value[0]}/{$exploded_value[1]}/{$exploded_value[2]}"; + } + }elseif($column_type_lookup[$column_name] == 'europe_date'){ //date with format DD/MM/YYYY + if(!empty($row[$column_name]) && ($row[$column_name] != '0000-00-00')){ + $exploded_value = array(); + $exploded_value = explode("-",$row[$column_name]); + $form_data[$i][$j] = "{$exploded_value[0]}/{$exploded_value[1]}/{$exploded_value[2]}"; + } + }elseif($column_type_lookup[$column_name] == 'number'){ + $form_data[$i][$j] = $row[$column_name]; + }elseif (in_array($column_type_lookup[$column_name],array('radio','select'))){ //multiple choice or dropdown + $exploded = array(); + $exploded = explode('_',$column_name); + $this_element_id = $exploded[1]; + $this_option_id = $row[$column_name]; + + $form_data[$i][$j] = $element_option_lookup[$this_element_id][$this_option_id]; + }elseif($column_type_lookup[$column_name] == 'checkbox'){ + + if(!empty($row[$column_name])){ + $form_data[$i][$j] = '
    '; + }else{ + $form_data[$i][$j] = ''; + } + + }elseif(in_array($column_type_lookup[$column_name],array('phone','simple_phone'))){ + $form_data[$i][$j] = $row[$column_name]; + }elseif($column_type_lookup[$column_name] == 'file'){ + if(!empty($row[$column_name])){ + //encode the long query string for more readibility + $q_string = base64_encode("form_id={$form_id}&id={$row['id']}&el={$column_name}"); + $form_data[$i][$j] = "  Download file"; + } + }else{ + $form_data[$i][$j] = htmlspecialchars(str_replace("\r","",str_replace("\n"," ",$row[$column_name])),ENT_QUOTES); + + if($column_name == 'date_created' || $column_name == 'date_updated'){ + $form_data[$i][$j] = short_relative_date($form_data[$i][$j]); + } + } + + if(count($column_label) < $fields_num){ + $column_label[$c]['name'] = $column_name; + $column_label[$c]['label'] = str_replace("\r","",str_replace("\n"," ",$column_name_lookup[$column_name])); + $c++; + } + } + + $last_row_number++; + $i++; + } + + $last_row_number--; + /******************************************************************************************/ + + + $header_data =<< + + + +EOT; + + +?> + + + + +
    + +
    + +
    Export all entries: Excel File CSV File
    + +

    Entries

    +

    Edit and manage your form entries

    +
    + + +
    +
    +
    +
      + or + +
    + +
    + + + + + +'.$table_header['label'].''; + }elseif ($table_header['name'] == 'row_num'){ + echo ''; + }else{ + echo ''; + } + + + } +?> + + + + +"; + + foreach ($row_data as $key=>$column_data){ + if($key == 0){ + echo ''; + }elseif ($key == 1){ + echo ''; + }else{ + echo ''; + } + } + + echo ''; + } +?> + +
    '.$table_header['label'].'
    '.$table_header['label'].'
    '.$column_data.'
    '.$column_data.'
    + + +
    +
    + +

    This form doesn't have any entry yet.

    "; + } +?> + + + +
    + 19){ + echo " <<First "; + } + $prevpage = $pageno-1; + + + } + + //middle navigation + if($pageno == 1){ + $i=1; + while(($i<=19) && ($i<=$lastpage)){ + if($i != 1){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $i "; + $i++; + } + if($lastpage > $i){ + echo ' ... '; + } + }elseif ($pageno == $lastpage){ + + if(($lastpage - 19) > 1){ + echo ' ... '; + $i=1; + $j=$lastpage - 18; + while($i<=19){ + if($j != $lastpage){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $j "; + $i++; + $j++; + } + }else{ + $i=1; + while(($i<=19) && ($i<=$lastpage)){ + if($i != $lastpage){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $i "; + $i++; + } + } + + }else{ + $next_pages = false; + $prev_pages = false; + + if(($lastpage - ($pageno + 9)) >= 1){ + $next_pages = true; + } + if(($pageno - 9) > 1){ + $prev_pages = true; + } + + if($prev_pages){ //if there are previous pages + echo ' ... '; + if($next_pages){ //if there are next pages + $i=1; + $j=$pageno - 9; + while($i<=19){ + if($j != $pageno){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $j "; + $i++; + $j++; + } + echo ' ... '; + }else{ + + $i=1; + $j=$pageno - 9; + while(($i<=19) && ($j <= $lastpage)){ + if($j != $pageno){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $j "; + $i++; + $j++; + } + } + }else{ //if there aren't previous pages + + $i=1; + while(($i<=19) && ($i <= $lastpage)){ + if($i != $pageno){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $i "; + $i++; + + } + if($next_pages){ + echo ' ... '; + } + + } + + + } + + if ($pageno != $lastpage) + { + $nextpage = $pageno+1; + if($lastpage > 19){ + echo " Last>> "; + } + } + + + //next we inform the user of his current position in the sequence of available pages + ?> + + +
    + + + + +
    + \ No newline at end of file diff --git a/manage_form.php b/manage_form.php new file mode 100644 index 0000000..4c5136d --- /dev/null +++ b/manage_form.php @@ -0,0 +1,682 @@ +$value){ + $index_key = array_search($form_id,$value,true); + if($index_key !== false){ + $active_tab_auto = $index_key; + $pageno_auto = $key + 1; + } + } + } + + + //check for form delete parameter + if(!empty($_GET['delete'])){ + $deleted_form_id = (int) trim($_GET['delete']); + delete_form($deleted_form_id); + } + + //check for form duplicate parameter + if(!empty($_GET['duplicate'])){ + $target_form_id = (int) trim($_GET['duplicate']); + $result_form_id = duplicate_form($target_form_id); + + if(!empty($result_form_id)){ + $_SESSION['AP_SUCCESS']['title'] = 'Success'; + $_SESSION['AP_SUCCESS']['desc'] = 'Form duplicated.'; + + header("Location: manage_form.php?id={$result_form_id}"); + exit; + } + } + + + /****Pagination *************/ + //get page number for pagination + if(!empty($pageno_auto)){ + $pageno = $pageno_auto; + }elseif(!empty($_GET['pageno'])) { + $pageno = $_GET['pageno']; + }else{ + $pageno = 1; + } + + //identify how many database rows are available + $query = "select count(*) total_row from `ap_forms`"; + $result = do_query($query); + $row = do_fetch_result($result); + + $numrows = $row['total_row']; + + $lastpage = ceil($numrows/$rows_per_page); + + + //ensure that $pageno is within range + //this code checks that the value of $pageno is an integer between 1 and $lastpage + $pageno = (int)$pageno; + + if ($pageno < 1) { + $pageno = 1; + } + elseif ($pageno > $lastpage){ + $pageno = $lastpage; + } + + //construct the LIMIT clause for the sql SELECT statement + if(!empty($numrows)){ + $limit = 'LIMIT ' .($pageno - 1) * $rows_per_page .',' .$rows_per_page; + } + /*****End Pagination code *******/ + + + + //get form list + $query = "select form_id,form_name,form_active,form_email from `ap_forms` order by form_id asc $limit"; + $result = do_query($query); + $i=0; + $form_id_array = array(); + while($row = do_fetch_result($result)){ + $form_list[$i]['form_id'] = $row['form_id']; + $form_list[$i]['form_name'] = $row['form_name']; + $form_list[$i]['form_active'] = $row['form_active']; + if(!empty($row['form_email'])){ + $form_list[$i]['form_email'] = $row['form_email']; + }else{ + $form_list[$i]['form_email'] = 'nobody'; + } + $form_id_array[] = $row['form_id']; + $i++; + } + + //get total entries for each form + foreach ($form_id_array as $form_id){ + //get all time entries + $query = "select count(*) total_entry from `ap_form_{$form_id}`"; + $result = do_query($query); + $row = do_fetch_result($result); + $entries[$form_id]['total'] = $row['total_entry']; + + //get todays entries + $query = "select count(*) today_entry from `ap_form_{$form_id}` where date_created >= date_format(curdate(),'%Y-%m-%d 00:00:00') "; + $result = do_query($query); + $row = do_fetch_result($result); + $entries[$form_id]['today'] = $row['today_entry']; + + //get latest entry timing + $query = "select date_created from `ap_form_{$form_id}` order by id desc limit 1"; + $result = do_query($query); + $row = do_fetch_result($result); + $entries[$form_id]['latest_entry'] = relative_date($row['date_created']); + } + + $header_data =<< + + + + + + +EOT; + + //delete a form, definition, entries and uploaded files + function delete_form($form_id){ + //remove from ap_forms + $query = "delete from `ap_forms` where form_id='$form_id'"; + do_query($query); + + //remove from ap_form_elements + $query = "delete from `ap_form_elements` where form_id='$form_id'"; + do_query($query); + + //remove from ap_element_options + $query = "delete from `ap_element_options` where form_id='$form_id'"; + do_query($query); + + //remove from ap_column_preferences + $query = "delete from `ap_column_preferences` where form_id='$form_id'"; + do_query($query); + + //remove review table + $query = "drop table if exists `ap_form_{$form_id}_review`"; + do_query($query); + + //remove the actual table + $query = "drop table if exists `ap_form_{$form_id}`"; + do_query($query); + + //remove form folder + @full_rmdir(UPLOAD_DIR."/form_{$form_id}"); + if(DATA_DIR != UPLOAD_DIR){ + @full_rmdir(DATA_DIR."/form_{$form_id}"); + } + return true; + } + + //duplicate a form + function duplicate_form($form_id){ + + //set the new name + $query = "select form_name,form_review from `ap_forms` where form_id='$form_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + $form_review = $row['form_review']; + $form_name = trim($row['form_name']); + $form_name .= " Copy"; + + //get new form_id + $query = "select max(form_id)+1 new_form_id from `ap_forms`"; + $result = do_query($query); + $row = do_fetch_result($result); + $new_form_id = trim($row['new_form_id']); + + //insert into ap_forms table + $query = "select * from `ap_forms` where form_id='{$form_id}'"; + $result = do_query($query); + + $i = 0; + $columns = array(); + $fields_num = mysql_num_fields($result); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + + if(($meta->name != 'form_id') && ($meta->name != 'form_name')){ + $columns[] = $meta->name; + } + + $i++; + } + + + //build the query string + $columns_joined = implode(",",$columns); + $form_name = mysql_real_escape_string($form_name); + + //insert to ap_forms + $query = "insert into + `ap_forms`(form_id,form_name,{$columns_joined}) + select + {$new_form_id},'{$form_name}',{$columns_joined} + from + `ap_forms` + where + form_id='$form_id'"; + do_query($query); + + //create the new table + do_query("create table `ap_form_{$new_form_id}` like `ap_form_{$form_id}`"); + + + //copy ap_form_elements table + $query = "select * from `ap_form_elements` limit 1"; + $result = do_query($query); + + $i = 0; + $columns = array(); + $fields_num = mysql_num_fields($result); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + + if($meta->name != 'form_id'){ + $columns[] = $meta->name; + } + + $i++; + } + $columns_joined = implode("`,`",$columns); + $query = "insert into + `ap_form_elements`(form_id,`{$columns_joined}`) + select + {$new_form_id},`{$columns_joined}` + from + `ap_form_elements` + where + form_id='$form_id'"; + do_query($query); + + //copy ap_element_options table + $query = "select * from `ap_element_options` limit 1"; + $result = do_query($query); + + $i = 0; + $columns = array(); + $fields_num = mysql_num_fields($result); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + + if(($meta->name != 'form_id') && ($meta->name != 'aeo_id')){ + $columns[] = $meta->name; + } + + $i++; + } + $columns_joined = implode("`,`",$columns); + $query = "insert into + `ap_element_options`(form_id,`{$columns_joined}`) + select + {$new_form_id},`{$columns_joined}` + from + `ap_element_options` + where + form_id='$form_id'"; + do_query($query); + + + //copy ap_column_preferences table + $query = "select * from `ap_column_preferences` limit 1"; + $result = do_query($query); + + $i = 0; + $columns = array(); + $fields_num = mysql_num_fields($result); + while($i < $fields_num){ + $meta = mysql_fetch_field($result, $i); + + if(($meta->name != 'form_id') && ($meta->name != 'acp_id')){ + $columns[] = $meta->name; + } + + $i++; + } + $columns_joined = implode("`,`",$columns); + $query = "insert into + `ap_column_preferences`(form_id,`{$columns_joined}`) + select + {$new_form_id},`{$columns_joined}` + from + `ap_column_preferences` + where + form_id='$form_id'"; + do_query($query); + + //copy ap_form_xx_review table if exists + if(!empty($form_review)){ + do_query("CREATE TABLE `ap_form_{$new_form_id}_review` like `ap_form_{$form_id}_review`"); + } + + //create form folder + $old_mask = umask(0); + mkdir(DATA_DIR."/form_{$new_form_id}",0777); + mkdir(DATA_DIR."/form_{$new_form_id}/css",0777); + if(DATA_DIR != UPLOAD_DIR){ + mkdir(UPLOAD_DIR."/form_{$new_form_id}",0777); + } + mkdir(UPLOAD_DIR."/form_{$new_form_id}/files",0777); + umask($old_mask); + + //copy css file + copy(DATA_DIR."/form_{$form_id}/css/view.css",DATA_DIR."/form_{$new_form_id}/css/view.css"); + + return $new_form_id; + } + +?> + + +
    + +
    + +
    + +
    +

    Form Manager

    +

    Create, edit and manage your forms

    +
    + + + + +'; + + foreach ($form_list as $data){ + + if(!empty($data['form_active'])){ + $form_status = 'Accepting Entries'; + $image_status = 'checkbox.gif'; + $activation_text = 'Disable this form'; + $activation_link = 'disable_form'; + }else{ + $form_status = 'Inactive'; + $image_status = 'disabled.gif'; + $activation_text = 'Enable this form'; + $activation_link = 'enable_form'; + }; + + +?> +
    +
    +

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ">">">">">  ">
    ">Entries">Edit Form">Edit CSS">Emails">Embed Code View Form ">DuplicateDelete
    +
    + Today's Entries:
    + Total Entries:

    + Latest Entry:
    + +
    + Notifications will be sent to: +
    + + + Form Status: +       +    + + +
    +
    +
    +'; + echo ''; + + }else{ + echo "

    You have no form yet. Go create one!

    "; + } +?> + + + + + + +
    +
    + 19){ + echo " <<First "; + } + $prevpage = $pageno-1; + + + } + + //middle navigation + if($pageno == 1){ + $i=1; + while(($i<=19) && ($i<=$lastpage)){ + if($i != 1){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $i "; + $i++; + } + if($lastpage > $i){ + echo ' ... '; + } + }elseif ($pageno == $lastpage){ + + if(($lastpage - 19) > 1){ + echo ' ... '; + $i=1; + $j=$lastpage - 18; + while($i<=19){ + if($j != $lastpage){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $j "; + $i++; + $j++; + } + }else{ + $i=1; + while(($i<=19) && ($i<=$lastpage)){ + if($i != $lastpage){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $i "; + $i++; + } + } + + }else{ + $next_pages = false; + $prev_pages = false; + + if(($lastpage - ($pageno + 9)) >= 1){ + $next_pages = true; + } + if(($pageno - 9) > 1){ + $prev_pages = true; + } + + if($prev_pages){ //if there are previous pages + echo ' ... '; + if($next_pages){ //if there are next pages + $i=1; + $j=$pageno - 9; + while($i<=19){ + if($j != $pageno){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $j "; + $i++; + $j++; + } + echo ' ... '; + }else{ + + $i=1; + $j=$pageno - 9; + while(($i<=19) && ($j <= $lastpage)){ + if($j != $pageno){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $j "; + $i++; + $j++; + } + } + }else{ //if there aren't previous pages + + $i=1; + while(($i<=19) && ($i <= $lastpage)){ + if($i != $pageno){ + $active_style = ''; + }else{ + $active_style = 'class="active_page"'; + } + echo " $i "; + $i++; + + } + if($next_pages){ + echo ' ... '; + } + + } + + + } + + if ($pageno != $lastpage) + { + $nextpage = $pageno+1; + if($lastpage > 19){ + echo " Last>> "; + } + } + + + //next we inform the user of his current position in the sequence of available pages + ?> + + +
    + + + + +
    + \ No newline at end of file diff --git a/save.php b/save.php new file mode 100644 index 0000000..33fbbb3 --- /dev/null +++ b/save.php @@ -0,0 +1,474 @@ +decode($input_array['form']); + $elements_object = $json->decode($input_array['elements']); + + $form_id = $form_object->id; + + /******** Start Form Section ********************************************************************/ + //check for form_id, if exist this is an update operation + //if not this is an insert operation + $query = "select count(form_id) form_exist from ap_forms where form_id='$form_id'"; + $result = do_query($query); + $row = do_fetch_result($result); + + if(empty($row['form_exist'])){ + $is_new_form = true; + }else{ + $is_new_form = false; + } + + $form_input['form_id'] = $form_id; + $form_input['form_name'] = $form_object->name; + $form_input['form_description'] = $form_object->description; + $form_input['form_redirect'] = $form_object->redirect; + $form_input['form_success_message'] = $form_object->success_message; + $form_input['form_password'] = $form_object->password; + $form_input['form_unique_ip'] = $form_object->unique_ip; + $form_input['form_captcha'] = $form_object->captcha; + $form_input['form_review'] = $form_object->review; + $form_input['form_frame_height'] = $form_object->frame_height; + + if($is_new_form){ //this is a new form, insert new form data + $result = ap_forms_insert($form_input); + check_result($result); + + $form_id = mysql_insert_id(); + + //create new table for this form + $query = "CREATE TABLE `ap_form_{$form_id}` ( + `id` int(11) NOT NULL auto_increment, + `date_created` datetime NOT NULL default '0000-00-00 00:00:00', + `date_updated` datetime default NULL, + `ip_address` varchar(15) default NULL, + PRIMARY KEY (`id`) + ) DEFAULT CHARACTER SET utf8;"; + do_query($query); + + //create data folder for this form + if(is_writable(DATA_DIR)){ + + $old_mask = umask(0); + mkdir(DATA_DIR."/form_{$form_id}",0777); + mkdir(DATA_DIR."/form_{$form_id}/css",0777); + if(DATA_DIR != UPLOAD_DIR){ + mkdir(UPLOAD_DIR."/form_{$form_id}",0777); + } + mkdir(UPLOAD_DIR."/form_{$form_id}/files",0777); + + umask($old_mask); + + //copy default view.css to css folder + if(copy("./view.css",DATA_DIR."/form_{$form_id}/css/view.css")){ + //on success update 'form_has_css' field on ap_forms table + $form_update_input['form_has_css'] = 1; + ap_forms_update($form_id,$form_update_input); + } + } + }else{ //this is just an update, update form info + $result = ap_forms_update($form_id,$form_input); + check_result($result); + } + /******** End Form Section ********************************************************************/ + + + /******** Start Elements Section ********************************************************************/ + $elements_array = $elements_object->elements; + + //separate optionable elements (checkbox/radio button/dropdown) from other elements + $optionable_elements = array(); + + foreach ($elements_array as $key=>$value){ + if(($value->type == 'radio') || ($value->type == 'checkbox') || ($value->type == 'select')){ + $optionable_elements[] = $value; + }else{ + $value->options = null; //remove options for elements other than checkbox/radio/dropdown + $non_optionable_elements[] = $value; + } + } + + //1. Process non optionable elements + if(!empty($non_optionable_elements)){ + foreach ($non_optionable_elements as $element){ + if(empty($element->is_db_live)){ + $new_non_optionable_elements[] = $element; + }else{ + $old_non_optionable_elements[] = $element; + } + } + } + //1.1 Process new non-optionable element. Insert to table + + //get new element_id + $query = "select ifnull(max(element_id),0)+1 next_element_id from ap_form_elements where form_id='{$form_id}'"; + $result = do_query($query); + $row = do_fetch_result($result); + + $next_element_id = $row['next_element_id']; + + $element_input = array(); + $element_input['form_id'] = $form_id; + + if(!empty($new_non_optionable_elements)){ + foreach ($new_non_optionable_elements as $element){ + $element_input['element_id'] = $next_element_id; + $element_input['element_title'] = $element->title; + $element_input['element_guidelines'] = $element->guidelines; + $element_input['element_size'] = $element->size; + $element_input['element_is_required'] = $element->is_required; + $element_input['element_is_unique'] = $element->is_unique; + $element_input['element_is_private'] = $element->is_private; + $element_input['element_type'] = $element->type; + $element_input['element_position'] = $element->position; + $element_input['element_default_value'] = $element->default_value; + $element_input['element_constraint'] = $element->constraint; + + if(empty($element_child_lookup[$element->type])){ + $element_input['element_total_child'] = 0; + }else{ + $element_input['element_total_child'] = $element_child_lookup[$element->type]; + } + + ap_form_elements_insert($element_input); //insert field information + table_add_field($form_id,$next_element_id,$element->type); //actually create the field + + $next_element_id++; + } + } + + //1.2 Process old non-optionable element. Update table + + + $element_input = array(); + $updatable_element_type = array('phone','simple_phone','date','europe_date'); + + if(!empty($old_non_optionable_elements)){ + foreach ($old_non_optionable_elements as $element){ + $element_input['element_title'] = $element->title; + $element_input['element_guidelines'] = $element->guidelines; + $element_input['element_size'] = $element->size; + $element_input['element_is_required'] = $element->is_required; + $element_input['element_is_unique'] = $element->is_unique; + $element_input['element_is_private'] = $element->is_private; + $element_input['element_position'] = $element->position; + $element_input['element_default_value'] = $element->default_value; + $element_input['element_constraint'] = $element->constraint; + + if(empty($element_child_lookup[$element->type])){ + $element_input['element_total_child'] = 0; + }else{ + $element_input['element_total_child'] = $element_child_lookup[$element->type]; + } + + //special for phone,simple_phone,date,europe_date .. type can be changed + if(in_array($element->type,$updatable_element_type)){ + $element_input['element_type'] = $element->type; + }else{ + unset($element_input['element_type']); + } + + ap_form_elements_update($form_id,$element->id,$element_input); + + } + } + + + + //2. Process optionable elements (checkbox/radio button/dropdown) + foreach ($optionable_elements as $element){ + if(empty($element->is_db_live)){ + $new_optionable_elements[] = $element; + }else{ + $old_optionable_elements[] = $element; + } + } + + //2.1 Process new optionable element. Insert to table + $element_input = array(); + $element_input['form_id'] = $form_id; + + if(!empty($new_optionable_elements)){ + foreach ($new_optionable_elements as $element){ + $element_input['element_id'] = $next_element_id; + $element_input['element_title'] = $element->title; + $element_input['element_guidelines'] = $element->guidelines; + $element_input['element_size'] = $element->size; + $element_input['element_is_required'] = $element->is_required; + $element_input['element_is_unique'] = $element->is_unique; + $element_input['element_is_private'] = $element->is_private; + $element_input['element_type'] = $element->type; + $element_input['element_position'] = $element->position; + $element_input['element_default_value'] = $element->default_value; + $element_input['element_constraint'] = $element->constraint; + + if(empty($element_child_lookup[$element->type])){ + $element_input['element_total_child'] = 0; + }else{ + $element_input['element_total_child'] = $element_child_lookup[$element->type]; + } + ap_form_elements_insert($element_input); + + if(($element->type == 'radio') || ($element->type == 'select')){ //radio button and select only need one field total,,while checkboxes need one field per option + table_add_field($form_id,$next_element_id,$element->type); //actually create the field + } + + //insert options into ap_element_options table + //get new option_id + $query = "select ifnull(max(option_id),0)+1 next_option_id from ap_element_options where form_id='{$form_id}' and element_id='{$next_element_id}'"; + $result = do_query($query); + $row = do_fetch_result($result); + + $next_option_id = $row['next_option_id']; + + $option_input = array(); + $option_input['form_id'] = $form_id; + $option_input['element_id'] = $next_element_id; + $position = 1; + foreach ($element->options as $option){ + $option->option = trim($option->option); + if(empty($option->option) && ($option->option != '0')){ + continue; + } + $option_input['option_id'] = $next_option_id; + $option_input['option'] = $option->option; + $option_input['option_is_default'] = $option->is_default; + $option_input['position'] = $position; + ap_element_options_insert($option_input); + + if($element->type == 'checkbox'){ + table_add_field($form_id,$next_element_id,$element->type,$next_option_id); //actually create the field for checkbox + } + + $next_option_id++; + $position++; + } + + //update 'element_total_child' on ap_form_elements + $position -= 2; + do_query("update ap_form_elements set element_total_child='$position' where form_id='$form_id' and element_id='$next_element_id'"); + + $next_element_id++; + } + } + + + + //2.2 Process old optionable element. Update table + $element_input = array(); + + if(!empty($old_optionable_elements)){ + foreach ($old_optionable_elements as $element){ + //update ap_forms_element table + $element_input['element_title'] = $element->title; + $element_input['element_guidelines'] = $element->guidelines; + $element_input['element_size'] = $element->size; + $element_input['element_is_required'] = $element->is_required; + $element_input['element_is_unique'] = $element->is_unique; + $element_input['element_is_private'] = $element->is_private; + $element_input['element_position'] = $element->position; + $element_input['element_default_value'] = $element->default_value; + $element_input['element_constraint'] = $element->constraint; + + if(empty($element_child_lookup[$element->type])){ + $element_input['element_total_child'] = 0; + }else{ + $element_input['element_total_child'] = $element_child_lookup[$element->type]; + } + + ap_form_elements_update($form_id,$element->id,$element_input); + + //update ap_element_options table (checkbox/radio button/dropdown) + //'erase' all old data + $query = "update `ap_element_options` set `live`=0 where form_id='{$form_id}' and element_id='{$element->id}'"; + do_query($query); + + + //get new option_id for current element_id, just in case we need it to insert new option + $query = "select ifnull(max(option_id),0)+1 next_option_id from ap_element_options where form_id='{$form_id}' and element_id='{$element->id}'"; + $result = do_query($query); + $row = do_fetch_result($result); + + $next_option_id = $row['next_option_id']; + + $option_input = array(); + $option_input['form_id'] = $form_id; + $option_input['element_id'] = $element->id; + + //loop through elements + $position = 1; + foreach ($element->options as $option){ + $option->option = trim($option->option); + if(empty($option->option) && ($option->option != '0')){ + continue; + } + + $option_input['option'] = $option->option; + $option_input['option_is_default'] = $option->is_default; + $option_input['live'] = 1; + $option_input['position'] = $position; + + if(empty($option->id)){ //if id=0 insert new row + $option_input['option_id'] = $next_option_id; + + ap_element_options_insert($option_input); + + if($element->type == 'checkbox'){ + table_add_field($form_id,$element->id,$element->type,$next_option_id); //actually create the field for checkbox + } + + $next_option_id++; + }else{//if id !=0 update + unset($option_input['option_id']); + ap_element_options_update($form_id,$element->id,$option->id,$option_input); + } + $position++; + } + + //update 'element_total_child' on ap_form_elements + $position -= 2; + do_query("update ap_form_elements set element_total_child='$position' where form_id='$form_id' and element_id='{$element->id}'"); + } + } + + /******** End Elements Section **********************************************************************/ + + /******** Start processing review table **********************************************************/ + //delete review table if exists + do_query("DROP TABLE IF EXISTS `ap_form_{$form_id}_review`"); + + //if review is enabled, create the table + if(!empty($form_input['form_review'])){ + do_query("CREATE TABLE `ap_form_{$form_id}_review` like `ap_form_{$form_id}`"); + + do_query("ALTER TABLE `ap_form_{$form_id}_review` ADD COLUMN `session_id` varchar(100) NULL"); + } + + /******** End processing review table **********************************************************/ + + + $_SESSION['AP_SUCCESS']['title'] = 'Success'; + $_SESSION['AP_SUCCESS']['desc'] = 'Your form has been saved.'; + + echo '{ "status" : "ok", "message" : "'.$form_id.'" }'; + + /** Functions *************************/ + + function check_result($result){ + if($result !== true){ + if(!is_array($result)){ //if one line error message + $error = '{ "status" : "error","message" : "'.$result.'"}'; + echo $error; + } + } + } + + + + + //add fields to the specified form table + function table_add_field($form_id,$element_id,$type,$option_id=0){ + global $comment_desc; + + $comment = @$comment_desc[$type]; + + if(('text' == $type) || ('phone' == $type) || ('simple_phone' == $type) || ('url' == $type) || ('email' == $type) || ('file' == $type)){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}` text NULL COMMENT '{$comment}';"; + do_query($query); + }elseif ('textarea' == $type){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}` mediumtext NULL COMMENT '{$comment}';"; + do_query($query); + }elseif (('radio' == $type) || ('select' == $type)){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}` int(6) unsigned NOT NULL DEFAULT '0' COMMENT '{$comment}';"; + do_query($query); + }elseif ('time' == $type){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}` time NULL COMMENT '{$comment}';"; + do_query($query); + }elseif (('date' == $type) || ('europe_date' == $type)){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}` date NULL COMMENT '{$comment}';"; + do_query($query); + }elseif ('money' == $type){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}` decimal(62,2) NULL COMMENT '{$comment}';"; + do_query($query); + }elseif ('number' == $type){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}` double NULL COMMENT '{$comment}';"; + do_query($query); + }elseif ('simple_name' == $type){ + //add two field, first and last name + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}_1` varchar(255) NULL COMMENT '{$comment} - First', ADD COLUMN `element_{$element_id}_2` varchar(255) NULL COMMENT '{$comment} - Last';"; + do_query($query); + }elseif ('name' == $type){ + //add four field, title, first, last, suffix + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}_1` varchar(255) NULL COMMENT '{$comment} - Title', ADD COLUMN `element_{$element_id}_2` varchar(255) NULL COMMENT '{$comment} - First', ADD COLUMN `element_{$element_id}_3` varchar(255) NULL COMMENT '{$comment} - Last', ADD COLUMN `element_{$element_id}_4` varchar(255) NULL COMMENT '{$comment} - Suffix';"; + do_query($query); + }elseif ('address' == $type){ + //add six field + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}_1` varchar(255) NULL COMMENT '{$comment} - Street', ADD COLUMN `element_{$element_id}_2` varchar(255) NULL COMMENT '{$comment} - Line 2', ADD COLUMN `element_{$element_id}_3` varchar(255) NULL COMMENT '{$comment} - City', ADD COLUMN `element_{$element_id}_4` varchar(255) NULL COMMENT '{$comment} - State/Province/Region', ADD COLUMN `element_{$element_id}_5` varchar(255) NULL COMMENT '{$comment} - Zip/Postal Code', ADD COLUMN `element_{$element_id}_6` varchar(255) NULL COMMENT '{$comment} - Country';"; + do_query($query); + }elseif ('checkbox' == $type){ + $query = "ALTER TABLE `ap_form_{$form_id}` ADD COLUMN `element_{$element_id}_{$option_id}` int(6) unsigned NOT NULL DEFAULT '0' COMMENT '{$comment} - {$option_id}';"; + do_query($query); + } + + } +?> \ No newline at end of file diff --git a/template_variables.php b/template_variables.php new file mode 100644 index 0000000..ce62643 --- /dev/null +++ b/template_variables.php @@ -0,0 +1,149 @@ + MAX_TITLE_LENGTH){ + $row['element_title'] = substr($row['element_title'],0,MAX_TITLE_LENGTH); + } + + $row['element_title'] = htmlspecialchars($row['element_title']); + $column_list[$i]['field_name'] = $row['element_title']; + $column_list[$i]['template_variable'] = '{element_'.$row['element_id'].'}'; + $i++; + } + /******************************************************************************************/ + $column_list[$i]['field_name'] = ' '; + $column_list[$i]['template_variable'] = ' '; + $i++; + $column_list[$i]['field_name'] = 'Entry No.'; + $column_list[$i]['template_variable'] = '{entry_no}'; + $i++; + $column_list[$i]['field_name'] = 'Date Created'; + $column_list[$i]['template_variable'] = '{date_created}'; + $i++; + $column_list[$i]['field_name'] = 'IP Address'; + $column_list[$i]['template_variable'] = '{ip_address}'; + $i++; + $column_list[$i]['field_name'] = 'Form ID'; + $column_list[$i]['template_variable'] = '{form_id}'; + $i++; + $column_list[$i]['field_name'] = 'Form Name'; + $column_list[$i]['template_variable'] = '{form_name}'; + $i++; + $column_list[$i]['field_name'] = 'Complete Entry'; + $column_list[$i]['template_variable'] = '{entry_data}'; + + $header_data =<< + + + +EOT; + +?> + + + + +
    + +
    +

    Emails Template Variables

    +

    A list of available template variables for your email content

    +
    + + +
    +
    + + + + + + + + + + + + + +EOT; + echo $table_row; + $i++; + } +?> + + +
    FieldTemplate Variable
    {$data['field_name']}
    {$data['template_variable']}

    + +
    +
    + What is a Template Variable? +

    A Template Variable is a special identifier that is automatically replaced with data typed in by a user.


    + How are they used? +

    Copy the variable name on the left (including curly braces) to your email template.


    + Where can Template Variables be used? +

    Template Variables can be used in From Name, Subject and Content fields.

    +
    + +
    + \ No newline at end of file diff --git a/upgrade.php b/upgrade.php new file mode 100644 index 0000000..2d9c6b4 --- /dev/null +++ b/upgrade.php @@ -0,0 +1,416 @@ +Congratulations!
    You have completed the upgrade process. MachForm version 2 is now installed."; + }else{ + $install_message = "An error has occured during upgrade."; + } + + $state = 'install_report'; + }else{ + + //do a pre installation check + $state = 'show_preinstall_check'; + + //check for PHP version + if(version_compare(PHP_VERSION,"4.3.0",">=")){ + $is_php_version_passed = true; + }else{ + $is_php_version_passed = false; + $pre_install_has_error = true; + } + + //check for MySQL version + if(version_compare(mysql_get_server_info(),"4.1.0",">=")){ + $is_mysql_version_passed = true; + }else{ + $is_mysql_version_passed = false; + $pre_install_has_error = true; + } + + //check for MySQL user,password and database existance + if(empty($mysql_connect_error)){ + $is_mysql_connect_passed = true; + }else{ + $is_mysql_connect_passed = false; + $pre_install_has_error = true; + } + + if(empty($mysql_select_db_error)){ + $is_mysql_select_db_passed = true; + }else{ + $is_mysql_select_db_passed = false; + $pre_install_has_error = true; + } + + //check for data folder permission + if(is_writable(DATA_DIR)){ + $is_data_dir_writable = true; + }else { + $is_data_dir_writable = false; + $pre_install_has_error = true; + $data_dir_writable_error = "MachForm require read and write access to this folder. Please set the correct permission."; + } + + //check for current tables, make sure that version 2 is not installed already + $query = "select form_review from ap_forms limit 1"; + mysql_query($query); + $error_msg = mysql_error(); + if(empty($error_msg)){ + $is_version2_already_installed = true; + $pre_install_has_error = true; + $version2_already_installed_error = "Your installation already has the most recent version (Version 2)."; + }else{ + $is_version2_already_installed = false; + } + + if($pre_install_has_error){ + $pre_install_message = "Your system does not match the minimum requirements necessary. Please take the appropriate actions to correct the errors."; + }else{ + $pre_install_message = "Your system passed the minimum requirements necessary. You can now start the upgrade process."; + } + } + } + + } + + $hide_nav = true; +?> + + + +
    + + +
    +

    MachForm Installer Error

    +

    Please fix the following error before you can continue the installation process:

    +
    + +
    +
    +
      +
    • + +
      +

      + There doesn't seem to be a config.php file. We need this before we can get started. +

      +

      +

      In the base directory of your installation you'll find a file called config-empty.php. Open this file and fill in the required database information.



      +

      After the details are filled in you must rename the file config.php before continuing.


      +
      +
    • +
    • + +
    • +
    +
    +

    + + + +
    +

    MachForm 2.0 Pre-Upgrade Check

    +

    +
    + +
    +
    +
      +
    • + +
    • + +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + + + + + + +
    • +
    +
    +

    + + + +
    +

    No Previous Version of MachForm Found

    +

    Please follow the step below to be able to continue:

    +
    + +
    +
    +
      +
    • + +
      +

      + In order to upgrade to version 2.0, you need to have version 1.2 installed. +

      +
      +

      Make sure to double check your config.php file for any error or typo.


      +

      If this is the first time you use MachForm, then go to the installer page instead.


      +
      +
    • +
    +
    +

    + + + + +
    +

    MachForm Upgrade Report

    +

    +
    + +
    +
    +
      + +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + Important: Please delete this installer file (upgrade.php) now.

      After deleting this file, you can login to MachForm admin panel +
    • + +
    • + +
    • + + +
    • + +
    • + + + + +
    • + + +
    • + + +
    +
    +

    + + + +
    + \ No newline at end of file diff --git a/view.css b/view.css new file mode 100644 index 0000000..a04fa20 --- /dev/null +++ b/view.css @@ -0,0 +1,936 @@ +#main_body +{ + background:#fffff; + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + font-size:small; + margin:8px 0 16px; + text-align:center; +} + +#form_container +{ + background:#fff; + border:1px solid #ccc; + margin:0 auto; + text-align:left; + width:640px; +} + +#top +{ + display:block; + height:10px; + margin:10px auto 0; + width:650px; +} + +#footer +{ + width:640px; + clear:both; + color:#999999; + text-align:center; + width:640px; + padding-bottom: 15px; + font-size: 85%; +} + +#footer a{ + color:#999999; + text-decoration: none; + border-bottom: 1px dotted #999999; +} + +#bottom +{ + display:block; + height:10px; + margin:0 auto; + width:650px; +} + +form.appnitro +{ + margin:20px 20px 0; + padding:0 0 20px; +} + +/**** Logo Section *****/ +#main_body h1 +{ + background-color:#dedede; + margin:0; + min-height:0; + padding:0; + text-decoration:none; + text-indent:-8000px; + background-image: url('../../../images/machform.gif'); + background-repeat: no-repeat; +} + +#main_body h1 a +{ + + display:block; + height:100%; + min-height:40px; + overflow:hidden; +} + + +#main_body img +{ + behavior:url(css/iepngfix.htc); + border:none; +} + + +/**** Form Section ****/ +.appnitro +{ + font-family:Lucida Grande, Tahoma, Arial, Verdana, sans-serif; + font-size:small; +} + +.appnitro li +{ + width:61%; +} + +#main_body form ul +{ + font-size:100%; + list-style-type:none; + margin:0; + padding:0; + width:100%; +} + +#main_body form li +{ + display:block; + margin:0; + padding:4px 5px 2px 9px; + position:relative; +} + +#main_body form li:after +{ + clear:both; + content:"."; + display:block; + height:0; + visibility:hidden; +} + +#main_body .buttons:after +{ + clear:both; + content:"."; + display:block; + height:0; + visibility:hidden; +} + +#main_body .buttons +{ + clear:both; + display:block; + margin-top:10px; +} + +#main_body html form li div +{ + display:inline-block; +} + +#main_body form li div +{ + color:#444; + margin:0 4px 0 0; + padding:0 0 8px; +} + +#main_body form li span +{ + color:#444; + float:left; + margin:0 4px 0 0; + padding:0 0 8px; +} + +#main_body form li div.left +{ + display:inline; + float:left; + width:48%; +} + +#main_body form li div.right +{ + display:inline; + float:right; + width:48%; +} + +#main_body form li div.left .medium +{ + width:100%; +} + +#main_body form li div.right .medium +{ + width:98%; +} + +#main_body .clear +{ + clear:both; +} + +#main_body form li div label +{ + clear:both; + color:#444; + display:block; + font-size:9px; + line-height:9px; + margin:0; + padding-top:3px; +} + +#main_body form li span label +{ + clear:both; + color:#444; + display:block; + font-size:9px; + line-height:9px; + margin:0; + padding-top:3px; +} + +#main_body form li .datepicker +{ + cursor:pointer !important; + float:left; + height:16px; + margin:.1em 5px 0 0; + padding:0; + width:16px; +} + +#main_body .form_description +{ + border-bottom:1px dotted #ccc; + clear:both; + display:inline-block; + margin:0 0 1em; +} + +#main_body .form_description[class] +{ + display:block; +} + +#main_body .form_description h2 +{ + clear:left; + font-size:160%; + font-weight:400; + margin:0 0 3px; +} + +#main_body .form_description p +{ + font-size:95%; + line-height:130%; + margin:0 0 12px; +} + +#main_body form hr +{ + display:none; +} + +#main_body form li.section_break +{ + border-top:1px dotted #ccc; + margin-top:9px; + padding-bottom:0; + padding-left:9px; + padding-top:13px; + width:97% !important; +} + +#main_body form ul li.first +{ + border-top:none !important; + margin-top:0 !important; + padding-top:0 !important; +} + +#main_body form .section_break h3 +{ + font-size:110%; + font-weight:400; + line-height:130%; + margin:0 0 2px; +} + +#main_body form .section_break p +{ + font-size:85%; + + margin:0 0 10px; +} + +/**** Buttons ****/ +#main_body input.button_text +{ + overflow:visible; + padding:0 7px; + width:auto; +} + +#main_body .buttons input +{ + font-size:120%; + margin-right:5px; +} + +/**** Inputs and Labels ****/ +#main_body label.description +{ + border:none; + color:#222; + display:block; + font-size:95%; + font-weight:700; + line-height:150%; + padding:0 0 1px; +} + +#main_body span.symbol +{ + font-size:115%; + line-height:130%; +} + +#main_body input.text +{ + background:#fff url(../../../images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; + color:#333; + font-size:100%; + margin:0; + padding:2px 0; +} + +#main_body input.file +{ + color:#333; + font-size:100%; + margin:0; + padding:2px 0; +} + +#main_body textarea.textarea +{ + background:#fff url(../../../images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; + color:#333; + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + font-size:100%; + margin:0; + width:99%; +} + +#main_body select.select +{ + color:#333; + font-size:100%; + margin:1px 0; + padding:1px 0 0; + background:#fff url(../../../images/shadow.gif) repeat-x top; + border-bottom:1px solid #ddd; + border-left:1px solid #c3c3c3; + border-right:1px solid #c3c3c3; + border-top:1px solid #7c7c7c; +} + + +#main_body input.currency +{ + text-align:right; + padding-right:3px; +} + +#main_body input.checkbox +{ + display:block; + height:13px; + line-height:1.4em; + margin:6px 0 0 3px; + width:13px; +} + +#main_body input.radio +{ + display:block; + height:13px; + line-height:1.4em; + margin:6px 0 0 3px; + width:13px; +} + +#main_body label.choice +{ + color:#444; + display:block; + font-size:100%; + line-height:1.4em; + margin:-1.55em 0 0 25px; + padding:4px 0 5px; + width:90%; +} + +#main_body select.select[class] +{ + margin:0; + padding:1px 0; +} + +*:first-child+html select.select[class] +{ + margin:1px 0; +} + +#main_body .safari select.select +{ + font-size:120% !important; + margin-bottom:1px; +} + +#main_body input.small +{ + width:25%; +} + +#main_body select.small +{ + width:25%; +} + +#main_body input.medium +{ + width:50%; +} + +#main_body select.medium +{ + width:50%; +} + +#main_body input.large +{ + width:99%; +} + +#main_body select.large +{ + width:100%; +} + +#main_body textarea.small +{ + height:5.5em; +} + +#main_body textarea.medium +{ + height:10em; +} + +#main_body textarea.large +{ + height:20em; +} + +/**** Errors ****/ +#error_message +{ + background:#fff; + border:1px dotted red; + margin-bottom:1em; + padding-left:0; + padding-right:0; + padding-top:4px; + text-align:center; + width:97%; +} + +#error_message_title +{ + color:#DF0000; + font-size:125%; + margin:7px 0 5px !important; + padding:0 !important; +} + +#error_message_desc +{ + color:#000; + font-size:100%; + margin:0 0 .8em !important; +} + +#error_message_desc strong +{ + background-color:#FFDFDF; + color:red; + padding:2px 3px; +} + +#main_body form li.error +{ + background-color:#FFDFDF !important; + border-bottom:1px solid #EACBCC; + border-right:1px solid #EACBCC; + margin:3px 0; +} + +#main_body form li.error label +{ + color:#DF0000 !important; +} + +#main_body form p.error +{ + clear:both; + color:red; + font-size:10px; + font-weight:700; + margin:0 0 5px !important; +} + +#main_body form .required +{ + color:red !important; + float:none !important; + font-weight:700; +} + +/**** Guidelines and Error Highlight ****/ +#main_body form li.highlighted +{ + background-color:#fff7c0; +} + +#main_body form .guidelines +{ + background:#f5f5f5; + border:1px solid #e6e6e6; + color:#444; + font-size:80%; + left:100%; + line-height:130%; + margin:0 0 0 8px !important; + padding:8px 10px 9px; + position:absolute; + top:0; + visibility:hidden; + width:42%; + z-index:1000; +} + +#main_body form .guidelines small +{ + font-size:105%; +} + +#main_body form li.highlighted .guidelines +{ + visibility:visible; +} + +#main_body form li:hover .guidelines +{ + visibility:visible; +} + +.no_guidelines .guidelines +{ + display:none !important; +} + +.no_guidelines form li +{ + width:97%; +} + +.no_guidelines li.section +{ + padding-left:9px; +} + +/*** Success Message ****/ +.form_success +{ + clear: both; + margin: 0; + padding: 90px 0pt 100px; + text-align: center +} + +.form_success h2 { + clear:left; + font-size:160%; + font-weight:normal; + margin:0pt 0pt 3px; +} + +/*** Password ****/ +#main_body ul.password{ + margin-top:60px; + margin-bottom: 60px; + text-align: center; +} +.password h2{ + color:#DF0000; + font-weight:bold; + margin:0pt auto 10px; +} + +.password input.text { + font-size:170% !important; + width:380px; + text-align: center; +} +.password label{ + display:block; + font-size:120% !important; + padding-top:10px; + font-weight:bold; +} + +#li_captcha{ + padding-left: 5px; +} + + +#li_captcha span{ + float:none; + padding: 0px !important; +} + +#li_captcha div{ + padding: 0px !important; +} +#captcha_image{ + padding-top: 5px; + padding-bottom: 10px; +} +#captcha_response_field{ + margin-bottom: 10px; +} +#dummy_captcha_internal{ + height: 8px; +} +/** Embedded Form **/ + +.embed #top, .embed #bottom, .embed h1{ + display: none; +} + +.embed #form_container{ + border: none; + width: 100%; + background: none; +} + +.embed #footer{ + text-align: left; + padding-left: 10px; + width: 99%; +} + +.embed #footer.success{ + text-align: center; +} + +.embed form.appnitro +{ + margin:0px 0px 0; + +} + +/** Integrated Form **/ +.integrated *{ + font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; + color: #000; +} + +.integrated #top, .integrated #bottom, .integrated h1{ + display: none; +} + +.integrated #form_container{ + border: none; + width: 99%; + background: none; +} + +.integrated #footer{ + text-align: left; + padding-left: 10px; + width: 99%; +} + +.integrated #footer.success{ + text-align: center; +} + +.integrated form.appnitro +{ + margin:0px 0px 0; + +} + +.integrated form .section_break h3 +{ + border: none !important; +} + +.integrated #error_message h3 +{ + border: none !important; + +} + + + +/*** Calendar **********************/ +div.calendar { position: relative; } + + +.calendar table { +cursor:pointer; +border:1px solid #ccc; +font-size: 11px; +color: #000; +background: #fff; +font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; +} + +.calendar table .title,.calendar table .button{ +font-size: 11px; +} + +.calendar * { +font-size: 11px; +font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif; +} + +.calendar .button { +text-align: center; +padding: 2px; +} + +.calendar .nav { +background:#f5f5f5; +} + +.calendar thead .title { +font-weight: bold; +text-align: center; +background: #dedede; +color: #000; +padding: 2px 0 3px 0; +} + +.calendar thead .headrow { +background: #f5f5f5; +color: #444; +font-weight:bold; +} + +.calendar thead .daynames { +background: #fff; +color:#333; +font-weight:bold; +} + +.calendar thead .name { +border-bottom: 1px dotted #ccc; +padding: 2px; +text-align: center; +color: #000; +} + +.calendar thead .weekend { +color: #666; +} + +.calendar thead .hilite { +background-color: #444; +color: #fff; +padding: 1px; +} + +.calendar thead .active { +background-color: #d12f19; +color:#fff; +padding: 2px 0px 0px 2px; +} + + +.calendar tbody .day { +width:1.8em; +color: #222; +text-align: right; +padding: 2px 2px 2px 2px; +} +.calendar tbody .day.othermonth { +font-size: 80%; +color: #bbb; +} +.calendar tbody .day.othermonth.oweekend { +color: #fbb; +} + +.calendar table .wn { +padding: 2px 2px 2px 2px; +border-right: 1px solid #000; +background: #666; +} + +.calendar tbody .rowhilite td { +background: #FFF1AF; +} + +.calendar tbody .rowhilite td.wn { +background: #FFF1AF; +} + +.calendar tbody td.hilite { +padding: 1px 1px 1px 1px; +background:#444 !important; +color:#fff !important; +} + +.calendar tbody td.active { +color:#fff; +background: #529214 !important; +padding: 2px 2px 0px 2px; +} + +.calendar tbody td.selected { +font-weight: bold; +border: 1px solid #888; +padding: 1px 1px 1px 1px; +background: #f5f5f5 !important; +color: #222 !important; +} + +.calendar tbody td.weekend { +color: #666; +} + +.calendar tbody td.today { +font-weight: bold; +color: #529214; +background:#D9EFC2; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { +visibility: hidden; +} + +.calendar tbody .emptyrow { +display: none; +} + +.calendar tfoot .footrow { +text-align: center; +background: #556; +color: #fff; +} + +.calendar tfoot .ttip { +background: #222; +color: #fff; +font-size:10px; +border-top: 1px solid #dedede; +padding: 3px; +} + +.calendar tfoot .hilite { +background: #aaf; +border: 1px solid #04f; +color: #000; +padding: 1px; +} + +.calendar tfoot .active { +background: #77c; +padding: 2px 0px 0px 2px; +} + +.calendar .combo { +position: absolute; +display: none; +top: 0px; +left: 0px; +width: 4em; +border: 1px solid #ccc; +background: #f5f5f5; +color: #222; +font-size: 90%; +z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { +text-align: center; +padding: 1px; +} + +.calendar .combo .label-IEfix { +width: 4em; +} + +.calendar .combo .hilite { +background: #444; +color:#fff; +} + +.calendar .combo .active { +border-top: 1px solid #999; +border-bottom: 1px solid #999; +background: #dedede; +font-weight: bold; +} + +/** Form Review **/ +#machform_review_table tbody tr:hover +{ + background-color: #FFF7C0; +} +.alt{ + background: #efefef; +} +#machform_review_table td +{ + text-align: left; + border-bottom:1px solid #DEDEDE; + padding:5px 10px; +} \ No newline at end of file diff --git a/view.php b/view.php new file mode 100644 index 0000000..8994f3c --- /dev/null +++ b/view.php @@ -0,0 +1,92 @@ +top.location.replace('{$submit_result['form_redirect']}')"; + exit; + } + }else{ //redirect to review page + $ssl_suffix = get_ssl_suffix(); + + $_SESSION['review_id'] = $submit_result['review_id']; + header("Location: http{$ssl_suffix}://".$_SERVER['HTTP_HOST'].get_dirname($_SERVER['PHP_SELF'])."/confirm.php?id={$input_array['form_id']}"); + exit; + } + }else{ + $old_values = $submit_result['old_values']; + $custom_error = @$submit_result['custom_error']; + $error_elements = $submit_result['error_elements']; + + $markup = display_form($input_array['form_id'],$old_values,$error_elements,$custom_error); + } + }else{ //if password form submitted + if($submit_result['status'] === true){ //on success, display the form + $markup = display_form($input_array['form_id']); + }else{ + $custom_error = $submit_result['custom_error']; //error, display the pasword form again + $markup = display_form($input_array['form_id'],null,null,$custom_error); + } + } + }else{ + $form_id = (int) trim($_GET['id']); + if(empty($form_id)){ + die('ID required.'); + } + + //check for delete file option + //this is available for form with review enabled + if(!empty($_GET['delete_file']) && !empty($_SESSION['review_id'])){ + $element_id = (int) trim($_GET['delete_file']); + delete_review_file_entry($form_id,$_SESSION['review_id'],$element_id); + } + + if(!empty($_GET['done'])){ + $markup = display_success($form_id); + }else{ + $markup = display_form($form_id); + } + } + + header("Content-Type: text/html; charset=UTF-8"); + echo $markup; + +?> diff --git a/view_entry.php b/view_entry.php new file mode 100644 index 0000000..0d6af34 --- /dev/null +++ b/view_entry.php @@ -0,0 +1,221 @@ + $entry_id order by id asc limit 1"); + $row = do_fetch_result($result); + $newer_entry_id = $row['id']; + + //newest entry id + $result = do_query("select id from ap_form_{$form_id} order by id desc limit 1"); + $row = do_fetch_result($result); + $newest_entry_id = $row['id']; + + if(($entry_id == $newest_entry_id) && ($entry_id == $oldest_entry_id)){ + $nav_position = 'disabled'; + }elseif($entry_id == $newest_entry_id){ + $nav_position = 'newest'; + }elseif ($entry_id == $oldest_entry_id){ + $nav_position = 'oldest'; + }else{ + $nav_position = 'middle'; + } + + + $header_data =<< + + + + + + + + + +EOT; + + +?> + + + + +
    + +
    +

    Entries #

    +

    Viewing entry #

    +
    + + +
    +
    + + + + + > + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    Entry Info 
    Date Created
    Date Updated
    IP Address
    +
    + +
    +
    + + " alt="Newest">  + " alt="Newer">  + + + +   +   + + + +" alt="Older">  + " alt="Oldest"> + + +   + + +
    +
    Entry Options
    +
    + +
    +
    + + +
    + \ No newline at end of file